Commit d3d55a4c authored by neverlord's avatar neverlord

pattern matching

parent f246a9c9
...@@ -121,6 +121,7 @@ nobase_library_include_HEADERS = \ ...@@ -121,6 +121,7 @@ nobase_library_include_HEADERS = \
cppa/detail/post_office.hpp \ cppa/detail/post_office.hpp \
cppa/detail/post_office_msg.hpp \ cppa/detail/post_office_msg.hpp \
cppa/detail/primitive_member.hpp \ cppa/detail/primitive_member.hpp \
cppa/detail/projection.hpp \
cppa/detail/ptype_to_type.hpp \ cppa/detail/ptype_to_type.hpp \
cppa/detail/receive_loop_helper.hpp \ cppa/detail/receive_loop_helper.hpp \
cppa/detail/ref_counted_impl.hpp \ cppa/detail/ref_counted_impl.hpp \
...@@ -132,12 +133,14 @@ nobase_library_include_HEADERS = \ ...@@ -132,12 +133,14 @@ nobase_library_include_HEADERS = \
cppa/detail/thread_pool_scheduler.hpp \ cppa/detail/thread_pool_scheduler.hpp \
cppa/detail/to_uniform_name.hpp \ cppa/detail/to_uniform_name.hpp \
cppa/detail/tuple_cast_impl.hpp \ cppa/detail/tuple_cast_impl.hpp \
cppa/detail/tuple_iterator.hpp \
cppa/detail/tuple_vals.hpp \ cppa/detail/tuple_vals.hpp \
cppa/detail/tuple_view.hpp \ cppa/detail/tuple_view.hpp \
cppa/detail/type_to_ptype.hpp \ cppa/detail/type_to_ptype.hpp \
cppa/detail/types_array.hpp \ cppa/detail/types_array.hpp \
cppa/detail/unboxed.hpp \ cppa/detail/unboxed.hpp \
cppa/detail/uniform_type_info_map.hpp \ cppa/detail/uniform_type_info_map.hpp \
cppa/detail/value_guard.hpp \
cppa/detail/yield_interface.hpp \ cppa/detail/yield_interface.hpp \
cppa/detail/yielding_actor.hpp \ cppa/detail/yielding_actor.hpp \
cppa/either.hpp \ cppa/either.hpp \
...@@ -186,6 +189,7 @@ nobase_library_include_HEADERS = \ ...@@ -186,6 +189,7 @@ nobase_library_include_HEADERS = \
cppa/util/comparable.hpp \ cppa/util/comparable.hpp \
cppa/util/compare_tuples.hpp \ cppa/util/compare_tuples.hpp \
cppa/util/conjunction.hpp \ cppa/util/conjunction.hpp \
cppa/util/deduce_ref_type.hpp \
cppa/util/disable_if.hpp \ cppa/util/disable_if.hpp \
cppa/util/disjunction.hpp \ cppa/util/disjunction.hpp \
cppa/util/duration.hpp \ cppa/util/duration.hpp \
...@@ -205,8 +209,10 @@ nobase_library_include_HEADERS = \ ...@@ -205,8 +209,10 @@ nobase_library_include_HEADERS = \
cppa/util/is_primitive.hpp \ cppa/util/is_primitive.hpp \
cppa/util/left_or_right.hpp \ cppa/util/left_or_right.hpp \
cppa/util/producer_consumer_list.hpp \ cppa/util/producer_consumer_list.hpp \
cppa/util/projection.hpp \
cppa/util/pt_dispatch.hpp \ cppa/util/pt_dispatch.hpp \
cppa/util/pt_token.hpp \ cppa/util/pt_token.hpp \
cppa/util/purge_refs.hpp \
cppa/util/replace_type.hpp \ cppa/util/replace_type.hpp \
cppa/util/ripemd_160.hpp \ cppa/util/ripemd_160.hpp \
cppa/util/rm_option.hpp \ cppa/util/rm_option.hpp \
......
...@@ -262,3 +262,9 @@ cppa/util/left_or_right.hpp ...@@ -262,3 +262,9 @@ cppa/util/left_or_right.hpp
cppa/util/apply_args.hpp cppa/util/apply_args.hpp
cppa/tpartial_function.hpp cppa/tpartial_function.hpp
cppa/util/rm_option.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 @@ ...@@ -40,6 +40,8 @@
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tuple_iterator.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
enum tuple_impl_info enum tuple_impl_info
...@@ -85,87 +87,7 @@ class abstract_tuple : public ref_counted ...@@ -85,87 +87,7 @@ class abstract_tuple : public ref_counted
bool equals(abstract_tuple const& other) const; bool equals(abstract_tuple const& other) const;
// iterator support typedef tuple_iterator<abstract_tuple> const_iterator;
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; }
};
inline const_iterator begin() const { return {this}; } inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; } inline const_iterator cbegin() const { return {this}; }
...@@ -175,24 +97,41 @@ class abstract_tuple : public ref_counted ...@@ -175,24 +97,41 @@ class abstract_tuple : public ref_counted
}; };
inline bool full_eq_v3(abstract_tuple::const_iterator const& lhs, struct full_eq_type
abstract_tuple::const_iterator const& rhs)
{ {
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() return lhs.type() == rhs.type()
&& lhs.type()->equals(lhs.value(), rhs.value()); && lhs.type()->equals(lhs.value(), rhs.value());
} }
};
inline bool types_only_eq(abstract_tuple::const_iterator const& lhs, struct types_only_eq_type
uniform_type_info const* 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; return lhs.type() == rhs;
} }
template<class Tuple>
inline bool types_only_eq_v2(uniform_type_info const* lhs, inline bool operator()(uniform_type_info const* lhs,
abstract_tuple::const_iterator const& rhs) tuple_iterator<Tuple> const& rhs) const
{ {
return lhs == rhs.type(); return lhs == rhs.type();
} }
};
namespace {
constexpr full_eq_type full_eq;
constexpr types_only_eq_type types_only_eq;
} // namespace <anonymous>
} } // namespace cppa::detail } } // 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 @@ ...@@ -47,6 +47,7 @@
#include "cppa/detail/boxed.hpp" #include "cppa/detail/boxed.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/tuple_iterator.hpp"
#include "cppa/detail/implicit_conversions.hpp" #include "cppa/detail/implicit_conversions.hpp"
namespace cppa { namespace cppa {
...@@ -154,6 +155,14 @@ struct tdata<> ...@@ -154,6 +155,14 @@ struct tdata<>
"Additional unboxed arguments provided"); "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&&) { } inline tdata(tdata&&) { }
inline tdata(tdata const&) { } inline tdata(tdata const&) { }
...@@ -310,6 +319,15 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -310,6 +319,15 @@ struct tdata<Head, Tail...> : tdata<Tail...>
inline size_t size() const { return num_elements; } 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 // upcast
inline tdata<Tail...>& tail() { return *this; } inline tdata<Tail...>& tail() { return *this; }
...@@ -427,6 +445,22 @@ struct tdata_from_type_list<util::type_list<T...>> ...@@ -427,6 +445,22 @@ struct tdata_from_type_list<util::type_list<T...>>
typedef tdata<T...> type; 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::detail
namespace cppa { namespace cppa {
......
...@@ -59,7 +59,8 @@ struct tuple_cast_impl ...@@ -59,7 +59,8 @@ struct tuple_cast_impl
static constexpr size_t size = static constexpr size_t size =
util::tl_count_not<util::type_list<T...>, is_anything>::value; util::tl_count_not<util::type_list<T...>, is_anything>::value;
static constexpr size_t first_wc = 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; typedef util::fixed_vector<size_t, size> mapping_vector;
static inline option<Result> safe(any_tuple& tup) static inline option<Result> safe(any_tuple& tup)
{ {
...@@ -80,7 +81,7 @@ struct tuple_cast_impl ...@@ -80,7 +81,7 @@ struct tuple_cast_impl
mapping_vector mv; mapping_vector mv;
if (WP == wildcard_position::in_between) 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 // first range
mv.resize(size); mv.resize(size);
...@@ -140,7 +141,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...> ...@@ -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) static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{ {
if ( p.has_values() == false 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()))}; return {Result::from(std::move(tup.vals()))};
} }
...@@ -159,7 +160,8 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...> ...@@ -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) static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{ {
if ( p.has_values() == false 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()))}; return {Result::from(std::move(tup.vals()))};
} }
...@@ -189,7 +191,8 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...> ...@@ -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) static inline option<Result> unsafe(any_tuple& tup, pattern<T...> const& p)
{ {
if ( p.has_values() == false 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); size_t o = tup.size() - (sizeof...(T) - 1);
return Result::offset_subtuple(tup.vals(), o); 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 ...@@ -729,6 +729,26 @@ bool guard_expr<OP, First, Second>::operator()(Args const&... args) const
return ge_invoke(*this, args...); 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 ... // finally ...
namespace placeholders { namespace { namespace placeholders { namespace {
......
...@@ -108,13 +108,6 @@ struct get_arg_types ...@@ -108,13 +108,6 @@ struct get_arg_types
typedef typename trait_type::arg_types 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> template<typename T>
struct is_callable struct is_callable
{ {
...@@ -142,6 +135,25 @@ 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 } } // namespace cppa::util
#endif // CPPA_UTIL_CALLABLE_TRAIT #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> ...@@ -50,6 +50,33 @@ struct left_or_right<util::void_type, Right>
typedef Right type; 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 } } // namespace cppa::util
#endif // LEFT_OR_RIGHT_HPP #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> ...@@ -554,18 +554,93 @@ struct tl_push_front<type_list<ListTypes...>, What>
// list map(list, trait) // 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. * @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; struct tl_map;
template<template<typename> class Fun, typename... Elements> template<typename... Ts, template<typename> class... Funs>
struct tl_map<type_list<Elements...>, Fun> 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) // list zipped_map(trait)
template<class List, template<typename, typename> class Fun> template<class List, template<typename, typename> class Fun>
...@@ -590,8 +665,13 @@ struct tl_zipped_map<type_list<T...>, Fun> ...@@ -590,8 +665,13 @@ struct tl_zipped_map<type_list<T...>, Fun>
template<class List> template<class List>
struct tl_pop_back struct tl_pop_back
{ {
typedef typename tl_reverse<List>::type rlist; typedef typename tl_slice<List, 0, List::size - 1>::type type;
typedef typename tl_reverse<typename rlist::tail>::type type; };
template<>
struct tl_pop_back<type_list<> >
{
typedef type_list<> type;
}; };
// type at(size_t) // type at(size_t)
...@@ -833,7 +913,7 @@ struct tl_is_zipped ...@@ -833,7 +913,7 @@ struct tl_is_zipped
/** /**
* @brief Removes trailing @p What elements from the end. * @brief Removes trailing @p What elements from the end.
*/ */
template<class List, typename What> template<class List, typename What = void_type>
struct tl_trim struct tl_trim
{ {
typedef typename util::if_else< typedef typename util::if_else<
......
...@@ -36,7 +36,7 @@ bool abstract_tuple::equals(const abstract_tuple &other) const ...@@ -36,7 +36,7 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
{ {
return this == &other return this == &other
|| ( size() == other.size() || ( 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) 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