Commit 8f393dc7 authored by neverlord's avatar neverlord

pattern matching

parent 7ee5a950
......@@ -173,10 +173,12 @@ nobase_library_include_HEADERS = \
cppa/serializer.hpp \
cppa/stacked_event_based_actor.hpp \
cppa/to_string.hpp \
cppa/tpartial_function.hpp \
cppa/tuple_cast.hpp \
cppa/type_value_pair.hpp \
cppa/uniform_type_info.hpp \
cppa/util/abstract_uniform_type_info.hpp \
cppa/util/apply_args.hpp \
cppa/util/apply_tuple.hpp \
cppa/util/arg_match_t.hpp \
cppa/util/at.hpp \
......@@ -201,11 +203,13 @@ nobase_library_include_HEADERS = \
cppa/util/is_manipulator.hpp \
cppa/util/is_mutable_ref.hpp \
cppa/util/is_primitive.hpp \
cppa/util/left_or_right.hpp \
cppa/util/producer_consumer_list.hpp \
cppa/util/pt_dispatch.hpp \
cppa/util/pt_token.hpp \
cppa/util/replace_type.hpp \
cppa/util/ripemd_160.hpp \
cppa/util/rm_option.hpp \
cppa/util/rm_ref.hpp \
cppa/util/shared_lock_guard.hpp \
cppa/util/shared_spinlock.hpp \
......
......@@ -258,3 +258,7 @@ cppa/detail/matches.hpp
unit_testing/test__match.cpp
cppa/guard_expr.hpp
src/pattern.cpp
cppa/util/left_or_right.hpp
cppa/util/apply_args.hpp
cppa/tpartial_function.hpp
cppa/util/rm_option.hpp
......@@ -186,6 +186,11 @@ class any_tuple
return any_tuple{simple_view(std::forward<T>(value), token)};
}
void force_detach()
{
m_vals.detach();
}
void reset();
private:
......
......@@ -89,6 +89,11 @@ class cow_ptr
return *this;
}
void detach()
{
(void) detached_ptr();
}
inline void reset(T* value = nullptr) { m_ptr.reset(value); }
inline T* get() { return (m_ptr) ? detached_ptr() : nullptr; }
......
......@@ -61,6 +61,7 @@ class abstract_tuple : public ref_counted
// mutators
virtual void* mutable_at(size_t pos) = 0;
virtual void* mutable_native_data();
// accessors
virtual size_t size() const = 0;
......
......@@ -65,7 +65,7 @@ class ftor_behavior<true, true, F, Args...> : public scheduled_actor
F m_fun;
typedef typename tdata_from_type_list<
typename util::tl_apply<util::type_list<Args...>,
typename util::tl_map<util::type_list<Args...>,
implicit_conversions>::type>::type
tdata_type;
......@@ -104,7 +104,7 @@ class ftor_behavior<false, true, F, Args...> : public scheduled_actor
F m_fun;
typedef typename tdata_from_type_list<
typename util::tl_apply<util::type_list<Args...>,
typename util::tl_map<util::type_list<Args...>,
implicit_conversions>::type>::type
tdata_type;
......
......@@ -274,7 +274,7 @@ template<typename Fun, class Pattern>
struct select_invokable_impl
{
typedef typename util::get_arg_types<Fun>::types qualified_arg_types;
typedef typename util::tl_apply<qualified_arg_types, util::rm_ref>::type
typedef typename util::tl_map<qualified_arg_types, util::rm_ref>::type
arg_types;
static constexpr mapping_policy mp = get_mapping_policy<arg_types>();
typedef invokable_impl<Fun, pattern_policy<mp, Pattern> > type;
......@@ -284,7 +284,7 @@ template<typename Fun>
struct select_invokable_impl<Fun, pattern<anything> >
{
typedef typename util::get_arg_types<Fun>::types qualified_arg_types;
typedef typename util::tl_apply<qualified_arg_types, util::rm_ref>::type
typedef typename util::tl_map<qualified_arg_types, util::rm_ref>::type
arg_types;
typedef typename util::rm_ref<typename arg_types::head>::type arg0;
static_assert(arg_types::size < 2, "functor has too many arguments");
......
......@@ -43,6 +43,7 @@
#include "cppa/util/disable_if.hpp"
#include "cppa/util/arg_match_t.hpp"
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp"
......@@ -65,6 +66,18 @@ inline void* ptr_to(T* what) { return what; }
template<typename T>
inline void const* ptr_to(T const* what) { return what; }
template<typename T>
struct boxed_or_void
{
static constexpr bool value = is_boxed<T>::value;
};
template<>
struct boxed_or_void<util::void_type>
{
static constexpr bool value = true;
};
/*
* "enhanced std::tuple"
*/
......@@ -82,16 +95,25 @@ struct tdata<>
typedef util::void_type back_type;
typedef util::type_list<> types;
static constexpr size_t tdata_size = 0;
static constexpr size_t num_elements = 0;
constexpr tdata() { }
inline tdata(tdata&&) { }
// swallow any number of additional boxed or void_type arguments silently
template<typename... Args>
tdata(Args&&...)
{
typedef util::type_list<typename util::rm_ref<Args>::type...> incoming;
static_assert(util::tl_forall<incoming, boxed_or_void>::value,
"Additional unboxed arguments provided");
}
inline tdata(tdata&) { }
inline tdata(tdata&&) { }
inline tdata(tdata const&) { }
// swallow "arg_match" silently
constexpr tdata(util::wrapped<util::arg_match_t> const&) { }
//// swallow "arg_match" silently
//constexpr tdata(util::wrapped<util::arg_match_t> const&) { }
tdata<>& tail() { return *this; }
......@@ -113,6 +135,49 @@ struct tdata<>
};
template<bool IsBoxed, bool IsFunction, typename Head, typename T>
struct td_filter_
{
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 Head, typename T>
struct td_filter_<false, true, Head, T>
{
static inline T* _(T* arg) { return arg; }
};
template<typename Head, typename T>
struct td_filter_<true, false, Head, T>
{
static inline Head _(T const&) { return Head{}; }
};
template<typename Head, typename T>
struct td_filter_<true, true, Head, T> : td_filter_<true, false, Head, T>
{
};
template<typename Head, typename T>
auto td_filter(T&& arg)
-> decltype(
td_filter_<
is_boxed<typename util::rm_ref<T>::type>::value,
std::is_function<typename util::rm_ref<T>::type>::value,
Head,
typename util::rm_ref<T>::type
>::_(std::forward<T>(arg)))
{
return td_filter_<
is_boxed<typename util::rm_ref<T>::type>::value,
std::is_function<typename util::rm_ref<T>::type>::value,
Head,
typename util::rm_ref<T>::type
>::_(std::forward<T>(arg));
}
template<typename... X, typename... Y>
void tdata_set(tdata<X...>& rhs, tdata<Y...> const& lhs);
......@@ -126,7 +191,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
Head head;
static constexpr size_t tdata_size = (sizeof...(Tail) + 1);
static constexpr size_t num_elements = (sizeof...(Tail) + 1);
typedef Head head_type;
typedef tdata<Tail...> tail_type;
......@@ -142,23 +207,31 @@ struct tdata<Head, Tail...> : tdata<Tail...>
//tdata(Head const& v0, Tail const&... vals) : super(vals...), head(v0) { }
template<typename Arg0, typename... Args>
tdata(Arg0&& arg0, Args&&... args)
: super(std::forward<Args>(args)...)
, head(td_filter<Head>(std::forward<Arg0>(arg0)))
{
}
tdata(tdata const&) = default;
// allow partial initialization
template<typename... Args>
tdata(Head const& v0, Args const&... vals) : super(vals...), head(v0) { }
//template<typename... Args>
//tdata(Head const& v0, Args const&... vals) : super(vals...), head(v0) { }
// allow partial initialization
template<typename... Args>
tdata(Head&& v0, Args const&... vals) : super(vals...), head(std::move(v0)) { }
//template<typename... Args>
//tdata(Head&& v0, Args const&... vals) : super(vals...), head(std::move(v0)) { }
// allow initialization with wrapped<Head> (uses the default constructor)
template<typename... Args>
tdata(util::wrapped<Head> const&, Args const&... vals)
: super(vals...), head()
// allow (partial) initialization from a different tdata
// with traling extra arguments to initialize additional arguments
template<typename... Y>
tdata(tdata<Y...>& other) : super(other.tail()), head(other.head)
{
}
// allow (partial) initialization from a different tdata
// with traling extra arguments to initialize additional arguments
template<typename... Y>
tdata(tdata<Y...> const& other) : super(other.tail()), head(other.head)
{
......@@ -170,6 +243,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
{
}
/*
template<typename... Y>
tdata(Head const& arg, tdata<Y...> const& other)
: super(other), head(arg)
......@@ -203,14 +277,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
: super(), head(other.head, arg)
{
}
// allow initialization with a function pointer or reference
// returning a wrapped<Head>
template<typename...Args>
tdata(util::wrapped<Head>(*)(), Args const&... vals)
: super(vals...), head()
{
}
*/
template<typename... Y>
tdata& operator=(tdata<Y...> const& other)
......
......@@ -73,6 +73,11 @@ class tuple_vals : public abstract_tuple
return &m_data;
}
void* mutable_native_data()
{
return &m_data;
}
inline data_type& data()
{
return m_data;
......
......@@ -46,11 +46,11 @@ template<typename...> class cow_tuple;
// forward declaration of get(detail::tdata<...> const&)
template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
typename util::at<N, Tn...>::type const& get(detail::tdata<Tn...> const&);
// forward declarations of get(tuple<...> const&)
template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(cow_tuple<Tn...> const&);
typename util::at<N, Tn...>::type const& get(cow_tuple<Tn...> const&);
// forward declarations of get_ref(detail::tdata<...>&)
template<size_t N, typename... Tn>
......@@ -60,6 +60,13 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(cow_tuple<Tn...>&);
// support container-like access for type lists containing tokens
template<size_t N, typename... Ts>
typename util::at<N, Ts...>::type get(util::type_list<Ts...> const&)
{
return {};
}
} // namespace cppa
#endif // GET_HPP
......@@ -37,8 +37,12 @@
#include <functional>
#include <type_traits>
#include "cppa/config.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/detail/tdata.hpp"
......@@ -54,6 +58,8 @@ enum operator_id
logical_and_op, logical_or_op,
// pseudo operators for function invocation
exec_fun1_op, exec_fun2_op, exec_fun3_op,
// operator to invoke a given functor with all arguments forwarded
exec_xfun_op,
// pseudo operator to store function parameters
dummy_op
};
......@@ -157,6 +163,15 @@ typename gbind3<Fun, T1, T2, T3>::result gbind(Fun fun, T1 t1, T2 t2, T3 t3)
return {fun, t1, t2, t3};
}
/**
* @brief Call wrapper for any given functor returning a boolean.
*/
template<typename Fun>
guard_expr<exec_xfun_op, Fun, util::void_type> gcall(Fun fun)
{
return {fun, util::void_type{}};
}
struct ge_search_container
{
bool sc;
......@@ -301,6 +316,20 @@ struct guard_placeholder
};
template<typename T>
struct ge_mutable_reference_wrapper
{
T* value;
ge_mutable_reference_wrapper() : value(nullptr) { }
ge_mutable_reference_wrapper(T&&) = delete;
ge_mutable_reference_wrapper(T const&) = delete;
ge_mutable_reference_wrapper(T& vref) : value(&vref) { }
ge_mutable_reference_wrapper(ge_mutable_reference_wrapper const&) = default;
ge_mutable_reference_wrapper& operator=(ge_mutable_reference_wrapper const&) = default;
T& get() { CPPA_REQUIRE(value != 0); return *value; }
operator T& () { CPPA_REQUIRE(value != 0); return *value; }
};
template<typename T>
struct ge_reference_wrapper
{
......@@ -310,8 +339,8 @@ struct ge_reference_wrapper
ge_reference_wrapper(T const& val_ref) : value(&val_ref) { }
ge_reference_wrapper(ge_reference_wrapper const&) = default;
ge_reference_wrapper& operator=(ge_reference_wrapper const&) = default;
T const& get() const { return *value; }
operator T const& () const { return *value; }
T const& get() const { CPPA_REQUIRE(value != 0); return *value; }
operator T const& () const { CPPA_REQUIRE(value != 0); return *value; }
};
// support use of gref(BooleanVariable) as receive loop 'guard'
......@@ -352,11 +381,11 @@ struct ge_unbound<ge_reference_wrapper<T>, Tuple>
// unbound type of placeholder
template<int X, typename... Ts>
struct ge_unbound<guard_placeholder<X>, detail::tdata<Ts...> >
struct ge_unbound<guard_placeholder<X>, detail::tdata<std::reference_wrapper<Ts>...> >
{
static_assert(X < sizeof...(Ts),
"Cannot unbind placeholder (too few arguments)");
typedef typename std::remove_pointer<typename util::at<X, Ts...>::type>::type type;
typedef typename util::at<X, Ts...>::type type;
};
// operators, operators, operators
......@@ -435,6 +464,12 @@ struct ge_result_<guard_expr<OP, First, Second>, Tuple>
*static_cast<rhs_type const*>(nullptr))) type;
};
template<typename Fun, class Tuple>
struct ge_result_<guard_expr<exec_xfun_op, Fun, util::void_type>, Tuple>
{
typedef bool type;
};
template<typename First, typename Second, class Tuple>
struct ge_result_<guard_expr<exec_fun1_op, First, Second>, Tuple>
{
......@@ -516,9 +551,9 @@ inline T const& ge_resolve(Tuple const&, ge_reference_wrapper<T> const& value)
template<class Tuple, int X>
inline auto ge_resolve(Tuple const& tup, guard_placeholder<X>)
-> decltype(*get<X>(tup))
-> decltype(get<X>(tup).get())
{
return *get<X>(tup);
return get<X>(tup).get();
}
template<class Tuple, operator_id OP, typename First, typename Second>
......@@ -557,6 +592,15 @@ struct ge_eval_<logical_or_op, Tuple, First, Second>
}
};
template<class Tuple, typename Fun>
struct ge_eval_<exec_xfun_op, Tuple, Fun, util::void_type>
{
static inline bool _(Tuple const& tup, Fun const& fun, util::void_type const&)
{
return util::unchecked_apply_tuple<bool>(fun, tup);
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<exec_fun1_op, Tuple, First, Second>
{
......@@ -618,9 +662,10 @@ auto ge_invoke_step2(guard_expr<OP, First, Second> const& ge,
template<operator_id OP, typename First, typename Second, typename... Args>
auto ge_invoke(guard_expr<OP, First, Second> const& ge,
Args const&... args)
-> typename ge_result<OP, First, Second, detail::tdata<Args*...>>::type
-> typename ge_result<OP, First, Second,
detail::tdata<std::reference_wrapper<const Args>...>>::type
{
detail::tdata<Args const*...> tup{&args...};
detail::tdata<std::reference_wrapper<const Args>...> tup{args...};
return ge_invoke_step2(ge, tup);
}
......@@ -630,7 +675,7 @@ struct ge_invoke_helper
GuardExpr const& ge;
ge_invoke_helper(GuardExpr const& arg) : ge(arg) { }
template<typename... Args>
bool operator()(Args&&... args)
bool operator()(Args&&... args) const
{
return ge_invoke(ge, std::forward<Args>(args)...);
}
......
......@@ -117,7 +117,7 @@ class rvalue_builder
typedef typename get_callable_trait<F>::type ctrait;
typedef typename ctrait::arg_types raw_arg_types;
static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_arg_types,rm_ref>::type arg_types;
typedef typename tl_map<raw_arg_types,rm_ref>::type arg_types;
typedef typename tl_concat<types,arg_types>::type full_types;
typedef typename pattern_from_type_list<full_types>::type epattern;
return get_invokable_impl<epattern>(std::forward<F>(f),
......@@ -231,7 +231,7 @@ class on_the_fly_rvalue_builder
typedef typename get_callable_trait<F>::type ctrait;
typedef typename ctrait::arg_types raw_types;
static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_types,rm_ref>::type types;
typedef typename tl_map<raw_types,rm_ref>::type types;
typedef typename pattern_from_type_list<types>::type pattern_type;
return get_invokable_impl<pattern_type>(std::forward<F>(f));
}
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 TPARTIAL_FUNCTION_HPP
#define TPARTIAL_FUNCTION_HPP
#include <cstddef>
#include <type_traits>
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/apply_args.hpp"
#include "cppa/util/left_or_right.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/is_mutable_ref.hpp"
namespace cppa {
template<class Expr, class Guard, typename Result, typename... Args>
class tpartial_function
{
typedef typename util::get_callable_trait<Expr>::type ctrait;
typedef typename ctrait::arg_types ctrait_args;
static_assert(util::tl_exists<util::type_list<Args...>,
std::is_rvalue_reference >::value == false,
"partial functions using rvalue arguments are not supported");
public:
typedef util::type_list<Args...> arg_types;
static constexpr size_t num_arguments = sizeof...(Args);
static constexpr bool manipulates_args =
util::tl_exists<arg_types, util::is_mutable_ref>::value;
template<typename Fun, typename... G>
tpartial_function(Fun&& fun, G&&... guard_args)
: m_guard(std::forward<G>(guard_args)...)
, m_expr(std::forward<Fun>(fun))
{
}
tpartial_function(tpartial_function&& other)
: m_guard(std::move(other.m_guard))
, m_expr(std::move(other.m_expr))
{
}
tpartial_function(tpartial_function const&) = default;
bool defined_at(typename util::rm_ref<Args>::type const&... args) const
{
return m_guard(args...);
}
Result operator()(Args... args) const
{
return util::apply_args<Result, ctrait_args::size, sizeof...(Args)>
::_(m_expr, args...);
}
private:
Guard m_guard;
Expr m_expr;
};
template<class Expr, class Guard, typename Args,
typename Result = util::void_type, size_t Step = 0>
struct get_tpartial_function;
template<class Expr, class Guard, typename... Args, typename Result>
struct get_tpartial_function<Expr, Guard, util::type_list<Args...>, Result, 1>
{
typedef tpartial_function<Expr, Guard, Result, Args...> type;
};
template<class Expr, class Guard, typename... Args>
struct get_tpartial_function<Expr, Guard,
util::type_list<Args...>, util::void_type, 0>
{
typedef typename util::get_callable_trait<Expr>::type ctrait;
typedef typename ctrait::arg_types arg_types;
static_assert(arg_types::size <= sizeof...(Args),
"Functor takes too much arguments");
typedef typename get_tpartial_function<
Expr,
Guard,
// fill arg_types of Expr from left with const Args&
typename util::tl_zip<
typename util::tl_pad_left<
typename ctrait::arg_types,
sizeof...(Args)
>::type,
util::type_list<Args const&...>,
util::left_or_right
>::type,
typename ctrait::result_type,
1
>::type
type;
};
} // namespace cppa
#endif // TPARTIAL_FUNCTION_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 APPLY_ARGS_HPP
#define APPLY_ARGS_HPP
#include <cstddef>
namespace cppa { namespace util {
template<typename Result, size_t NumFunctorArgs, size_t NumArgs>
struct apply_args
{
template<class Fun, typename Arg0, typename... Args>
static Result _(Fun const& fun, Arg0&&, Args&&... args)
{
return apply_args<Result, NumFunctorArgs, sizeof...(Args)>
::_(fun, std::forward<Args>(args)...);
}
};
template<typename Result, size_t X>
struct apply_args<Result, X, X>
{
template<class Fun, typename... Args>
static Result _(Fun const& fun, Args&&... args)
{
return fun(std::forward<Args>(args)...);
}
};
} } // namespace cppa::util
#endif // APPLY_ARGS_HPP
......@@ -43,7 +43,7 @@ template<typename Result, bool IsManipulator, size_t... Range>
struct apply_tuple_impl
{
template<typename F, template<typename...> class Tuple, typename... T>
static Result apply(F&& f, Tuple<T...> const& args)
static Result apply(F& f, Tuple<T...> const& args)
{
return f(get<Range>(args)...);
}
......@@ -53,7 +53,7 @@ template<typename Result, size_t... Range>
struct apply_tuple_impl<Result, true, Range...>
{
template<typename F, template<typename...> class Tuple, typename... T>
static Result apply(F&& f, Tuple<T...>& args)
static Result apply(F& f, Tuple<T...>& args)
{
return f(get_ref<Range>(args)...);
}
......@@ -75,7 +75,7 @@ template<typename Result, bool IsManipulator>
struct apply_tuple_util<Result, IsManipulator, 1, 0>
{
template<typename F, class Unused>
static Result apply(F&& f, Unused const&)
static Result apply(F& f, Unused const&)
{
return f();
}
......@@ -119,6 +119,14 @@ Result unchecked_apply_tuple_in_range(F&& fun, Tuple<T...> const& tup)
::apply(std::forward<F>(fun), tup);
}
template<typename Result, size_t From, size_t To,
typename F, template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple_in_range(F&& fun, Tuple<T...>& tup)
{
return apply_tuple_util<Result, true, From, To>
::apply(std::forward<F>(fun), tup);
}
// applies all values of @p tup to @p fun
// does not evaluate result type of functor
template<typename Result, typename F,
......@@ -129,6 +137,16 @@ Result unchecked_apply_tuple(F&& fun, Tuple<T...> const& tup)
(std::forward<F>(fun), tup);
}
// applies all values of @p tup to @p fun
// does not evaluate result type of functor
template<typename Result, typename F,
template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple(F&& fun, Tuple<T...>& tup)
{
return unchecked_apply_tuple_in_range<Result, 0, sizeof...(T) - 1>
(std::forward<F>(fun), tup);
}
} } // namespace cppa::util
#endif // APPLY_TUPLE_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 LEFT_OR_RIGHT_HPP
#define LEFT_OR_RIGHT_HPP
#include "cppa/util/void_type.hpp"
namespace cppa { namespace util {
/**
* @brief Evaluates to @p Right if @p Left == void_type, @p Left otherwise.
*/
template<typename Left, typename Right>
struct left_or_right
{
typedef Left type;
};
template<typename Right>
struct left_or_right<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 RM_OPTION_HPP
#define RM_OPTION_HPP
#include "cppa/option.hpp"
namespace cppa { namespace util {
template<typename T>
struct rm_option
{
typedef T type;
};
template<typename T>
struct rm_option<option<T> >
{
typedef T type;
};
} } // namespace cppa::util
#endif // RM_OPTION_HPP
......@@ -39,28 +39,32 @@ template<bool BeginLessEnd, size_t Begin, size_t End>
struct static_foreach_impl
{
template<typename Container, typename Fun, typename... Args>
static inline void _(Container const& c, Fun& f, Args const&... args)
static inline void _(Container const& c, Fun& f, Args&&... args)
{
f(get<Begin>(c), args...);
static_foreach_impl<(Begin+1 < End), Begin+1, End>::_(c, f, args...);
f(get<Begin>(c), std::forward<Args>(args)...);
static_foreach_impl<(Begin+1 < End), Begin+1, End>
::_(c, f, std::forward<Args>(args)...);
}
template<typename Container, typename Fun, typename... Args>
static inline void _ref(Container& c, Fun& f, Args const&... args)
static inline void _ref(Container& c, Fun& f, Args&&... args)
{
f(get_ref<Begin>(c), args...);
static_foreach_impl<(Begin+1 < End), Begin+1, End>::_ref(c, f, args...);
f(get_ref<Begin>(c), std::forward<Args>(args)...);
static_foreach_impl<(Begin+1 < End), Begin+1, End>
::_ref(c, f, std::forward<Args>(args)...);
}
template<typename Container, typename Fun, typename... Args>
static inline bool eval(Container const& c, Fun& f, Args const&... args)
static inline bool eval(Container const& c, Fun& f, Args&&... args)
{
return f(get<Begin>(c), args...)
&& static_foreach_impl<(Begin+1 < End), Begin+1, End>::eval(c, f, args...);
return f(get<Begin>(c), std::forward<Args>(args)...)
&& static_foreach_impl<(Begin+1 < End), Begin+1, End>
::eval(c, f, std::forward<Args>(args)...);
}
template<typename Container, typename Fun, typename... Args>
static inline bool eval_or(Container const& c, Fun& f, Args const&... args)
static inline bool eval_or(Container const& c, Fun& f, Args&&... args)
{
return f(get<Begin>(c), args...)
|| static_foreach_impl<(Begin+1 < End), Begin+1, End>::eval_or(c, f, args...);
return f(get<Begin>(c), std::forward<Args>(args)...)
|| static_foreach_impl<(Begin+1 < End), Begin+1, End>
::eval_or(c, f, std::forward<Args>(args)...);
}
};
......@@ -68,13 +72,13 @@ template<size_t X, size_t Y>
struct static_foreach_impl<false, X, Y>
{
template<typename... Args>
static inline void _(Args const&...) { }
static inline void _(Args&&...) { }
template<typename... Args>
static inline void _ref(Args const&...) { }
static inline void _ref(Args&&...) { }
template<typename... Args>
static inline bool eval(Args const&...) { return true; }
static inline bool eval(Args&&...) { return true; }
template<typename... Args>
static inline bool eval_or(Args const&...) { return false; }
static inline bool eval_or(Args&&...) { return false; }
};
/**
......
This diff is collapsed.
......@@ -44,6 +44,12 @@ struct type_pair
typedef Second second;
};
template<typename First, typename Second>
struct to_type_pair
{
typedef type_pair<First, Second> type;
};
template<class What>
struct is_type_pair
{
......
......@@ -55,4 +55,9 @@ void const* abstract_tuple::native_data() const
return nullptr;
}
void* abstract_tuple::mutable_native_data()
{
return nullptr;
}
} } // namespace cppa::detail
......@@ -103,8 +103,9 @@ if (!(line_of_code)) \
#endif
#define CPPA_ERROR(err_msg) \
std::cerr << err_msg << std::endl; \
++cppa_ts.error_count
std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \
<< ": " << err_msg << std::endl; \
++cppa_ts.error_count
#define CPPA_CHECK_NOT_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) != (rhs_loc)))
......
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