Commit 525a7428 authored by Dominik Charousset's avatar Dominik Charousset

Add tuple_cast to cppa headers

parent 28b176f2
......@@ -71,17 +71,7 @@ class cow_tuple<Head, Tail...> {
* @param args Initialization values.
*/
template<typename... Ts>
cow_tuple(const Head& arg, Ts&&... args)
: m_vals(new data_type(arg, std::forward<Ts>(args)...)) {
// nop
}
/**
* @brief Initializes the cow_tuple with @p args.
* @param args Initialization values.
*/
template<typename... Ts>
cow_tuple(Head&& arg, Ts&&... args)
cow_tuple(Head arg, Ts&&... args)
: m_vals(new data_type(std::move(arg), std::forward<Ts>(args)...)) {
// nop
}
......@@ -128,8 +118,14 @@ class cow_tuple<Head, Tail...> {
return message{m_vals};
}
static cow_tuple from(message& msg) {
return cow_tuple(msg.vals());
}
private:
cow_tuple(data_ptr ptr) : m_vals(ptr) { }
data_type* ptr() {
return static_cast<data_type*>(m_vals.get());
}
......@@ -186,7 +182,15 @@ make_cow_tuple(Ts&&... args) {
return {std::forward<Ts>(args)...};
}
} // namespace cppa
template<typename TypeList>
struct cow_tuple_from_type_list;
template<typename... Ts>
struct cow_tuple_from_type_list<detail::type_list<Ts...>> {
typedef cow_tuple<Ts...> type;
};
} // namespace caf
// </backward_compatibility>
#endif // CPPA_COW_TUPLE_HPP
......@@ -27,6 +27,7 @@
// include compatibility headers
#include "cppa/opt.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/remote_actor.hpp"
#include "cppa/publish_local_groups.hpp"
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_TUPLE_CAST_HPP
#define CPPA_TUPLE_CAST_HPP
// <backward_compatibility version="0.9" whole_file="yes">
#include <type_traits>
#include "caf/message.hpp"
#include "caf/optional.hpp"
#include "caf/wildcard_position.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/types_array.hpp"
#include "caf/detail/decorated_tuple.hpp"
namespace caf {
template<class TupleIter, class PatternIter,
class Push, class Commit, class Rollback>
bool dynamic_match(TupleIter tbegin, TupleIter tend,
PatternIter pbegin, PatternIter pend,
Push& push, Commit& commit, Rollback& rollback) {
while (!(pbegin == pend && tbegin == tend)) {
if (pbegin == pend) {
// reached end of pattern while some values remain unmatched
return false;
}
else if (*pbegin == nullptr) { // nullptr == wildcard (anything)
// perform submatching
++pbegin;
// always true at the end of the pattern
if (pbegin == pend) return true;
// safe current mapping as fallback
commit();
// iterate over tuple values until we found a match
for (; tbegin != tend; ++tbegin) {
if (dynamic_match(tbegin, tend, pbegin, pend,
push, commit, rollback)) {
return true;
}
// restore mapping to fallback (delete invalid mappings)
rollback();
}
return false; // no submatch found
}
// compare types
else if (tbegin.type() == *pbegin) push(tbegin);
// no match
else return false;
// next iteration
++tbegin;
++pbegin;
}
return true; // pbegin == pend && tbegin == tend
}
template<typename... T>
auto moving_tuple_cast(message& tup)
-> optional<
typename cow_tuple_from_type_list<
typename detail::tl_filter_not<detail::type_list<T...>,
is_anything>::type
>::type> {
using result_type = typename cow_tuple_from_type_list<
typename detail::tl_filter_not<detail::type_list<T...>,
is_anything>::type
>::type;
using types = detail::type_list<T...>;
static constexpr auto impl =
get_wildcard_position<detail::type_list<T...>>();
auto& tarr = detail::static_types_array<T...>::arr;
const uniform_type_info* const* arr_pos = tarr.begin();
message sub;
switch (impl) {
case wildcard_position::nil: {
sub = tup;
break;
}
case wildcard_position::trailing: {
sub = tup.take(sizeof...(T) - 1);
break;
}
case wildcard_position::leading: {
++arr_pos; // skip leading 'anything'
sub = tup.take_right(sizeof...(T) - 1);
break;
}
case wildcard_position::in_between:
case wildcard_position::multiple: {
constexpr size_t wc_count =
detail::tl_count<detail::type_list<T...>, is_anything>::value;
if (tup.size() >= (sizeof...(T) - wc_count)) {
std::vector<size_t> mv; // mapping vector
size_t commited_size = 0;
auto fpush = [&](const typename message::const_iterator& iter) {
mv.push_back(iter.position());
};
auto fcommit = [&] {
commited_size = mv.size();
};
auto frollback = [&] {
mv.resize(commited_size);
};
if (dynamic_match(tup.begin(), tup.end(),
tarr.begin(), tarr.end(),
fpush, fcommit, frollback)) {
message msg{detail::decorated_tuple::create(
tup.vals(), std::move(mv))};
return result_type::from(msg);
}
return none;
}
break;
}
}
// same for nil, leading, and trailing
if (std::equal(sub.begin(), sub.end(),
arr_pos, detail::types_only_eq)) {
return result_type::from(sub);
}
return none;
}
template<typename... T>
auto moving_tuple_cast(message& tup, const detail::type_list<T...>&)
-> decltype(moving_tuple_cast<T...>(tup)) {
return moving_tuple_cast<T...>(tup);
}
template<typename... T>
auto tuple_cast(message tup)
-> optional<
typename cow_tuple_from_type_list<
typename detail::tl_filter_not<detail::type_list<T...>,
is_anything>::type
>::type> {
return moving_tuple_cast<T...>(tup);
}
template<typename... T>
auto tuple_cast(message tup, const detail::type_list<T...>&)
-> decltype(tuple_cast<T...>(tup)) {
return moving_tuple_cast<T...>(tup);
}
template<typename... T>
auto unsafe_tuple_cast(message& tup, const detail::type_list<T...>&)
-> decltype(tuple_cast<T...>(tup)) {
return tuple_cast<T...>(tup);
}
} // namespace caf
// </backward_compatibility>
#endif // CPPA_TUPLE_CAST_HPP
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment