Commit d3d55a4c authored by neverlord's avatar neverlord

pattern matching

parent f246a9c9
......@@ -121,6 +121,7 @@ nobase_library_include_HEADERS = \
cppa/detail/post_office.hpp \
cppa/detail/post_office_msg.hpp \
cppa/detail/primitive_member.hpp \
cppa/detail/projection.hpp \
cppa/detail/ptype_to_type.hpp \
cppa/detail/receive_loop_helper.hpp \
cppa/detail/ref_counted_impl.hpp \
......@@ -132,12 +133,14 @@ nobase_library_include_HEADERS = \
cppa/detail/thread_pool_scheduler.hpp \
cppa/detail/to_uniform_name.hpp \
cppa/detail/tuple_cast_impl.hpp \
cppa/detail/tuple_iterator.hpp \
cppa/detail/tuple_vals.hpp \
cppa/detail/tuple_view.hpp \
cppa/detail/type_to_ptype.hpp \
cppa/detail/types_array.hpp \
cppa/detail/unboxed.hpp \
cppa/detail/uniform_type_info_map.hpp \
cppa/detail/value_guard.hpp \
cppa/detail/yield_interface.hpp \
cppa/detail/yielding_actor.hpp \
cppa/either.hpp \
......@@ -186,6 +189,7 @@ nobase_library_include_HEADERS = \
cppa/util/comparable.hpp \
cppa/util/compare_tuples.hpp \
cppa/util/conjunction.hpp \
cppa/util/deduce_ref_type.hpp \
cppa/util/disable_if.hpp \
cppa/util/disjunction.hpp \
cppa/util/duration.hpp \
......@@ -205,8 +209,10 @@ nobase_library_include_HEADERS = \
cppa/util/is_primitive.hpp \
cppa/util/left_or_right.hpp \
cppa/util/producer_consumer_list.hpp \
cppa/util/projection.hpp \
cppa/util/pt_dispatch.hpp \
cppa/util/pt_token.hpp \
cppa/util/purge_refs.hpp \
cppa/util/replace_type.hpp \
cppa/util/ripemd_160.hpp \
cppa/util/rm_option.hpp \
......
......@@ -262,3 +262,9 @@ cppa/util/left_or_right.hpp
cppa/util/apply_args.hpp
cppa/tpartial_function.hpp
cppa/util/rm_option.hpp
cppa/util/projection.hpp
cppa/util/purge_refs.hpp
cppa/util/deduce_ref_type.hpp
cppa/detail/projection.hpp
cppa/detail/value_guard.hpp
cppa/detail/tuple_iterator.hpp
......@@ -40,6 +40,8 @@
#include "cppa/util/type_list.hpp"
#include "cppa/detail/tuple_iterator.hpp"
namespace cppa { namespace detail {
enum tuple_impl_info
......@@ -85,87 +87,7 @@ class abstract_tuple : public ref_counted
bool equals(abstract_tuple const& other) const;
// iterator support
class const_iterator
{
size_t m_pos;
abstract_tuple const* m_tuple;
public:
inline const_iterator(abstract_tuple const* tup, size_t pos = 0)
: m_pos(pos), m_tuple(tup)
{
}
const_iterator(const_iterator const&) = default;
const_iterator& operator=(const_iterator const&) = default;
inline bool operator==(const_iterator const& other) const
{
CPPA_REQUIRE(other.m_tuple == other.m_tuple);
return other.m_pos == m_pos;
}
inline bool operator!=(const_iterator const& other) const
{
return !(*this == other);
}
inline const_iterator& operator++()
{
++m_pos;
return *this;
}
inline const_iterator& operator--()
{
CPPA_REQUIRE(m_pos > 0);
--m_pos;
return *this;
}
inline const_iterator operator+(size_t offset)
{
return {m_tuple, m_pos + offset};
}
inline const_iterator& operator+=(size_t offset)
{
m_pos += offset;
return *this;
}
inline const_iterator operator-(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
return {m_tuple, m_pos - offset};
}
inline const_iterator& operator-=(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
m_pos -= offset;
return *this;
}
inline size_t position() const { return m_pos; }
inline void const* value() const
{
return m_tuple->at(m_pos);
}
inline uniform_type_info const* type() const
{
return m_tuple->type_at(m_pos);
}
inline const_iterator& operator*() { return *this; }
};
typedef tuple_iterator<abstract_tuple> const_iterator;
inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; }
......@@ -175,24 +97,41 @@ class abstract_tuple : public ref_counted
};
inline bool full_eq_v3(abstract_tuple::const_iterator const& lhs,
abstract_tuple::const_iterator const& rhs)
struct full_eq_type
{
return lhs.type() == rhs.type()
&& lhs.type()->equals(lhs.value(), rhs.value());
}
constexpr full_eq_type() { }
template<class Tuple>
inline bool operator()(tuple_iterator<Tuple> const& lhs,
tuple_iterator<Tuple> const& rhs) const
{
return lhs.type() == rhs.type()
&& lhs.type()->equals(lhs.value(), rhs.value());
}
};
inline bool types_only_eq(abstract_tuple::const_iterator const& lhs,
uniform_type_info const* rhs)
struct types_only_eq_type
{
return lhs.type() == rhs;
}
constexpr types_only_eq_type() { }
template<class Tuple>
inline bool operator()(tuple_iterator<Tuple> const& lhs,
uniform_type_info const* rhs ) const
{
return lhs.type() == rhs;
}
template<class Tuple>
inline bool operator()(uniform_type_info const* lhs,
tuple_iterator<Tuple> const& rhs) const
{
return lhs == rhs.type();
}
};
inline bool types_only_eq_v2(uniform_type_info const* lhs,
abstract_tuple::const_iterator const& rhs)
{
return lhs == rhs.type();
}
namespace {
constexpr full_eq_type full_eq;
constexpr types_only_eq_type types_only_eq;
} // namespace <anonymous>
} } // namespace cppa::detail
......
This diff is collapsed.
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef PROJECTION_HPP
#define PROJECTION_HPP
#include "cppa/option.hpp"
#include "cppa/guard_expr.hpp"
#include "cppa/util/rm_option.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/left_or_right.hpp"
#include "cppa/detail/tdata.hpp"
namespace cppa { namespace detail {
template<class PartialFun>
struct projection_helper
{
PartialFun const& fun;
projection_helper(PartialFun const& pfun) : fun(pfun) { }
template<typename... Args>
bool operator()(Args&&... args) const
{
if (fun.defined_at(std::forward<Args>(args)...))
{
fun(std::forward<Args>(args)...);
return true;
}
return false;
}
};
/**
* @brief Projection implemented by a set of functors.
*/
template<class ProjectionFuns, typename... Args>
class projection
{
public:
typedef typename tdata_from_type_list<ProjectionFuns>::type fun_container;
projection(fun_container const& args) : m_funs(args) { }
projection(projection const&) = default;
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
template<class PartialFun>
bool operator()(PartialFun& fun, Args... args) const
{
typedef typename util::tl_zip<
typename util::tl_map<
ProjectionFuns,
util::get_result_type,
util::rm_option
>::type,
typename util::tl_map<
util::type_list<Args...>,
mutable_gref_wrapped
>::type,
util::left_or_right
>::type
collected_args;
typename tdata_from_type_list<collected_args>::type pargs;
if (collect(pargs, m_funs, std::forward<Args>(args)...))
{
projection_helper<PartialFun> helper{fun};
return util::unchecked_apply_tuple<bool>(helper, pargs);
}
return false;
}
private:
template<typename Storage, typename T>
static inline bool fetch_(Storage& storage, T&& value)
{
storage = std::forward<T>(value);
return true;
}
template<class Storage>
static inline bool fetch_(Storage& storage, option<Storage>&& value)
{
if (value)
{
storage = std::move(*value);
return true;
}
return false;
}
template<class Storage, typename Fun, typename T>
static inline bool fetch(Storage& storage, Fun const& fun, T&& arg)
{
return fetch_(storage, fun(std::forward<T>(arg)));
}
template<typename Storage, typename T>
static inline bool fetch(Storage& storage, util::void_type const&, T&& arg)
{
return fetch_(storage, std::forward<T>(arg));
}
static inline bool collect(tdata<>&, tdata<> const&)
{
return true;
}
template<class TData, class Trans, typename T0, typename... Ts>
static inline bool collect(TData& td, Trans const& tr,
T0&& arg0, Ts&&... args)
{
return fetch(td.head, tr.head, std::forward<T0>(arg0))
&& collect(td.tail(), tr.tail(), std::forward<Ts>(args)...);
}
fun_container m_funs;
};
template<>
class projection<util::type_list<> >
{
public:
projection() = default;
projection(tdata<> const&) { }
projection(projection const&) = default;
template<class PartialFun>
bool operator()(PartialFun& fun) const
{
fun();
return true;
}
};
template<class ProjectionFuns, class List>
class projection_from_type_list;
template<class ProjectionFuns, typename... Args>
class projection_from_type_list<ProjectionFuns, util::type_list<Args...> >
{
typedef projection<ProjectionFuns, Args...> type;
};
} } // namespace cppa::detail
#endif // PROJECTION_HPP
......@@ -47,6 +47,7 @@
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/tuple_iterator.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
......@@ -154,6 +155,14 @@ struct tdata<>
"Additional unboxed arguments provided");
}
typedef tuple_iterator<tdata> const_iterator;
inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; }
inline const_iterator end() const { return {this}; }
inline const_iterator cend() const { return {this}; }
inline tdata(tdata&) { }
inline tdata(tdata&&) { }
inline tdata(tdata const&) { }
......@@ -310,6 +319,15 @@ struct tdata<Head, Tail...> : tdata<Tail...>
inline size_t size() const { return num_elements; }
typedef tuple_iterator<tdata> const_iterator;
inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; }
inline const_iterator end() const { return {this, size()}; }
inline const_iterator cend() const { return {this, size()}; }
// upcast
inline tdata<Tail...>& tail() { return *this; }
......@@ -427,6 +445,22 @@ struct tdata_from_type_list<util::type_list<T...>>
typedef tdata<T...> type;
};
template<typename... T>
inline void collect_tdata(tdata<T...>&) { }
template<typename Storage, typename... Args>
void collect_tdata(Storage& storage, tdata<> const&, Args const&... args)
{
collect_tdata(storage, args...);
}
template<typename Storage, typename Arg0, typename... Args>
void collect_tdata(Storage& storage, Arg0 const& arg0, Args const&... args)
{
storage.head = arg0.head;
collect_tdata(storage.tail(), arg0.tail(), args...);
}
} } // namespace cppa::detail
namespace cppa {
......
......@@ -59,7 +59,8 @@ struct tuple_cast_impl
static constexpr size_t size =
util::tl_count_not<util::type_list<T...>, is_anything>::value;
static constexpr size_t first_wc =
static_cast<size_t>(util::tl_find<util::type_list<T...>, anything>::value);
static_cast<size_t>(
util::tl_find<util::type_list<T...>, anything>::value);
typedef util::fixed_vector<size_t, size> mapping_vector;
static inline option<Result> safe(any_tuple& tup)
{
......@@ -80,7 +81,7 @@ struct tuple_cast_impl
mapping_vector mv;
if (WP == wildcard_position::in_between)
{
if (!p.has_values() || matcher<WP, T...>::vmatch(tup, p))
if (!p.has_values() || matcher<WP, any_tuple, T...>::vmatch(tup, p))
{
// first range
mv.resize(size);
......@@ -140,7 +141,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...>
static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{
if ( p.has_values() == false
|| matcher<wildcard_position::nil, T...>::vmatch(tup, p))
|| matcher<wildcard_position::nil, any_tuple, T...>::vmatch(tup, p))
{
return {Result::from(std::move(tup.vals()))};
}
......@@ -159,7 +160,8 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{
if ( p.has_values() == false
|| matcher<wildcard_position::trailing, T...>::vmatch(tup, p))
|| matcher<wildcard_position::trailing, any_tuple, T...>
::vmatch(tup, p))
{
return {Result::from(std::move(tup.vals()))};
}
......@@ -189,7 +191,8 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...>
static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{
if ( p.has_values() == false
|| matcher<wildcard_position::leading, T...>::vmatch(tup, p))
|| matcher<wildcard_position::leading, any_tuple, T...>
::vmatch(tup, p))
{
size_t o = tup.size() - (sizeof...(T) - 1);
return Result::offset_subtuple(tup.vals(), o);
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef TUPLE_ITERATOR_HPP
#define TUPLE_ITERATOR_HPP
#include <cstddef>
#include "cppa/config.hpp"
namespace cppa { namespace detail {
template<class Tuple>
class tuple_iterator
{
size_t m_pos;
Tuple const* m_tuple;
public:
inline tuple_iterator(Tuple const* tup, size_t pos = 0)
: m_pos(pos), m_tuple(tup)
{
}
tuple_iterator(tuple_iterator const&) = default;
tuple_iterator& operator=(tuple_iterator const&) = default;
inline bool operator==(tuple_iterator const& other) const
{
CPPA_REQUIRE(other.m_tuple == other.m_tuple);
return other.m_pos == m_pos;
}
inline bool operator!=(tuple_iterator const& other) const
{
return !(*this == other);
}
inline tuple_iterator& operator++()
{
++m_pos;
return *this;
}
inline tuple_iterator& operator--()
{
CPPA_REQUIRE(m_pos > 0);
--m_pos;
return *this;
}
inline tuple_iterator operator+(size_t offset)
{
return {m_tuple, m_pos + offset};
}
inline tuple_iterator& operator+=(size_t offset)
{
m_pos += offset;
return *this;
}
inline tuple_iterator operator-(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
return {m_tuple, m_pos - offset};
}
inline tuple_iterator& operator-=(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
m_pos -= offset;
return *this;
}
inline size_t position() const { return m_pos; }
inline void const* value() const
{
return m_tuple->at(m_pos);
}
inline uniform_type_info const* type() const
{
return m_tuple->type_at(m_pos);
}
inline tuple_iterator& operator*() { return *this; }
};
} } // namespace cppa::detail
#endif // TUPLE_ITERATOR_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef VALUE_GUARD_HPP
#define VALUE_GUARD_HPP
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/detail/tdata.hpp"
namespace cppa { namespace detail {
template<bool IsFun, typename T>
struct vg_fwd_
{
static inline T const& _(T const& arg) { return arg; }
static inline T&& _(T&& arg) { return std::move(arg); }
static inline T& _(T& arg) { return arg; }
};
template<typename T>
struct vg_fwd_<true, T>
{
template<typename Arg>
static inline util::void_type _(Arg&&) { return {}; }
};
// absorbs callables
template<typename T>
struct vg_fwd
: vg_fwd_<util::is_callable<typename util::rm_ref<T>::type>::value,
typename util::rm_ref<T>::type>
{
};
template<typename FilteredPattern>
class value_guard
{
typename tdata_from_type_list<FilteredPattern>::type m_args;
template<typename... Args>
inline bool _eval(util::void_type const&, tdata<> const&, Args&&...) const
{
return true;
}
template<class Tail, typename Arg0, typename... Args>
inline bool _eval(util::void_type const&, Tail const& tail,
Arg0 const&, Args const&... args ) const
{
return _eval(tail.head, tail.tail(), args...);
}
template<typename Head, class Tail, typename Arg0, typename... Args>
inline bool _eval(Head const& head, Tail const& tail,
Arg0 const& arg0, Args const&... args) const
{
return head == arg0 && _eval(tail.head, tail.tail(), args...);
}
public:
value_guard() = default;
value_guard(value_guard const&) = default;
template<typename... Args>
value_guard(Args const&... args) : m_args(vg_fwd<Args>::_(args)...)
{
}
template<typename... Args>
inline bool operator()(Args const&... args) const
{
return _eval(m_args.head, m_args.tail(), args...);
}
};
} } // namespace cppa::detail
#endif // VALUE_GUARD_HPP
......@@ -729,6 +729,26 @@ bool guard_expr<OP, First, Second>::operator()(Args const&... args) const
return ge_invoke(*this, args...);
}
// some utility functions
template<typename T>
struct gref_wrapped
{
typedef ge_reference_wrapper<typename util::rm_ref<T>::type> type;
};
template<typename T>
struct mutable_gref_wrapped
{
typedef ge_mutable_reference_wrapper<T> type;
};
template<typename T>
struct mutable_gref_wrapped<T&>
{
typedef ge_mutable_reference_wrapper<T> type;
};
// finally ...
namespace placeholders { namespace {
......
......@@ -108,13 +108,6 @@ struct get_arg_types
typedef typename trait_type::arg_types types;
};
template<typename C>
struct get_result_type
{
typedef typename get_callable_trait<C>::type trait_type;
typedef typename trait_type::result_type type;
};
template<typename T>
struct is_callable
{
......@@ -142,6 +135,25 @@ struct is_callable
};
template<bool IsCallable, typename C>
struct get_result_type_impl
{
typedef typename get_callable_trait<C>::type trait_type;
typedef typename trait_type::result_type type;
};
template<typename C>
struct get_result_type_impl<false, C>
{
typedef void_type type;
};
template<typename C>
struct get_result_type
{
typedef typename get_result_type_impl<is_callable<C>::value, C>::type type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_CALLABLE_TRAIT
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef DEDUCE_REF_TYPE_HPP
#define DEDUCE_REF_TYPE_HPP
#include "cppa/util/rm_ref.hpp"
namespace cppa { namespace util {
/**
* @brief Deduces reference type of T0 and applies it to T1.
*/
template<typename T0, typename T1>
struct deduce_ref_type
{
typedef typename util::rm_ref<T1>::type type;
};
template<typename T0, typename T1>
struct deduce_ref_type<T0&, T1>
{
typedef typename util::rm_ref<T1>::type& type;
};
template<typename T0, typename T1>
struct deduce_ref_type<T0 const&, T1>
{
typedef typename util::rm_ref<T1>::type const& type;
};
} } // namespace cppa::util
#endif // DEDUCE_REF_TYPE_HPP
......@@ -50,6 +50,33 @@ struct left_or_right<util::void_type, Right>
typedef Right type;
};
template<typename Right>
struct left_or_right<util::void_type&, Right>
{
typedef Right type;
};
template<typename Right>
struct left_or_right<util::void_type const&, Right>
{
typedef Right type;
};
/**
* @brief Evaluates to @p Right if @p Left != void_type, @p void_type otherwise.
*/
template<typename Left, typename Right>
struct if_not_left
{
typedef void_type type;
};
template<typename Right>
struct if_not_left<util::void_type, Right>
{
typedef Right type;
};
} } // namespace cppa::util
#endif // LEFT_OR_RIGHT_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef PROJECTION_HPP
#define PROJECTION_HPP
namespace cppa { namespace util {
} } // namespace cppa::util
#endif // PROJECTION_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef PURGE_REFS_HPP
#define PURGE_REFS_HPP
#include <functional>
#include "cppa/guard_expr.hpp"
#include "cppa/util/rm_ref.hpp"
namespace cppa { namespace util {
template<typename T>
struct purge_refs_impl
{
typedef T type;
};
template<typename T>
struct purge_refs_impl<ge_reference_wrapper<T> >
{
typedef T type;
};
template<typename T>
struct purge_refs_impl<ge_mutable_reference_wrapper<T> >
{
typedef T type;
};
template<typename T>
struct purge_refs_impl<std::reference_wrapper<T> >
{
typedef T type;
};
/**
* @brief Removes references and reference wrappers.
*/
template<typename T>
struct purge_refs
{
typedef typename purge_refs_impl<typename util::rm_ref<T>::type>::type type;
};
} } // namespace cppa::util
#endif // PURGE_REFS_HPP
......@@ -554,18 +554,93 @@ struct tl_push_front<type_list<ListTypes...>, What>
// list map(list, trait)
template<typename T, template<typename> class... Funs>
struct tl_apply_all;
template<typename T>
struct tl_apply_all<T>
{
typedef T type;
};
template<typename T,
template<typename> class Fun0,
template<typename> class... Funs>
struct tl_apply_all<T, Fun0, Funs...>
{
typedef typename tl_apply_all<typename Fun0<T>::type, Funs...>::type type;
};
/**
* @brief Creates a new list by applying a "template function" to each element.
*/
template<class List, template<typename> class Fun>
template<class List, template<typename> class... Funs>
struct tl_map;
template<template<typename> class Fun, typename... Elements>
struct tl_map<type_list<Elements...>, Fun>
template<typename... Ts, template<typename> class... Funs>
struct tl_map<type_list<Ts...>, Funs...>
{
typedef type_list<typename Fun<Elements>::type...> type;
typedef type_list<typename tl_apply_all<Ts, Funs...>::type...> type;
};
/**
* @brief Creates a new list by applying a @p Fun to each element which
* returns @p TraitResult for @p Trait.
*/
template<class List,
template<typename> class Trait,
bool TraitResult,
template<typename> class... Funs>
struct tl_map_conditional
{
typedef typename tl_concat<
type_list<
typename std::conditional<
Trait<typename List::head>::value == TraitResult,
typename tl_apply_all<typename List::head, Funs...>::type,
typename List::head
>::type
>,
typename tl_map_conditional<
typename List::tail,
Trait,
TraitResult,
Funs...
>::type
>::type
type;
};
template<template<typename> class Trait,
bool TraitResult,
template<typename> class... Funs>
struct tl_map_conditional<type_list<>, Trait, TraitResult, Funs...>
{
typedef type_list<> type;
};
/*
freaks GCC out ...
template<typename... Ts,
template<typename> class Trait,
bool TraitResult,
template<typename> class... Funs>
struct tl_map_conditional<type_list<Ts...>, Trait, TraitResult, Funs...>
{
typedef type_list<
typename std::conditional<
Trait<Ts>::value == TraitResult,
typename tl_apply_all<Ts, Funs...>::type,
Ts
>::type
...
type;
};
*/
// list zipped_map(trait)
template<class List, template<typename, typename> class Fun>
......@@ -590,8 +665,13 @@ struct tl_zipped_map<type_list<T...>, Fun>
template<class List>
struct tl_pop_back
{
typedef typename tl_reverse<List>::type rlist;
typedef typename tl_reverse<typename rlist::tail>::type type;
typedef typename tl_slice<List, 0, List::size - 1>::type type;
};
template<>
struct tl_pop_back<type_list<> >
{
typedef type_list<> type;
};
// type at(size_t)
......@@ -833,7 +913,7 @@ struct tl_is_zipped
/**
* @brief Removes trailing @p What elements from the end.
*/
template<class List, typename What>
template<class List, typename What = void_type>
struct tl_trim
{
typedef typename util::if_else<
......
......@@ -36,7 +36,7 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
{
return this == &other
|| ( size() == other.size()
&& std::equal(begin(), end(), other.begin(), detail::full_eq_v3));
&& std::equal(begin(), end(), other.begin(), detail::full_eq));
}
abstract_tuple::abstract_tuple(abstract_tuple const& other)
......
This diff is collapsed.
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