Commit 996ab01d authored by Dominik Charousset's avatar Dominik Charousset

maintenance

this patch removes the old `apply_tuple` function family
(replaced by `apply_args`), removes `partially_apply_args`
(use `int_list` for indices instead), and cleans up unit test macros
parent 98998f93
...@@ -136,7 +136,6 @@ cppa/tuple_cast.hpp ...@@ -136,7 +136,6 @@ cppa/tuple_cast.hpp
cppa/uniform_type_info.hpp cppa/uniform_type_info.hpp
cppa/util/abstract_uniform_type_info.hpp cppa/util/abstract_uniform_type_info.hpp
cppa/util/apply_args.hpp cppa/util/apply_args.hpp
cppa/util/apply_tuple.hpp
cppa/util/arg_match_t.hpp cppa/util/arg_match_t.hpp
cppa/util/at.hpp cppa/util/at.hpp
cppa/util/buffer.hpp cppa/util/buffer.hpp
...@@ -274,21 +273,21 @@ src/yield_interface.cpp ...@@ -274,21 +273,21 @@ src/yield_interface.cpp
unit_testing/ping_pong.cpp unit_testing/ping_pong.cpp
unit_testing/ping_pong.hpp unit_testing/ping_pong.hpp
unit_testing/test.hpp unit_testing/test.hpp
unit_testing/test__atom.cpp unit_testing/test_atom.cpp
unit_testing/test__fixed_vector.cpp unit_testing/test_fixed_vector.cpp
unit_testing/test__intrusive_containers.cpp unit_testing/test_intrusive_containers.cpp
unit_testing/test__intrusive_ptr.cpp unit_testing/test_intrusive_ptr.cpp
unit_testing/test__local_group.cpp unit_testing/test_local_group.cpp
unit_testing/test__match.cpp unit_testing/test_match.cpp
unit_testing/test__primitive_variant.cpp unit_testing/test_primitive_variant.cpp
unit_testing/test__remote_actor.cpp unit_testing/test_remote_actor.cpp
unit_testing/test__ripemd_160.cpp unit_testing/test_ripemd_160.cpp
unit_testing/test__serialization.cpp unit_testing/test_serialization.cpp
unit_testing/test__spawn.cpp unit_testing/test_spawn.cpp
unit_testing/test__sync_send.cpp unit_testing/test_sync_send.cpp
unit_testing/test__tuple.cpp unit_testing/test_tuple.cpp
unit_testing/test__type_list.cpp unit_testing/test_metaprogramming.cpp
unit_testing/test__uniform_type.cpp unit_testing/test_uniform_type.cpp
unit_testing/test__yield_interface.cpp unit_testing/test_yield_interface.cpp
cppa/memory_cached_mixin.hpp cppa/memory_cached_mixin.hpp
unit_testing/test.cpp unit_testing/test.cpp
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/fixed_vector.hpp" #include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp" #include "cppa/detail/tuple_vals.hpp"
......
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
#include <type_traits> #include <type_traits>
#include "cppa/util/rm_ref.hpp" #include "cppa/util/rm_ref.hpp"
#include "cppa/util/apply_tuple.hpp" #include "cppa/util/int_list.hpp"
#include "cppa/util/apply_args.hpp"
#include "cppa/detail/tdata.hpp" #include "cppa/detail/tdata.hpp"
#include "cppa/scheduled_actor.hpp" #include "cppa/scheduled_actor.hpp"
...@@ -73,7 +74,9 @@ class ftor_behavior<true, true, F, Args...> : public scheduled_actor { ...@@ -73,7 +74,9 @@ class ftor_behavior<true, true, F, Args...> : public scheduled_actor {
ftor_behavior(F ptr, const Args&... args) : m_fun(ptr), m_args(args...) { } ftor_behavior(F ptr, const Args&... args) : m_fun(ptr), m_args(args...) { }
virtual void act() { util::apply_tuple(m_fun, m_args); } virtual void act() {
util::apply_args(m_fun, m_args, util::get_indices(m_args));
}
}; };
...@@ -115,7 +118,9 @@ class ftor_behavior<false, true, F, Args...> : public scheduled_actor { ...@@ -115,7 +118,9 @@ class ftor_behavior<false, true, F, Args...> : public scheduled_actor {
, m_args(args...) { , m_args(args...) {
} }
virtual void act() { util::apply_tuple(m_fun, m_args); } virtual void act() {
util::apply_args(m_fun, m_args, util::get_indices(m_args));
}
}; };
......
...@@ -38,42 +38,34 @@ ...@@ -38,42 +38,34 @@
#include "cppa/util/rm_option.hpp" #include "cppa/util/rm_option.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/apply_args.hpp" #include "cppa/util/apply_args.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/left_or_right.hpp" #include "cppa/util/left_or_right.hpp"
#include "cppa/detail/tdata.hpp" #include "cppa/detail/tdata.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<class PartialFun> template<typename Fun, typename Tuple, long... Is>
struct projection_helper { inline bool is_defined_at(Fun& f, Tuple& tup, util::int_list<Is...>) {
const PartialFun& fun; return f.defined_at(get_cv_aware<Is>(tup)...);
projection_helper(const PartialFun& pfun) : fun(pfun) { } }
template<typename... Args>
bool operator()(Args&&... args) const { template<typename ProjectionFuns, typename... Args>
if (fun.defined_at(std::forward<Args>(args)...)) { struct collected_args_tuple {
fun(std::forward<Args>(args)...); typedef typename tdata_from_type_list<
return true; typename util::tl_zip<
} typename util::tl_map<
return false; ProjectionFuns,
} util::get_result_type,
}; util::rm_option
>::type,
template<class PartialFun> typename util::tl_map<
struct result_fetching_projection_helper { util::type_list<Args...>,
typedef typename PartialFun::result_type result_type; mutable_gref_wrapped
const PartialFun& fun; >::type,
result_type& result; util::left_or_right
result_fetching_projection_helper(const PartialFun& pfun, result_type& res) >::type
: fun(pfun), result(res) { } >::type
template<typename... Args> type;
bool operator()(Args&&... args) const {
if (fun.defined_at(std::forward<Args>(args)...)) {
result = fun(std::forward<Args>(args)...);
return true;
}
return false;
}
}; };
/** /**
...@@ -95,55 +87,34 @@ class projection { ...@@ -95,55 +87,34 @@ class projection {
projection(const projection&) = default; projection(const projection&) = default;
/** /**
* @brief Invokes @p fun with a projection of <tt>args...</tt>. * @brief Invokes @p fun with a projection of <tt>args...</tt> and stores
* the result of @p fun in @p result.
*/ */
template<class PartialFun> template<class PartialFun>
bool operator()(PartialFun& fun, Args... args) const { bool invoke(PartialFun& fun, typename PartialFun::result_type& result, Args... args) const {
typedef typename util::tl_zip< typename collected_args_tuple<ProjectionFuns,Args...>::type pargs;
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)...)) { if (collect(pargs, m_funs, std::forward<Args>(args)...)) {
projection_helper<PartialFun> helper{fun};
auto indices = util::get_indices(pargs); auto indices = util::get_indices(pargs);
return util::apply_args(helper, pargs, indices); if (is_defined_at(fun, pargs, indices)) {
result = util::apply_args(fun, pargs, indices);
return true;
}
} }
return false; return false;
} }
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
template<class PartialFun> template<class PartialFun>
bool invoke(PartialFun& fun, typename PartialFun::result_type& result, Args... args) const { bool operator()(PartialFun& fun, Args... args) const {
typedef typename PartialFun::result_type result_type; typename collected_args_tuple<ProjectionFuns,Args...>::type pargs;
typedef typename util::tl_zip< auto indices = util::get_indices(pargs);
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)...)) { if (collect(pargs, m_funs, std::forward<Args>(args)...)) {
result_fetching_projection_helper<PartialFun> helper{fun, result}; if (is_defined_at(fun, pargs, indices)) {
auto indices = util::get_indices(pargs); util::apply_args(fun, pargs, indices);
return util::apply_args(helper, pargs, indices); return true;
}
} }
return false; return false;
} }
...@@ -151,13 +122,13 @@ class projection { ...@@ -151,13 +122,13 @@ class projection {
private: private:
template<typename Storage, typename T> template<typename Storage, typename T>
static inline bool fetch_(Storage& storage, T&& value) { static inline bool store(Storage& storage, T&& value) {
storage = std::forward<T>(value); storage = std::forward<T>(value);
return true; return true;
} }
template<class Storage> template<class Storage>
static inline bool fetch_(Storage& storage, option<Storage>&& value) { static inline bool store(Storage& storage, option<Storage>&& value) {
if (value) { if (value) {
storage = std::move(*value); storage = std::move(*value);
return true; return true;
...@@ -165,14 +136,16 @@ class projection { ...@@ -165,14 +136,16 @@ class projection {
return false; return false;
} }
template<class Storage, typename Fun, typename T> template<typename T>
static inline bool fetch(Storage& storage, const Fun& fun, T&& arg) { static inline auto fetch(const util::void_type&, T&& arg)
return fetch_(storage, fun(std::forward<T>(arg))); -> decltype(std::forward<T>(arg)) {
return std::forward<T>(arg);
} }
template<typename Storage, typename T> template<typename Fun, typename T>
static inline bool fetch(Storage& storage, const util::void_type&, T&& arg) { static inline auto fetch(const Fun& fun, T&& arg)
return fetch_(storage, std::forward<T>(arg)); -> decltype(fun(std::forward<T>(arg))) {
return fun(std::forward<T>(arg));
} }
static inline bool collect(tdata<>&, const tdata<>&) { static inline bool collect(tdata<>&, const tdata<>&) {
...@@ -182,7 +155,7 @@ class projection { ...@@ -182,7 +155,7 @@ class projection {
template<class TData, class Trans, typename T0, typename... Ts> template<class TData, class Trans, typename T0, typename... Ts>
static inline bool collect(TData& td, const Trans& tr, static inline bool collect(TData& td, const Trans& tr,
T0&& arg0, Ts&&... args) { T0&& arg0, Ts&&... args) {
return fetch(td.head, tr.head, std::forward<T0>(arg0)) return store(td.head, fetch(tr.head, std::forward<T0>(arg0)))
&& collect(td.tail(), tr.tail(), std::forward<Ts>(args)...); && collect(td.tail(), tr.tail(), std::forward<Ts>(args)...);
} }
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include "cppa/util/at.hpp" #include "cppa/util/at.hpp"
#include "cppa/util/rm_ref.hpp" #include "cppa/util/rm_ref.hpp"
#include "cppa/util/void_type.hpp" #include "cppa/util/void_type.hpp"
#include "cppa/util/apply_tuple.hpp" #include "cppa/util/apply_args.hpp"
#include "cppa/detail/tdata.hpp" #include "cppa/detail/tdata.hpp"
...@@ -597,7 +597,7 @@ struct ge_eval_<logical_or_op, Tuple, First, Second> { ...@@ -597,7 +597,7 @@ struct ge_eval_<logical_or_op, Tuple, First, Second> {
template<class Tuple, typename Fun> template<class Tuple, typename Fun>
struct ge_eval_<exec_xfun_op, Tuple, Fun, util::void_type> { struct ge_eval_<exec_xfun_op, Tuple, Fun, util::void_type> {
static inline bool _(const Tuple& tup, const Fun& fun, const util::void_type&) { static inline bool _(const Tuple& tup, const Fun& fun, const util::void_type&) {
return util::unchecked_apply_tuple<bool>(fun, tup); return util::apply_args(fun, tup, util::get_indices(tup));
} }
}; };
...@@ -696,7 +696,7 @@ ge_invoke_any(const guard_expr<OP, First, Second>& ge, ...@@ -696,7 +696,7 @@ ge_invoke_any(const guard_expr<OP, First, Second>& ge,
auto x = tuple_cast(tup, cast_token); auto x = tuple_cast(tup, cast_token);
CPPA_REQUIRE(static_cast<bool>(x) == true); CPPA_REQUIRE(static_cast<bool>(x) == true);
ge_invoke_helper<guard_expr<OP, First, Second> > f{ge}; ge_invoke_helper<guard_expr<OP, First, Second> > f{ge};
return util::unchecked_apply_tuple<result_type>(f, *x); return util::apply_args(f, *x, util::get_indices(*x));
} }
template<operator_id OP, typename First, typename Second> template<operator_id OP, typename First, typename Second>
......
...@@ -48,6 +48,7 @@ class tpartial_function { ...@@ -48,6 +48,7 @@ class tpartial_function {
typedef typename util::get_callable_trait<Expr>::type ctrait; typedef typename util::get_callable_trait<Expr>::type ctrait;
typedef typename ctrait::arg_types ctrait_args; typedef typename ctrait::arg_types ctrait_args;
static constexpr size_t num_expr_args = util::tl_size<ctrait_args>::value;
static_assert(util::tl_exists<util::type_list<Args...>, static_assert(util::tl_exists<util::type_list<Args...>,
std::is_rvalue_reference >::value == false, std::is_rvalue_reference >::value == false,
...@@ -77,13 +78,14 @@ class tpartial_function { ...@@ -77,13 +78,14 @@ class tpartial_function {
tpartial_function(const tpartial_function&) = default; tpartial_function(const tpartial_function&) = default;
//bool defined_at(const typename util::rm_ref<Args>::type&... args) const
bool defined_at(Args... args) const { bool defined_at(Args... args) const {
return m_guard(args...); return m_guard(args...);
} }
result_type operator()(Args... args) const { result_type operator()(Args... args) const {
return util::partially_apply<result_type,util::tl_size<ctrait_args>::value>(m_expr, args...); auto targs = std::forward_as_tuple(args...);
auto indices = util::get_right_indices<num_expr_args>(targs);
return util::apply_args(m_expr, targs, indices);
} }
private: private:
......
...@@ -56,29 +56,6 @@ inline auto apply_args_suffxied(F& f, Tuple& tup, util::int_list<Is...>, Args&&. ...@@ -56,29 +56,6 @@ inline auto apply_args_suffxied(F& f, Tuple& tup, util::int_list<Is...>, Args&&.
return f(get_cv_aware<Is>(tup)..., std::forward<Args>(args)...); return f(get_cv_aware<Is>(tup)..., std::forward<Args>(args)...);
} }
template<typename Result, size_t NumFunctorArgs, size_t NumArgs>
struct partially_apply_helper {
template<class Fun, typename Arg0, typename... Args>
static inline Result _(const Fun& fun, Arg0&&, Args&&... args) {
return partially_apply_helper<Result, NumFunctorArgs, sizeof...(Args)>
::_(fun, std::forward<Args>(args)...);
}
};
template<typename Result, size_t X>
struct partially_apply_helper<Result, X, X> {
template<class Fun, typename... Args>
static inline Result _(const Fun& fun, Args&&... args) {
return fun(std::forward<Args>(args)...);
}
};
template<typename Result, size_t Num, typename F, typename... Args>
inline Result partially_apply(F& f, Args&&... args) {
return partially_apply_helper<Result,Num,sizeof...(Args)>
::_(f, std::forward<Args>(args)...);
}
} } // namespace cppa::util } } // namespace cppa::util
#endif // CPPA_APPLY_ARGS_HPP #endif // CPPA_APPLY_ARGS_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 CPPA_APPLY_TUPLE_HPP
#define CPPA_APPLY_TUPLE_HPP
#include <type_traits>
#include "cppa/get.hpp"
#include "cppa/util/is_manipulator.hpp"
#include "cppa/util/callable_trait.hpp"
namespace cppa { namespace util {
template<typename Result, bool IsManipulator, size_t... Range>
struct apply_tuple_impl {
template<typename F, class Tuple>
static inline Result apply(F& f, const Tuple& args) {
return f(get<Range>(args)...);
}
};
template<typename Result, size_t... Range>
struct apply_tuple_impl<Result, true, Range...> {
template<typename F, class Tuple>
static inline Result apply(F& f, Tuple& args) {
return f(get_ref<Range>(args)...);
}
};
template<typename Result, bool IsManipulator, int From, int To, int... Args>
struct apply_tuple_util
: apply_tuple_util<Result, IsManipulator, From, To-1, To, Args...> {
};
template<typename Result, bool IsManipulator, int X, int... Args>
struct apply_tuple_util<Result, IsManipulator, X, X, Args...>
: apply_tuple_impl<Result, IsManipulator, X, Args...> {
};
template<typename Result, bool IsManipulator>
struct apply_tuple_util<Result, IsManipulator, 1, 0> {
template<typename F, class Unused>
static Result apply(F& f, const Unused&) {
return f();
}
};
template<typename F, template<typename...> class Tuple, typename... T>
typename get_result_type<F>::type apply_tuple(F&& fun, Tuple<T...>& tup) {
typedef typename get_result_type<F>::type result_type;
typedef typename get_arg_types<F>::types fun_args;
static constexpr size_t tup_size = sizeof...(T);
static_assert(tup_size >= fun_args::size,
"cannot conjure up additional arguments");
static constexpr size_t args_size = fun_args::size;
static constexpr size_t from = (args_size > 0) ? tup_size - args_size : 1;
static constexpr size_t to = (args_size > 0) ? tup_size - 1 : 0;
return apply_tuple_util<result_type, is_manipulator<F>::value, from, to>
::apply(std::forward<F>(fun), tup);
}
template<typename F, template<typename...> class Tuple, typename... T>
typename get_result_type<F>::type apply_tuple(F&& fun, const Tuple<T...>& tup) {
typedef typename get_result_type<F>::type result_type;
typedef typename get_arg_types<F>::types fun_args;
static constexpr size_t tup_size = sizeof...(T);
static_assert(tup_size >= fun_args::size,
"cannot conjure up additional arguments");
static constexpr size_t args_size = fun_args::size;
static constexpr size_t from = (args_size > 0) ? tup_size - args_size : 1;
static constexpr size_t to = (args_size > 0) ? tup_size - 1 : 0;
return apply_tuple_util<result_type, is_manipulator<F>::value, from, to>
::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, const Tuple<T...>& tup) {
return apply_tuple_util<Result, false, From, To>
::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,
template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple(F&& fun, const Tuple<T...>& tup) {
return apply_tuple_util<Result, false, 0, sizeof...(T) - 1>
::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,
template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple(F&& fun, Tuple<T...>& tup) {
return apply_tuple_util<Result, true, 0, sizeof...(T) - 1>
::apply(std::forward<F>(fun), tup);
}
} } // namespace cppa::util
#endif // CPPA_APPLY_TUPLE_HPP
...@@ -245,6 +245,21 @@ struct il_slice { ...@@ -245,6 +245,21 @@ struct il_slice {
typedef typename il_slice_<List,il_size<List>::value,First,Last>::type type; typedef typename il_slice_<List,il_size<List>::value,First,Last>::type type;
}; };
/**
* @brief Creates a new list containing the last @p N elements.
*/
template<class List, size_t N>
struct il_right {
static constexpr size_t list_size = il_size<List>::value;
static constexpr size_t first_idx = (list_size > N) ? (list_size - N) : 0;
typedef typename il_slice<List,first_idx,list_size>::type type;
};
template<size_t N>
struct il_right<empty_int_list,N> {
typedef empty_int_list type;
};
// list reverse() // list reverse()
template<class List, long... Vs> template<class List, long... Vs>
...@@ -463,7 +478,6 @@ struct il_range<X,X,Is...> { ...@@ -463,7 +478,6 @@ struct il_range<X,X,Is...> {
typedef int_list<X,Is...> type; typedef int_list<X,Is...> type;
}; };
/** /**
* @brief Creates indices for @p List beginning at @p Pos. * @brief Creates indices for @p List beginning at @p Pos.
*/ */
...@@ -482,7 +496,13 @@ struct il_indices<List<T0,Ts...>,Pos,int_list<Is...>> { ...@@ -482,7 +496,13 @@ struct il_indices<List<T0,Ts...>,Pos,int_list<Is...>> {
}; };
template<typename T> template<typename T>
constexpr auto get_indices(const T&) -> typename util::il_indices<T>::type { constexpr auto get_indices(const T&) -> typename il_indices<T>::type {
return {};
}
template<size_t Num, typename T>
constexpr auto get_right_indices(const T&)
-> typename il_right<typename il_indices<T>::type,Num>::type {
return {}; return {};
} }
......
...@@ -4,15 +4,15 @@ project(cppa_unit_tests CXX) ...@@ -4,15 +4,15 @@ project(cppa_unit_tests CXX)
add_custom_target(all_unit_tests) add_custom_target(all_unit_tests)
macro(add_unit_test name) macro(add_unit_test name)
add_executable(test__${name} test__${name}.cpp test.cpp ${ARGN}) add_executable(test_${name} test_${name}.cpp test.cpp ${ARGN})
target_link_libraries(test__${name} ${CMAKE_DL_LIBS} ${CPPA_LIBRARY} ${PTHREAD_LIBRARIES}) target_link_libraries(test_${name} ${CMAKE_DL_LIBS} ${CPPA_LIBRARY} ${PTHREAD_LIBRARIES})
add_test(${name} ${EXECUTABLE_OUTPUT_PATH}/test__${name}) add_test(${name} ${EXECUTABLE_OUTPUT_PATH}/test_${name})
add_dependencies(test__${name} all_unit_tests) add_dependencies(test_${name} all_unit_tests)
endmacro() endmacro()
add_unit_test(ripemd_160) add_unit_test(ripemd_160)
add_unit_test(atom) add_unit_test(atom)
add_unit_test(type_list) add_unit_test(metaprogramming)
add_unit_test(intrusive_containers) add_unit_test(intrusive_containers)
add_unit_test(serialization) add_unit_test(serialization)
add_unit_test(uniform_type) add_unit_test(uniform_type)
......
...@@ -12,30 +12,20 @@ ...@@ -12,30 +12,20 @@
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/util/scope_guard.hpp" #include "cppa/util/scope_guard.hpp"
void cppa_inc_error_count(); template<typename T1, typename T2>
struct both_integral {
static constexpr bool value = std::is_integral<T1>::value
&& std::is_integral<T2>::value;
};
template<bool V, typename T1, typename T2>
struct enable_integral : std::enable_if<both_integral<T1,T2>::value == V> { };
size_t cppa_error_count(); size_t cppa_error_count();
void cppa_inc_error_count();
void cppa_unexpected_message(const char* fname, size_t line_num); void cppa_unexpected_message(const char* fname, size_t line_num);
void cppa_unexpected_timeout(const char* fname, size_t line_num); void cppa_unexpected_timeout(const char* fname, size_t line_num);
template<typename T1, typename T2>
inline bool cppa_check_value_fun_eq(const T1& value1, const T2& value2,
typename std::enable_if<
!std::is_integral<T1>::value
|| !std::is_integral<T2>::value
>::type* = 0) {
return value1 == value2;
}
template<typename T1, typename T2>
inline bool cppa_check_value_fun_eq(T1 value1, T2 value2,
typename std::enable_if<
std::is_integral<T1>::value
&& std::is_integral<T2>::value
>::type* = 0) {
return value1 == static_cast<T1>(value2);
}
template<typename T> template<typename T>
const T& cppa_stream_arg(const T& value) { const T& cppa_stream_arg(const T& value) {
return value; return value;
...@@ -45,30 +35,41 @@ inline std::string cppa_stream_arg(const cppa::actor_ptr& ptr) { ...@@ -45,30 +35,41 @@ inline std::string cppa_stream_arg(const cppa::actor_ptr& ptr) {
return cppa::to_string(ptr); return cppa::to_string(ptr);
} }
template<typename T1, typename T2> inline void cppa_passed(const char* fname, int line_number) {
inline bool cppa_check_value_fun(const T1& value1, const T2& value2, std::cout << "line " << line_number << " in file " << fname
const char* file_name, << " passed" << std::endl;
int line_number) {
if (cppa_check_value_fun_eq(value1, value2) == false) {
std::cerr << "ERROR in file " << file_name << " on line " << line_number
<< " => expected value: "
<< cppa_stream_arg(value1)
<< ", found: "
<< cppa_stream_arg(value2)
<< std::endl;
cppa_inc_error_count();
return false;
}
return true;
} }
template<typename T1, typename T2> template<typename V1, typename V2>
inline void cppa_check_value_verbose_fun(const T1& value1, const T2& value2, inline void cppa_failed(const V1& v1,
const char* file_name, const V2& v2,
int line_number) { const char* fname,
if (cppa_check_value_fun(value1, value2, file_name, line_number)) { int line_number) {
std::cout << "line " << line_number << " passed" << std::endl; std::cerr << "ERROR in file " << fname << " on line " << line_number
} << " => expected value: "
<< cppa_stream_arg(v1)
<< ", found: "
<< cppa_stream_arg(v2)
<< std::endl;
cppa_inc_error_count();
}
template<typename V1, typename V2>
inline void cppa_check_value(const V1& v1, const V2& v2,
const char* fname,
int line_number,
typename enable_integral<false,V1,V2>::type* = 0) {
if (v1 == v2) cppa_passed(fname, line_number);
else cppa_failed(v1, v2, fname, line_number);
}
template<typename V1, typename V2>
inline void cppa_check_value(V1 v1, V2 v2,
const char* fname,
int line_number,
typename enable_integral<true,V1,V2>::type* = 0) {
if (v1 == static_cast<V1>(v2)) cppa_passed(fname, line_number);
else cppa_failed(v1, v2, fname, line_number);
} }
#define CPPA_TEST(name) \ #define CPPA_TEST(name) \
...@@ -76,21 +77,29 @@ inline void cppa_check_value_verbose_fun(const T1& value1, const T2& value2, ...@@ -76,21 +77,29 @@ inline void cppa_check_value_verbose_fun(const T1& value1, const T2& value2,
std::cout << cppa_error_count() << " error(s) detected" << std::endl; \ std::cout << cppa_error_count() << " error(s) detected" << std::endl; \
}); });
#define CPPA_TEST_RESULT cppa_error_count() #define CPPA_TEST_RESULT() ((cppa_error_count() == 0) ? 0 : -1)
#define CPPA_CHECK_VERBOSE(line_of_code, err_stream) \
if (!(line_of_code)) { \
std::cerr << err_stream << std::endl; \
cppa_inc_error_count(); \
} \
else { \
std::cout << "line " << __LINE__ << " passed" << std::endl; \
} ((void) 0)
#define CPPA_IF_VERBOSE(line_of_code) line_of_code
#define CPPA_CHECK(line_of_code) \ #define CPPA_CHECK(line_of_code) \
if (!(line_of_code)) { \ if (!(line_of_code)) { \
std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \ std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \
<< " => " << #line_of_code << std::endl; \ << " => " << #line_of_code << std::endl; \
cppa_inc_error_count(); \ cppa_inc_error_count(); \
} \ } \
else { \ else { \
std::cout << "line " << __LINE__ << " passed" << std::endl; \ std::cout << "line " << __LINE__ << " passed" << std::endl; \
} ((void) 0) } ((void) 0)
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value_verbose_fun((lhs_loc), (rhs_loc), __FILE__, __LINE__)
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value((lhs_loc), (rhs_loc), __FILE__, __LINE__)
#define CPPA_ERROR(err_msg) \ #define CPPA_ERROR(err_msg) \
std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \ std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \
...@@ -103,20 +112,15 @@ else { \ ...@@ -103,20 +112,15 @@ else { \
#define CPPA_CHECKPOINT() \ #define CPPA_CHECKPOINT() \
std::cout << "checkpoint at line " << __LINE__ << " passed" << std::endl std::cout << "checkpoint at line " << __LINE__ << " passed" << std::endl
// some convenience macros for defining callbacks #define CPPA_UNEXPECTED_TOUT() cppa_unexpected_timeout(__FILE__, __LINE__)
#define CPPA_CHECKPOINT_CB() \
[] { CPPA_CHECKPOINT(); }
#define CPPA_UNEXPECTED_MSG_CB() \
[] { cppa_unexpected_message(__FILE__, __LINE__); }
#define CPPA_UNEXPECTED_TOUT_CB() \ #define CPPA_UNEXPECTED_MSG() cppa_unexpected_message(__FILE__, __LINE__)
[] { cppa_unexpected_timeout(__FILE__, __LINE__); }
#define CPPA_ERROR_CB(err_msg) \ // some convenience macros for defining callbacks
[] { CPPA_ERROR(err_msg); } #define CPPA_CHECKPOINT_CB() [] { CPPA_CHECKPOINT(); }
#define CPPA_ERROR_CB(err_msg) [] { CPPA_ERROR(err_msg); }
typedef std::pair<std::string, std::string> string_pair; #define CPPA_UNEXPECTED_MSG_CB() [] { CPPA_UNEXPECTED_MSG(); }
#define CPPA_UNEXPECTED_TOUT_CB() [] { CPPA_UNEXPECTED_TOUT(); }
inline std::vector<std::string> split(const std::string& str, char delim) { inline std::vector<std::string> split(const std::string& str, char delim) {
std::vector<std::string> result; std::vector<std::string> result;
...@@ -126,8 +130,4 @@ inline std::vector<std::string> split(const std::string& str, char delim) { ...@@ -126,8 +130,4 @@ inline std::vector<std::string> split(const std::string& str, char delim) {
return result; return result;
} }
//using std::cout;
//using std::endl;
//using std::cerr;
#endif // TEST_HPP #endif // TEST_HPP
#include <string>
#include <cstdint>
#include <typeinfo>
#include <type_traits>
#include "test.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/element_at.hpp"
#include "cppa/uniform_type_info.hpp"
using std::cout;
using std::endl;
using std::is_same;
using namespace cppa::util;
int main() {
CPPA_TEST(test__type_list);
typedef type_list<int, float, std::string> l1;
typedef typename tl_reverse<l1>::type r1;
CPPA_CHECK((is_same<int, element_at<0, l1>::type>::value));
CPPA_CHECK((is_same<float, element_at<1, l1>::type>::value));
CPPA_CHECK((is_same<std::string, element_at<2, l1>::type>::value));
CPPA_CHECK(tl_size<l1>::value == 3);
CPPA_CHECK(tl_size<l1>::value == tl_size<r1>::value);
CPPA_CHECK((is_same<element_at<0, l1>::type, element_at<2, r1>::type>::value));
CPPA_CHECK((is_same<element_at<1, l1>::type, element_at<1, r1>::type>::value));
CPPA_CHECK((is_same<element_at<2, l1>::type, element_at<0, r1>::type>::value));
typedef tl_concat<type_list<int>, l1>::type l2;
CPPA_CHECK((is_same<int, tl_head<l2>::type>::value));
CPPA_CHECK((is_same<l1, tl_tail<l2>::type>::value));
return CPPA_TEST_RESULT;
}
...@@ -65,5 +65,5 @@ int main() { ...@@ -65,5 +65,5 @@ int main() {
// "erase" message { atom("b"), atom("a"), atom("c"), 23.f } // "erase" message { atom("b"), atom("a"), atom("c"), 23.f }
} }
); );
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -14,48 +14,48 @@ using cppa::util::fixed_vector; ...@@ -14,48 +14,48 @@ using cppa::util::fixed_vector;
int main() { int main() {
CPPA_TEST(test__fixed_vector); CPPA_TEST(test__fixed_vector);
int arr1[] {1, 2, 3, 4}; int arr1[] {1, 2, 3, 4};
fixed_vector<int, 4> vec1 {1, 2, 3, 4}; fixed_vector<int,4> vec1 {1, 2, 3, 4};
fixed_vector<int, 5> vec2 {4, 3, 2, 1}; fixed_vector<int,5> vec2 {4, 3, 2, 1};
fixed_vector<int, 4> vec3; fixed_vector<int,4> vec3;
for (int i = 1; i <= 4; ++i) vec3.push_back(i); for (int i = 1; i <= 4; ++i) vec3.push_back(i);
fixed_vector<int, 4> vec4 {1, 2}; fixed_vector<int,4> vec4 {1, 2};
fixed_vector<int, 2> vec5 {3, 4}; fixed_vector<int,2> vec5 {3, 4};
vec4.insert(vec4.end(), vec5.begin(), vec5.end()); vec4.insert(vec4.end(), vec5.begin(), vec5.end());
auto vec6 = vec4; auto vec6 = vec4;
CPPA_CHECK_EQUAL(vec1.size(), 4); CPPA_CHECK_EQUAL(4, vec1.size());
CPPA_CHECK_EQUAL(vec2.size(), 4); CPPA_CHECK_EQUAL(4, vec2.size());
CPPA_CHECK_EQUAL(vec3.size(), 4); CPPA_CHECK_EQUAL(4, vec3.size());
CPPA_CHECK_EQUAL(vec4.size(), 4); CPPA_CHECK_EQUAL(4, vec4.size());
CPPA_CHECK_EQUAL(vec5.size(), 2); CPPA_CHECK_EQUAL(2, vec5.size());
CPPA_CHECK_EQUAL(vec6.size(), 4); CPPA_CHECK_EQUAL(4, vec6.size());
CPPA_CHECK_EQUAL(vec1.full(), true); CPPA_CHECK_EQUAL(true, vec1.full());
CPPA_CHECK_EQUAL(vec2.full(), false); CPPA_CHECK_EQUAL(false, vec2.full());
CPPA_CHECK_EQUAL(vec3.full(), true); CPPA_CHECK_EQUAL(true, vec3.full());
CPPA_CHECK_EQUAL(vec4.full(), true); CPPA_CHECK_EQUAL(true, vec4.full());
CPPA_CHECK_EQUAL(vec5.full(), true); CPPA_CHECK_EQUAL(true, vec5.full());
CPPA_CHECK_EQUAL(vec6.full(), true); CPPA_CHECK_EQUAL(true, vec6.full());
CPPA_CHECK(std::equal(vec1.begin(), vec1.end(), arr1)); CPPA_CHECK(std::equal(vec1.begin(), vec1.end(), arr1));
CPPA_CHECK(std::equal(vec2.rbegin(), vec2.rend(), arr1)); CPPA_CHECK(std::equal(vec2.rbegin(), vec2.rend(), arr1));
CPPA_CHECK(std::equal(vec4.begin(), vec4.end(), arr1)); CPPA_CHECK(std::equal(vec4.begin(), vec4.end(), arr1));
CPPA_CHECK(std::equal(vec6.begin(), vec6.end(), arr1)); CPPA_CHECK(std::equal(vec6.begin(), vec6.end(), arr1));
CPPA_CHECK(std::equal(vec6.begin(), vec6.end(), vec2.rbegin())); CPPA_CHECK(std::equal(vec6.begin(), vec6.end(), vec2.rbegin()));
fixed_vector<int, 10> vec7 {5, 9}; fixed_vector<int,10> vec7 {5, 9};
fixed_vector<int, 10> vec8 {1, 2, 3, 4}; fixed_vector<int,10> vec8 {1, 2, 3, 4};
fixed_vector<int, 10> vec9 {6, 7, 8}; fixed_vector<int,10> vec9 {6, 7, 8};
vec7.insert(vec7.begin() + 1, vec9.begin(), vec9.end()); vec7.insert(vec7.begin() + 1, vec9.begin(), vec9.end());
vec7.insert(vec7.begin(), vec8.begin(), vec8.end()); vec7.insert(vec7.begin(), vec8.begin(), vec8.end());
CPPA_CHECK_EQUAL(vec7.full(), false); CPPA_CHECK_EQUAL(false, vec7.full());
fixed_vector<int, 1> vec10 {10}; fixed_vector<int,1> vec10 {10};
vec7.insert(vec7.end(), vec10.begin(), vec10.end()); vec7.insert(vec7.end(), vec10.begin(), vec10.end());
CPPA_CHECK_EQUAL(vec7.full(), true); CPPA_CHECK_EQUAL(true, vec7.full());
CPPA_CHECK((std::is_sorted(vec7.begin(), vec7.end()))); CPPA_CHECK((std::is_sorted(vec7.begin(), vec7.end())));
int arr2[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int arr2[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
CPPA_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2)))); CPPA_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2))));
vec7.assign(std::begin(arr2), std::end(arr2)); vec7.assign(std::begin(arr2), std::end(arr2));
CPPA_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2)))); CPPA_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2))));
vec7.assign(5, 0); vec7.assign(5, 0);
CPPA_CHECK_EQUAL(vec7.size(), 5); CPPA_CHECK_EQUAL(5, vec7.size());
CPPA_CHECK((std::all_of(vec7.begin(), vec7.end(), CPPA_CHECK((std::all_of(vec7.begin(), vec7.end(),
[](int i) { return i == 0; }))); [](int i) { return i == 0; })));
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -81,5 +81,5 @@ int main() { ...@@ -81,5 +81,5 @@ int main() {
x = q.try_pop(); x = q.try_pop();
CPPA_CHECK(x == nullptr); CPPA_CHECK(x == nullptr);
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -48,48 +48,48 @@ int main() { ...@@ -48,48 +48,48 @@ int main() {
CPPA_TEST(test__intrusive_ptr); CPPA_TEST(test__intrusive_ptr);
{ {
auto p = make_counted<class0>(); auto p = make_counted<class0>();
CPPA_CHECK_EQUAL(class0_instances, 1); CPPA_CHECK_EQUAL(1, class0_instances);
CPPA_CHECK(p->unique()); CPPA_CHECK(p->unique());
} }
CPPA_CHECK_EQUAL(class0_instances, 0); CPPA_CHECK_EQUAL(0, class0_instances);
{ {
class0_ptr p; class0_ptr p;
p = new class0; p = new class0;
CPPA_CHECK_EQUAL(class0_instances, 1); CPPA_CHECK_EQUAL(1, class0_instances);
CPPA_CHECK(p->unique()); CPPA_CHECK(p->unique());
} }
CPPA_CHECK_EQUAL(class0_instances, 0); CPPA_CHECK_EQUAL(0, class0_instances);
{ {
class0_ptr p1; class0_ptr p1;
p1 = get_test_rc(); p1 = get_test_rc();
class0_ptr p2 = p1; class0_ptr p2 = p1;
CPPA_CHECK_EQUAL(class0_instances, 1); CPPA_CHECK_EQUAL(1, class0_instances);
CPPA_CHECK_EQUAL(p1->unique(), false); CPPA_CHECK_EQUAL(false, p1->unique());
} }
CPPA_CHECK_EQUAL(class0_instances, 0); CPPA_CHECK_EQUAL(0, class0_instances);
{ {
std::list<class0_ptr> pl; std::list<class0_ptr> pl;
pl.push_back(get_test_ptr()); pl.push_back(get_test_ptr());
pl.push_back(get_test_rc()); pl.push_back(get_test_rc());
pl.push_back(pl.front()->create()); pl.push_back(pl.front()->create());
CPPA_CHECK(pl.front()->unique()); CPPA_CHECK(pl.front()->unique());
CPPA_CHECK_EQUAL(class0_instances, 3); CPPA_CHECK_EQUAL(3, class0_instances);
} }
CPPA_CHECK_EQUAL(class0_instances, 0); CPPA_CHECK_EQUAL(0, class0_instances);
{ {
auto p1 = make_counted<class0>(); auto p1 = make_counted<class0>();
p1 = new class1; p1 = new class1;
CPPA_CHECK_EQUAL(class0_instances, 1); CPPA_CHECK_EQUAL(1, class0_instances);
CPPA_CHECK_EQUAL(class1_instances, 1); CPPA_CHECK_EQUAL(1, class1_instances);
auto p2 = make_counted<class1>(); auto p2 = make_counted<class1>();
p1 = p2; p1 = p2;
CPPA_CHECK_EQUAL(class0_instances, 1); CPPA_CHECK_EQUAL(1, class0_instances);
CPPA_CHECK_EQUAL(class1_instances, 1); CPPA_CHECK_EQUAL(1, class1_instances);
CPPA_CHECK(p1 == p2); CPPA_CHECK(p1 == p2);
} }
CPPA_CHECK_EQUAL(class0_instances, 0); CPPA_CHECK_EQUAL(0, class0_instances);
CPPA_CHECK_EQUAL(class1_instances, 0); CPPA_CHECK_EQUAL(0, class1_instances);
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -38,15 +38,15 @@ int main() { ...@@ -38,15 +38,15 @@ int main() {
int result = 0; int result = 0;
do_receive ( do_receive (
on<int>() >> [&](int value) { on<int>() >> [&](int value) {
CPPA_CHECK(value == 2); CPPA_CHECK_EQUAL(2, value);
result += value; result += value;
}, },
after(std::chrono::seconds(2)) >> [&]() { after(std::chrono::seconds(2)) >> [&]() {
CPPA_CHECK(false); CPPA_UNEXPECTED_TOUT();
result = 10; result = 10;
} }
) )
.until(gref(result) == 10); .until(gref(result) == 10);
await_all_others_done(); await_all_others_done();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -293,22 +293,6 @@ int main() { ...@@ -293,22 +293,6 @@ int main() {
CPPA_CHECK_EQUAL("A", vec.front()); CPPA_CHECK_EQUAL("A", vec.front());
invoked = false; invoked = false;
/*
match(vec) (
others() >> [&](any_tuple& tup) {
if (detail::matches<string, string, string>(tup)) {
tup.get_as_mutable<string>(1) = "B";
}
else {
CPPA_ERROR("matches<string, string, string>(tup) == false");
}
invoked = true;
}
);
if (!invoked) { CPPA_ERROR("match({\"a\", \"b\", \"c\"}) failed"); }
CPPA_CHECK_EQUAL(vec[1], "B");
*/
vector<string> vec2{"a=0", "b=1", "c=2"}; vector<string> vec2{"a=0", "b=1", "c=2"};
auto c2 = split(vec2.back(), '='); auto c2 = split(vec2.back(), '=');
...@@ -318,44 +302,14 @@ int main() { ...@@ -318,44 +302,14 @@ int main() {
CPPA_CHECK_EQUAL(true, invoked); CPPA_CHECK_EQUAL(true, invoked);
invoked = false; invoked = false;
/*,
int pmatches = 0;
using std::placeholders::_1;
match_each(vec2.begin(), vec2.end(), std::bind(split, _1, '=')) (
on("a", val<string>) >> [&](const string& value) {
CPPA_CHECK_EQUAL("0", value);
CPPA_CHECK_EQUAL(0, pmatches);
++pmatches;
},
on("b", val<string>) >> [&](const string& value) {
CPPA_CHECK_EQUAL("1", value);
CPPA_CHECK_EQUAL(1, pmatches);
++pmatches;
},
on("c", val<string>) >> [&](const string& value) {
CPPA_CHECK_EQUAL("2", value);
CPPA_CHECK_EQUAL(2, pmatches);
++pmatches;
}
others() >> [](const any_tuple& value) {
cout << to_string(value) << endl;
}
);
CPPA_CHECK_EQUAL(3, pmatches);
*/
// let's get the awesomeness started // let's get the awesomeness started
bool success = false;
istringstream iss("hello world"); istringstream iss("hello world");
match_stream<string>(iss) ( success = match_stream<string>(iss) (
on("hello", "world") >> [] { on("hello", "world") >> CPPA_CHECKPOINT_CB()
cout << "yeeeeeehaaaaaaa!!!!!" << endl;
},
on_arg_match >> [](const string& s1, const string& s2, const std::string& s3) {
cout << "you said: " << s1 << " " << s2 << " " << s3 << endl;
cout << "mind sayin 'hello world'?" << endl;
}
); );
CPPA_CHECK_EQUAL(true, success);
auto extract_name = [](const string& kvp) -> option<string> { auto extract_name = [](const string& kvp) -> option<string> {
auto vec = split(kvp, '='); auto vec = split(kvp, '=');
...@@ -369,27 +323,25 @@ int main() { ...@@ -369,27 +323,25 @@ int main() {
const char* svec[] = {"-n", "foo", "--name=bar", "-p", "2"}; const char* svec[] = {"-n", "foo", "--name=bar", "-p", "2"};
bool success = match_stream<string>(begin(svec), end(svec)) ( success = match_stream<string>(begin(svec), end(svec)) (
(on("-n", arg_match) || on(extract_name)) >> [](const string& name) { (on("-n", arg_match) || on(extract_name)) >> [](const string& name) -> bool {
cout << "your name is " << name << endl; CPPA_CHECK(name == "foo" || name == "bar");
return name == "foo" || name == "bar";
}, },
on("-p", arg_match) >> [&](const string& port) -> bool { on("-p", arg_match) >> [&](const string& port) -> bool {
auto i = toint(port); auto i = toint(port);
if (i) { if (i) {
cout << "port = " << *i << endl; CPPA_CHECK_EQUAL(2, *i);
return true; return true;
} }
else { else return false;
cout << "'" << port << "' is not a valid port" << endl;
return false;
}
}, },
on_arg_match >> [](const string& arg) { on_arg_match >> [](const string& arg) -> bool{
cout << "dunno whatya wanna say me: " << arg << endl; CPPA_ERROR("unexpected string: " << arg);
return false;
} }
); );
CPPA_CHECK_EQUAL(true, success);
cout << "success: " << success << endl;
cout << "check combined partial function matching" << endl; cout << "check combined partial function matching" << endl;
...@@ -416,5 +368,5 @@ int main() { ...@@ -416,5 +368,5 @@ int main() {
check(pf0, make_any_tuple("hi"), ""); check(pf0, make_any_tuple("hi"), "");
check(pf1, make_any_tuple("hi"), "<string>@4"); check(pf1, make_any_tuple("hi"), "<string>@4");
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
#include <string>
#include <cstdint>
#include <typeinfo>
#include <type_traits>
#include "test.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/element_at.hpp"
#include "cppa/detail/demangle.hpp"
using std::cout;
using std::endl;
using std::is_same;
using namespace cppa;
using namespace cppa::util;
int main() {
CPPA_TEST(test__metaprogramming);
cout << "test type_list" << endl;
typedef type_list<int,float,std::string> l1;
typedef typename tl_reverse<l1>::type r1;
CPPA_CHECK((is_same<int,element_at<0,l1>::type>::value));
CPPA_CHECK((is_same<float,element_at<1,l1>::type>::value));
CPPA_CHECK((is_same<std::string,element_at<2,l1>::type>::value));
CPPA_CHECK_EQUAL(3 ,tl_size<l1>::value);
CPPA_CHECK_EQUAL(tl_size<l1>::value, tl_size<r1>::value);
CPPA_CHECK((is_same<element_at<0,l1>::type,element_at<2,r1>::type>::value));
CPPA_CHECK((is_same<element_at<1,l1>::type,element_at<1,r1>::type>::value));
CPPA_CHECK((is_same<element_at<2,l1>::type,element_at<0,r1>::type>::value));
typedef tl_concat<type_list<int>,l1>::type l2;
CPPA_CHECK((is_same<int,tl_head<l2>::type>::value));
CPPA_CHECK((is_same<l1,tl_tail<l2>::type>::value));
cout << "test int_list" << endl;
typedef int_list<0,1,2,3,4,5> il0;
typedef int_list<4,5> il1;
typedef typename il_right<il0,2>::type il2;
CPPA_CHECK_VERBOSE((is_same<il2,il1>::value),
"il_right<il0,2> returned " <<detail::demangle<il2>()
<< "expected: " << detail::demangle<il1>());
return CPPA_TEST_RESULT();
}
...@@ -8,13 +8,9 @@ struct streamer { ...@@ -8,13 +8,9 @@ struct streamer {
std::ostream& o; std::ostream& o;
streamer(std::ostream& mo) : o(mo) { } streamer(std::ostream& mo) : o(mo) { }
template<typename T> template<typename T>
void operator()(const T& value) { void operator()(const T& value) { o << value; }
o << value; void operator()(const std::u16string&) { }
} void operator()(const std::u32string&) { }
void operator()(const std::u16string&) {
}
void operator()(const std::u32string&) {
}
}; };
} // namespace <anonymous> } // namespace <anonymous>
...@@ -37,8 +33,8 @@ int main() { ...@@ -37,8 +33,8 @@ int main() {
primitive_variant v1(forty_two); primitive_variant v1(forty_two);
primitive_variant v2(pt_uint32); primitive_variant v2(pt_uint32);
// type checking // type checking
CPPA_CHECK_EQUAL(v1.ptype(), pt_uint32); CPPA_CHECK_EQUAL(pt_uint32, v1.ptype());
CPPA_CHECK_EQUAL(v2.ptype(), pt_uint32); CPPA_CHECK_EQUAL(pt_uint32, v2.ptype());
get_ref<std::uint32_t&>(v2) = forty_two; get_ref<std::uint32_t&>(v2) = forty_two;
CPPA_CHECK(equal(v1, v2)); CPPA_CHECK(equal(v1, v2));
CPPA_CHECK(equal(v1, forty_two)); CPPA_CHECK(equal(v1, forty_two));
...@@ -46,13 +42,13 @@ int main() { ...@@ -46,13 +42,13 @@ int main() {
// type mismatch => unequal // type mismatch => unequal
CPPA_CHECK(!equal(v2, static_cast<std::int8_t>(forty_two))); CPPA_CHECK(!equal(v2, static_cast<std::int8_t>(forty_two)));
v1 = "Hello world"; v1 = "Hello world";
CPPA_CHECK_EQUAL(v1.ptype(), pt_u8string); CPPA_CHECK_EQUAL(pt_u8string, v1.ptype());
v2 = "Hello"; v2 = "Hello";
CPPA_CHECK_EQUAL(v2.ptype(), pt_u8string); CPPA_CHECK_EQUAL(pt_u8string, v2.ptype());
get_ref<std::string>(v2) += " world"; get_ref<std::string>(v2) += " world";
CPPA_CHECK(equal(v1, v2)); CPPA_CHECK(equal(v1, v2));
v2 = u"Hello World"; v2 = u"Hello World";
CPPA_CHECK(!equal(v1, v2)); CPPA_CHECK(!equal(v1, v2));
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -15,6 +15,8 @@ using namespace cppa; ...@@ -15,6 +15,8 @@ using namespace cppa;
namespace { namespace {
typedef std::pair<std::string, std::string> string_pair;
typedef vector<actor_ptr> actor_vector; typedef vector<actor_ptr> actor_vector;
vector<string_pair> get_kv_pairs(int argc, char** argv, int begin = 1) { vector<string_pair> get_kv_pairs(int argc, char** argv, int begin = 1) {
...@@ -218,7 +220,7 @@ int client_part(const vector<string_pair>& args) { ...@@ -218,7 +220,7 @@ int client_part(const vector<string_pair>& args) {
send(server, atom("farewell")); send(server, atom("farewell"));
shutdown(); shutdown();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
} // namespace <anonymous> } // namespace <anonymous>
...@@ -356,5 +358,5 @@ int main(int argc, char** argv) { ...@@ -356,5 +358,5 @@ int main(int argc, char** argv) {
// wait until separate process (in sep. thread) finished execution // wait until separate process (in sep. thread) finished execution
if (run_remote_actor) child.join(); if (run_remote_actor) child.join();
shutdown(); shutdown();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -56,5 +56,5 @@ int main() { ...@@ -56,5 +56,5 @@ int main() {
str_hash("1234567890123456789012345678901234567890" str_hash("1234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890")); "1234567890123456789012345678901234567890"));
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -333,5 +333,5 @@ int main() { ...@@ -333,5 +333,5 @@ int main() {
// verify result of serialization / deserialization // verify result of serialization / deserialization
CPPA_CHECK(c1 == c2); CPPA_CHECK(c1 == c2);
} }
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
#define CPPA_VERBOSE_CHECK
#include <stack> #include <stack>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
...@@ -300,67 +298,67 @@ struct simple_mirror : sb_actor<simple_mirror> { ...@@ -300,67 +298,67 @@ struct simple_mirror : sb_actor<simple_mirror> {
int main() { int main() {
CPPA_TEST(test__spawn); CPPA_TEST(test__spawn);
CPPA_IF_VERBOSE(cout << "test send() ... " << flush); cout << "test send() ... " << flush;
send(self, 1, 2, 3, true); send(self, 1, 2, 3, true);
receive(on(1, 2, 3, true) >> []() { }); receive(on(1, 2, 3, true) >> []() { });
CPPA_IF_VERBOSE(cout << "... with empty message... " << flush); cout << "... with empty message... " << flush;
self << any_tuple{}; self << any_tuple{};
receive(on() >> []() { }); receive(on() >> []() { });
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
self << any_tuple{}; self << any_tuple{};
receive(on() >> []() { }); receive(on() >> []() { });
CPPA_IF_VERBOSE(cout << "test receive with zero timeout ... " << flush); cout << "test receive with zero timeout ... " << flush;
receive ( receive (
others() >> CPPA_UNEXPECTED_MSG_CB(), others() >> CPPA_UNEXPECTED_MSG_CB(),
after(chrono::seconds(0)) >> []() { after(chrono::seconds(0)) >> []() {
// mailbox empty // mailbox empty
} }
); );
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
auto mirror = spawn<simple_mirror>(); auto mirror = spawn<simple_mirror>();
CPPA_IF_VERBOSE(cout << "test mirror ... " << flush); cout << "test mirror ... " << flush;
send(mirror, "hello mirror"); send(mirror, "hello mirror");
receive(on("hello mirror") >> []() { }); receive(on("hello mirror") >> []() { });
send(mirror, atom("EXIT"), exit_reason::user_defined); send(mirror, atom("EXIT"), exit_reason::user_defined);
CPPA_IF_VERBOSE(cout << "await ... " << endl); cout << "await ... " << endl;
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test echo actor ... " << flush); cout << "test echo actor ... " << flush;
auto mecho = spawn(echo_actor); auto mecho = spawn(echo_actor);
send(mecho, "hello echo"); send(mecho, "hello echo");
receive ( receive (
on("hello echo") >> []() { }, on("hello echo") >> []() { },
others() >> CPPA_UNEXPECTED_MSG_CB() others() >> CPPA_UNEXPECTED_MSG_CB()
); );
CPPA_IF_VERBOSE(cout << "await ... " << endl); cout << "await ... " << endl;
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test delayed_send() ... " << flush); cout << "test delayed_send() ... " << flush;
delayed_send(self, chrono::seconds(1), 1, 2, 3); delayed_send(self, chrono::seconds(1), 1, 2, 3);
receive(on(1, 2, 3) >> []() { }); receive(on(1, 2, 3) >> []() { });
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test timeout ... " << flush); cout << "test timeout ... " << flush;
receive(after(chrono::seconds(1)) >> []() { }); receive(after(chrono::seconds(1)) >> []() { });
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "testee1 ... " << flush); cout << "testee1 ... " << flush;
spawn(testee1); spawn(testee1);
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "event_testee2 ... " << flush); cout << "event_testee2 ... " << flush;
spawn_event_testee2(); spawn_event_testee2();
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "chopstick ... " << flush); cout << "chopstick ... " << flush;
auto cstk = spawn<chopstick>(); auto cstk = spawn<chopstick>();
send(cstk, atom("take"), self); send(cstk, atom("take"), self);
receive ( receive (
...@@ -370,9 +368,9 @@ int main() { ...@@ -370,9 +368,9 @@ int main() {
} }
); );
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test event-based factory ... " << flush); cout << "test event-based factory ... " << flush;
auto factory = factory::event_based([&](int* i, float*, string*) { auto factory = factory::event_based([&](int* i, float*, string*) {
self->become ( self->become (
on(atom("get_int")) >> [i]() { on(atom("get_int")) >> [i]() {
...@@ -402,9 +400,9 @@ int main() { ...@@ -402,9 +400,9 @@ int main() {
} }
); );
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test fixed_stack ... " << flush); cout << "test fixed_stack ... " << flush;
auto st = spawn<fixed_stack>(10); auto st = spawn<fixed_stack>(10);
// push 20 values // push 20 values
for (int i = 0; i < 20; ++i) send(st, atom("push"), i); for (int i = 0; i < 20; ++i) send(st, atom("push"), i);
...@@ -433,9 +431,9 @@ int main() { ...@@ -433,9 +431,9 @@ int main() {
// terminate st // terminate st
send(st, atom("EXIT"), exit_reason::user_defined); send(st, atom("EXIT"), exit_reason::user_defined);
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test sync send/receive ... " << flush); cout << "test sync send/receive ... " << flush;
auto sync_testee1 = spawn([]() { auto sync_testee1 = spawn([]() {
receive ( receive (
on(atom("get")) >> []() { on(atom("get")) >> []() {
...@@ -472,9 +470,9 @@ int main() { ...@@ -472,9 +470,9 @@ int main() {
after(chrono::seconds(0)) >> []() { } after(chrono::seconds(0)) >> []() { }
); );
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
CPPA_IF_VERBOSE(cout << "test sync send with factory spawned actor ... " << flush); cout << "test sync send with factory spawned actor ... " << flush;
auto sync_testee_factory = factory::event_based( auto sync_testee_factory = factory::event_based(
[&]() { [&]() {
self->become ( self->become (
...@@ -521,7 +519,7 @@ int main() { ...@@ -521,7 +519,7 @@ int main() {
} }
); );
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); cout << "ok" << endl;
sync_send(sync_testee, "!?").await( sync_send(sync_testee, "!?").await(
on(atom("EXITED"), any_vals) >> CPPA_CHECKPOINT_CB(), on(atom("EXITED"), any_vals) >> CPPA_CHECKPOINT_CB(),
...@@ -583,13 +581,8 @@ int main() { ...@@ -583,13 +581,8 @@ int main() {
int zombie_init_called = 0; int zombie_init_called = 0;
int zombie_on_exit_called = 0; int zombie_on_exit_called = 0;
factory::event_based([&]() { factory::event_based([&]() { ++zombie_init_called; },
++zombie_init_called; [&]() { ++zombie_on_exit_called; }).spawn();
},
[&]() {
++zombie_on_exit_called;
})
.spawn();
CPPA_CHECK_EQUAL(1, zombie_init_called); CPPA_CHECK_EQUAL(1, zombie_init_called);
CPPA_CHECK_EQUAL(1, zombie_on_exit_called); CPPA_CHECK_EQUAL(1, zombie_on_exit_called);
factory::event_based([&](int* i) { factory::event_based([&](int* i) {
...@@ -709,5 +702,5 @@ int main() { ...@@ -709,5 +702,5 @@ int main() {
CPPA_CHECK_EQUAL(0x0F, flags); CPPA_CHECK_EQUAL(0x0F, flags);
// verify pong messages // verify pong messages
CPPA_CHECK_EQUAL(10, pongs()); CPPA_CHECK_EQUAL(10, pongs());
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -147,5 +147,5 @@ int main() { ...@@ -147,5 +147,5 @@ int main() {
after(std::chrono::seconds(0)) >> CPPA_CHECKPOINT_CB() after(std::chrono::seconds(0)) >> CPPA_CHECKPOINT_CB()
); );
shutdown(); shutdown();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -403,5 +403,5 @@ int main() { ...@@ -403,5 +403,5 @@ int main() {
CPPA_CHECK_EQUAL(s_expensive_copies, (size_t) 0); CPPA_CHECK_EQUAL(s_expensive_copies, (size_t) 0);
await_all_others_done(); await_all_others_done();
shutdown(); shutdown();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -182,5 +182,5 @@ int main() { ...@@ -182,5 +182,5 @@ int main() {
CPPA_CHECK(arr3[1] == uniform_type_info::from("@u16")); CPPA_CHECK(arr3[1] == uniform_type_info::from("@u16"));
CPPA_CHECK(uniform_type_info::from("@u16") == uniform_typeid<std::uint16_t>()); CPPA_CHECK(uniform_type_info::from("@u16") == uniform_typeid<std::uint16_t>());
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
...@@ -57,5 +57,5 @@ int main() { ...@@ -57,5 +57,5 @@ int main() {
CPPA_CHECK_EQUAL(10, worker.m_count); CPPA_CHECK_EQUAL(10, worker.m_count);
CPPA_CHECK_EQUAL(12, i); CPPA_CHECK_EQUAL(12, i);
# endif # endif
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT();
} }
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