Commit 58318857 authored by neverlord's avatar neverlord

match() and match_each()

parent a7c57cea
...@@ -74,7 +74,6 @@ nobase_library_include_HEADERS = \ ...@@ -74,7 +74,6 @@ nobase_library_include_HEADERS = \
cppa/actor_proxy.hpp \ cppa/actor_proxy.hpp \
cppa/announce.hpp \ cppa/announce.hpp \
cppa/any_tuple.hpp \ cppa/any_tuple.hpp \
cppa/any_tuple_view.hpp \
cppa/anything.hpp \ cppa/anything.hpp \
cppa/atom.hpp \ cppa/atom.hpp \
cppa/attachable.hpp \ cppa/attachable.hpp \
...@@ -96,6 +95,7 @@ nobase_library_include_HEADERS = \ ...@@ -96,6 +95,7 @@ nobase_library_include_HEADERS = \
cppa/detail/boxed.hpp \ cppa/detail/boxed.hpp \
cppa/detail/buffer.hpp \ cppa/detail/buffer.hpp \
cppa/detail/channel.hpp \ cppa/detail/channel.hpp \
cppa/detail/container_tuple_view.hpp \
cppa/detail/converted_thread_context.hpp \ cppa/detail/converted_thread_context.hpp \
cppa/detail/decorated_tuple.hpp \ cppa/detail/decorated_tuple.hpp \
cppa/detail/default_uniform_type_info_impl.hpp \ cppa/detail/default_uniform_type_info_impl.hpp \
...@@ -111,6 +111,7 @@ nobase_library_include_HEADERS = \ ...@@ -111,6 +111,7 @@ nobase_library_include_HEADERS = \
cppa/detail/list_member.hpp \ cppa/detail/list_member.hpp \
cppa/detail/mailman.hpp \ cppa/detail/mailman.hpp \
cppa/detail/map_member.hpp \ cppa/detail/map_member.hpp \
cppa/detail/matches.hpp \
cppa/detail/mock_scheduler.hpp \ cppa/detail/mock_scheduler.hpp \
cppa/detail/native_socket.hpp \ cppa/detail/native_socket.hpp \
cppa/detail/network_manager.hpp \ cppa/detail/network_manager.hpp \
...@@ -132,6 +133,7 @@ nobase_library_include_HEADERS = \ ...@@ -132,6 +133,7 @@ nobase_library_include_HEADERS = \
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_vals.hpp \ cppa/detail/tuple_vals.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 \
...@@ -172,7 +174,6 @@ nobase_library_include_HEADERS = \ ...@@ -172,7 +174,6 @@ nobase_library_include_HEADERS = \
cppa/to_string.hpp \ cppa/to_string.hpp \
cppa/tuple.hpp \ cppa/tuple.hpp \
cppa/tuple_cast.hpp \ cppa/tuple_cast.hpp \
cppa/tuple_view.hpp \
cppa/type_value_pair.hpp \ cppa/type_value_pair.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 \
......
...@@ -11,7 +11,6 @@ src/uniform_type_info.cpp ...@@ -11,7 +11,6 @@ src/uniform_type_info.cpp
cppa/config.hpp cppa/config.hpp
unit_testing/test__tuple.cpp unit_testing/test__tuple.cpp
cppa/detail/abstract_tuple.hpp cppa/detail/abstract_tuple.hpp
cppa/tuple_view.hpp
cppa/detail/tuple_vals.hpp cppa/detail/tuple_vals.hpp
cppa/detail/decorated_tuple.hpp cppa/detail/decorated_tuple.hpp
cppa/cow_ptr.hpp cppa/cow_ptr.hpp
...@@ -234,7 +233,6 @@ cppa/tuple_cast.hpp ...@@ -234,7 +233,6 @@ cppa/tuple_cast.hpp
cppa/util/is_mutable_ref.hpp cppa/util/is_mutable_ref.hpp
cppa/util/is_manipulator.hpp cppa/util/is_manipulator.hpp
cppa/util/apply_tuple.hpp cppa/util/apply_tuple.hpp
cppa/any_tuple_view.hpp
benchmarks/Matching.scala benchmarks/Matching.scala
benchmarks/matching.cpp benchmarks/matching.cpp
benchmarks/matching.erl benchmarks/matching.erl
...@@ -256,3 +254,7 @@ cppa/intrusive/forward_iterator.hpp ...@@ -256,3 +254,7 @@ cppa/intrusive/forward_iterator.hpp
unit_testing/test__intrusive_containers.cpp unit_testing/test__intrusive_containers.cpp
examples/dancing_kirby.cpp examples/dancing_kirby.cpp
cppa/util/is_comparable.hpp cppa/util/is_comparable.hpp
cppa/detail/tuple_view.hpp
cppa/detail/container_tuple_view.hpp
cppa/detail/matches.hpp
unit_testing/test__match.cpp
...@@ -34,7 +34,16 @@ ...@@ -34,7 +34,16 @@
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp" #include "cppa/cow_ptr.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/is_iterable.hpp"
#include "cppa/detail/tuple_view.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/container_tuple_view.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa { namespace cppa {
...@@ -149,19 +158,99 @@ class any_tuple ...@@ -149,19 +158,99 @@ class any_tuple
return m_vals->impl_type(); return m_vals->impl_type();
} }
template<typename T>
static inline any_tuple view(T&& value,
typename util::enable_if<util::is_iterable<typename util::rm_ref<T>::type> >::type* = 0)
{
static constexpr bool can_optimize = std::is_reference<T>::value
&& !std::is_const<T>::value;
std::integral_constant<bool, can_optimize> token;
return any_tuple{container_view(std::forward<T>(value), token)};
}
template<typename T>
static inline any_tuple view(T&& value,
typename util::disable_if<util::is_iterable<typename util::rm_ref<T>::type> >::type* = 0)
{
typedef typename util::rm_ref<T>::type vtype;
typedef typename detail::implicit_conversions<vtype>::type converted;
static_assert(util::is_legal_tuple_type<converted>::value,
"T is not a valid tuple type");
static constexpr bool can_optimize =
std::is_same<converted, vtype>::value
&& std::is_reference<T>::value
&& !std::is_const<T>::value;
std::integral_constant<bool, can_optimize> token;
return any_tuple{simple_view(std::forward<T>(value), token)};
}
private: private:
cow_ptr<detail::abstract_tuple> m_vals; cow_ptr<detail::abstract_tuple> m_vals;
explicit any_tuple(cow_ptr<detail::abstract_tuple> const& vals); explicit any_tuple(cow_ptr<detail::abstract_tuple> const& vals);
typedef detail::abstract_tuple* tup_ptr;
template<typename T>
static inline tup_ptr simple_view(T& value,
std::integral_constant<bool, true>)
{
return new detail::tuple_view<T>(&value);
}
template<typename First, typename Second>
static inline tup_ptr simple_view(std::pair<First, Second>& p,
std::integral_constant<bool, true>)
{
return new detail::tuple_view<First, Second>(&p.first, &p.second);
}
template<typename T>
static inline tup_ptr simple_view(T&& value,
std::integral_constant<bool, false>)
{
typedef typename util::rm_ref<T>::type vtype;
typedef typename detail::implicit_conversions<vtype>::type converted;
return new detail::tuple_vals<converted>(std::forward<T>(value));
}
template<typename First, typename Second>
static inline any_tuple view(std::pair<First, Second> p,
std::integral_constant<bool, false>)
{
return new detail::tuple_vals<First, Second>(std::move(p.first),
std::move(p.second));
}
template<typename T>
static inline detail::abstract_tuple* container_view(T& value,
std::integral_constant<bool, true>)
{
return new detail::container_tuple_view<T>(&value);
}
template<typename T>
static inline detail::abstract_tuple* container_view(T&& value,
std::integral_constant<bool, false>)
{
typedef typename util::rm_ref<T>::type ctype;
return new detail::container_tuple_view<T>(new ctype(std::forward<T>(value)));
}
}; };
/**
* @relates any_tuple
*/
inline bool operator==(any_tuple const& lhs, any_tuple const& rhs) inline bool operator==(any_tuple const& lhs, any_tuple const& rhs)
{ {
return lhs.equals(rhs); return lhs.equals(rhs);
} }
/**
* @relates any_tuple
*/
inline bool operator!=(any_tuple const& lhs, any_tuple const& rhs) inline bool operator!=(any_tuple const& lhs, any_tuple const& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
......
...@@ -28,132 +28,78 @@ ...@@ -28,132 +28,78 @@
\******************************************************************************/ \******************************************************************************/
#ifndef ANY_TUPLE_VIEW_HPP #ifndef CONTAINER_TUPLE_VIEW_HPP
#define ANY_TUPLE_VIEW_HPP #define CONTAINER_TUPLE_VIEW_HPP
#include <set> #include "cppa/detail/tuple_vals.hpp"
#include <list>
#include <vector>
#include <utility>
#include <iterator>
#include <algorithm>
#include "cppa/tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/is_primitive.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp" #include "cppa/detail/object_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/disablable_delete.hpp"
namespace cppa { namespace cppa { namespace detail {
class any_tuple_view template<class Container>
class container_tuple_view : public abstract_tuple
{ {
typedef std::vector<type_value_pair> vector_type; public:
vector_type m_values; typedef typename Container::value_type value_type;
template<typename T> container_tuple_view(Container* c, bool take_ownership = false) : m_ptr(c)
void from_list(T const& list)
{ {
auto& arr = detail::static_types_array<typename T::value_type>::arr; CPPA_REQUIRE(c != nullptr);
for (auto i = list.begin(); i != list.end(); ++i) if (!take_ownership) m_ptr.get_deleter().disable();
{
m_values.push_back(std::make_pair(arr[0], &(*i)));
}
} }
public: size_t size() const
class const_iterator;
friend class const_iterator;
any_tuple_view(any_tuple_view&&) = default;
any_tuple_view(any_tuple_view const&) = default;
any_tuple_view& operator=(any_tuple_view&&) = default;
any_tuple_view& operator=(any_tuple_view const&) = default;
any_tuple_view(any_tuple& tup)
{ {
if (tup.size() > 0) return m_ptr->size();
{
// force tuple to detach
tup.mutable_at(0);
std::back_insert_iterator<vector_type> back_iter{m_values};
std::copy(tup.begin(), tup.end(), back_iter);
}
} }
template<typename... T> abstract_tuple* copy() const
any_tuple_view(tuple_view<T...> const& tup)
{ {
for (size_t i = 0; i < tup.size(); ++i) return new container_tuple_view{new Container(*m_ptr), true};
{
m_values.push_back(std::make_pair(tup.type_at(i), tup.at(i)));
}
} }
template<typename F, typename S> void const* at(size_t pos) const
any_tuple_view(std::pair<F, S> const& pair)
{ {
auto& arr = detail::static_types_array<F, S>::arr; CPPA_REQUIRE(pos < size());
m_values.push_back(std::make_pair(arr[0], &pair.first)); auto i = m_ptr->begin();
m_values.push_back(std::make_pair(arr[1], &pair.second)); std::advance(i, pos);
return &(*i);
} }
template<typename T> void* mutable_at(size_t pos)
any_tuple_view(std::set<T>& vec) { from_list(vec); }
template<typename T>
any_tuple_view(std::list<T>& vec) { from_list(vec); }
template<typename T>
any_tuple_view(std::vector<T>& vec) { from_list(vec); }
template<typename T>
any_tuple_view(T& val,
typename util::enable_if<util::is_primitive<T> >::type* = 0)
{ {
auto& arr = detail::static_types_array<T>::arr; CPPA_REQUIRE(pos < size());
m_values.push_back(std::make_pair(arr[0], &val)); auto i = m_ptr->begin();
std::advance(i, pos);
return &(*i);
} }
inline vector_type const& vals() const { return m_values; } uniform_type_info const* type_at(size_t pos) const
inline size_t size() const { return m_values.size(); }
inline void const* at(size_t p) const { return m_values[p].second; }
void* mutable_at(size_t p) { return const_cast<void*>(m_values[p].second); }
inline uniform_type_info const* type_at(size_t p) const
{ {
return m_values[p].first; CPPA_REQUIRE(pos < size());
return static_types_array<value_type>::arr[0];
} }
inline bool empty() const { return m_values.empty(); } void const* type_token() const
template<typename T>
inline T const& get_as(size_t p) const
{ {
return *reinterpret_cast<T const*>(at(p)); return &(typeid(Container));
} }
inline std::type_info const& impl_type() const std::type_info const* impl_type() const
{ {
// this is a lie, but the pattern matching implementation return &(typeid(detail::object_array));
// needs to do a full runtime check of each element
return typeid(detail::object_array);
} }
private:
std::unique_ptr<Container, disablable_delete<Container> > m_ptr;
}; };
} // namespace cppa } } // namespace cppa::detail
#endif // ANY_TUPLE_VIEW_HPP #endif // CONTAINER_TUPLE_VIEW_HPP
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include "cppa/match.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/tuple_cast.hpp" #include "cppa/tuple_cast.hpp"
...@@ -45,6 +44,7 @@ ...@@ -45,6 +44,7 @@
#include "cppa/util/fixed_vector.hpp" #include "cppa/util/fixed_vector.hpp"
#include "cppa/util/callable_trait.hpp" #include "cppa/util/callable_trait.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
// forward declaration // forward declaration
...@@ -90,11 +90,11 @@ struct abstract_invokable : public invokable ...@@ -90,11 +90,11 @@ struct abstract_invokable : public invokable
} }
bool types_match(any_tuple const& value) const bool types_match(any_tuple const& value) const
{ {
return match_types(value, m_pattern); return matches_types(value, m_pattern);
} }
bool could_invoke(any_tuple const& value) const bool could_invoke(any_tuple const& value) const
{ {
return match(value, m_pattern); return matches(value, m_pattern);
} }
}; };
...@@ -218,9 +218,9 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T ...@@ -218,9 +218,9 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
: super(std::forward<Args>(args)...), m_iimpl(std::forward<F>(fun)) : super(std::forward<Args>(args)...), m_iimpl(std::forward<F>(fun))
{ {
} }
bool invoke(any_tuple const& data) const bool invoke(any_tuple const& value) const
{ {
return match(data, this->m_pattern) ? m_iimpl() : false; return matches(value, this->m_pattern) ? m_iimpl() : false;
} }
bool unsafe_invoke(any_tuple const& value) const bool unsafe_invoke(any_tuple const& value) const
{ {
...@@ -228,7 +228,7 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T ...@@ -228,7 +228,7 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
} }
intermediate* get_intermediate(any_tuple const& value) intermediate* get_intermediate(any_tuple const& value)
{ {
return match(value, this->m_pattern) ? &m_iimpl : nullptr; return matches(value, this->m_pattern) ? &m_iimpl : nullptr;
} }
intermediate* get_unsafe_intermediate(any_tuple const& value) intermediate* get_unsafe_intermediate(any_tuple const& value)
{ {
......
This diff is collapsed.
...@@ -50,6 +50,18 @@ uniform_type_info const* uniform_typeid(std::type_info const&); ...@@ -50,6 +50,18 @@ uniform_type_info const* uniform_typeid(std::type_info const&);
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename T>
inline void* ptr_to(T& what) { return &what; }
template<typename T>
inline void const* ptr_to(T const& what) { return &what; }
template<typename T>
inline void* ptr_to(T* what) { return what; }
template<typename T>
inline void const* ptr_to(T const* what) { return what; }
/* /*
* "enhanced std::tuple" * "enhanced std::tuple"
*/ */
...@@ -153,7 +165,7 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -153,7 +165,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
inline void const* at(size_t p) const inline void const* at(size_t p) const
{ {
return (p == 0) ? &head : super::at(p-1); return (p == 0) ? ptr_to(head) : super::at(p-1);
} }
inline uniform_type_info const* type_at(size_t p) const inline uniform_type_info const* type_at(size_t p) const
...@@ -215,7 +227,7 @@ struct tdata<option<Head>, Tail...> : tdata<Tail...> ...@@ -215,7 +227,7 @@ struct tdata<option<Head>, Tail...> : tdata<Tail...>
inline void const* at(size_t p) const inline void const* at(size_t p) const
{ {
return (p == 0) ? &head : super::at(p-1); return (p == 0) ? ptr_to(head) : super::at(p-1);
} }
inline uniform_type_info const* type_at(size_t p) const inline uniform_type_info const* type_at(size_t p) const
......
...@@ -31,10 +31,11 @@ ...@@ -31,10 +31,11 @@
#ifndef TUPLE_CAST_IMPL_HPP #ifndef TUPLE_CAST_IMPL_HPP
#define TUPLE_CAST_IMPL_HPP #define TUPLE_CAST_IMPL_HPP
#include "cppa/match.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/type_value_pair.hpp" #include "cppa/type_value_pair.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_vals.hpp" #include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp" #include "cppa/detail/object_array.hpp"
...@@ -60,22 +61,19 @@ struct tuple_cast_impl ...@@ -60,22 +61,19 @@ struct tuple_cast_impl
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;
template<class Tuple> static inline option<Result> safe(any_tuple const& tup)
static inline option<Result> safe(Tuple const& tup)
{ {
mapping_vector mv; mapping_vector mv;
if (match<T...>(tup, mv)) return {Result::from(tup.vals(), mv)}; if (matches<T...>(tup, mv)) return {Result::from(tup.vals(), mv)};
return {}; return {};
} }
template<class Tuple> static inline option<Result> safe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> safe(Tuple const& tup, pattern<T...> const& p)
{ {
mapping_vector mv; mapping_vector mv;
if (match(tup, p, mv)) return {Result::from(tup.vals(), mv)}; if (matches(tup, p, mv)) return {Result::from(tup.vals(), mv)};
return {}; return {};
} }
template<class Tuple> static inline option<Result> unsafe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> unsafe(Tuple const& tup, pattern<T...> const& p)
{ {
mapping_vector mv; mapping_vector mv;
if (WP == wildcard_position::in_between) if (WP == wildcard_position::in_between)
...@@ -94,12 +92,11 @@ struct tuple_cast_impl ...@@ -94,12 +92,11 @@ struct tuple_cast_impl
} }
else else
{ {
if (match(tup, p, mv)) return {Result::from(tup.vals(), mv)}; if (matches(tup, p, mv)) return {Result::from(tup.vals(), mv)};
} }
return {}; return {};
} }
template<class Tuple> static inline Result force(any_tuple const& tup, pattern<T...> const& p)
static inline Result force(Tuple const& tup, pattern<T...> const& p)
{ {
mapping_vector mv; mapping_vector mv;
if (WP == wildcard_position::in_between) if (WP == wildcard_position::in_between)
...@@ -115,7 +112,7 @@ struct tuple_cast_impl ...@@ -115,7 +112,7 @@ struct tuple_cast_impl
} }
else else
{ {
match(tup, p, mv); matches(tup, p, mv);
return {Result::from(tup.vals(), mv)}; return {Result::from(tup.vals(), mv)};
} }
} }
...@@ -124,20 +121,17 @@ struct tuple_cast_impl ...@@ -124,20 +121,17 @@ struct tuple_cast_impl
template<class Result, typename... T> template<class Result, typename... T>
struct tuple_cast_impl<wildcard_position::nil, Result, T...> struct tuple_cast_impl<wildcard_position::nil, Result, T...>
{ {
template<class Tuple> static inline option<Result> safe(any_tuple const& tup)
static inline option<Result> safe(Tuple const& tup)
{ {
if (match<T...>(tup)) return {Result::from(tup.vals())}; if (matches<T...>(tup)) return {Result::from(tup.vals())};
return {}; return {};
} }
template<class Tuple> static inline option<Result> safe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> safe(Tuple const& tup, pattern<T...> const& p)
{ {
if (match(tup, p)) return {Result::from(tup.vals())}; if (matches(tup, p)) return {Result::from(tup.vals())};
return {}; return {};
} }
template<class Tuple> static inline option<Result> unsafe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> unsafe(Tuple const& 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, T...>::vmatch(tup, p))
...@@ -146,8 +140,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...> ...@@ -146,8 +140,7 @@ struct tuple_cast_impl<wildcard_position::nil, Result, T...>
} }
return {}; return {};
} }
template<class Tuple> static inline Result force(any_tuple const& tup, pattern<T...> const&)
static inline Result force(Tuple const& tup, pattern<T...> const&)
{ {
return {Result::from(tup.vals())}; return {Result::from(tup.vals())};
} }
...@@ -157,8 +150,7 @@ template<class Result, typename... T> ...@@ -157,8 +150,7 @@ template<class Result, typename... T>
struct tuple_cast_impl<wildcard_position::trailing, Result, T...> struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
: tuple_cast_impl<wildcard_position::nil, Result, T...> : tuple_cast_impl<wildcard_position::nil, Result, T...>
{ {
template<class Tuple> static inline option<Result> unsafe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> unsafe(Tuple const& 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, T...>::vmatch(tup, p))
...@@ -167,8 +159,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...> ...@@ -167,8 +159,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
} }
return {}; return {};
} }
template<class Tuple> static inline Result force(any_tuple const& tup, pattern<T...> const&)
static inline Result force(Tuple const& tup, pattern<T...> const&)
{ {
return {Result::from(tup.vals())}; return {Result::from(tup.vals())};
} }
...@@ -177,22 +168,19 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...> ...@@ -177,22 +168,19 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
template<class Result, typename... T> template<class Result, typename... T>
struct tuple_cast_impl<wildcard_position::leading, Result, T...> struct tuple_cast_impl<wildcard_position::leading, Result, T...>
{ {
template<class Tuple> static inline option<Result> safe(any_tuple const& tup)
static inline option<Result> safe(Tuple const& tup)
{ {
size_t o = tup.size() - (sizeof...(T) - 1); size_t o = tup.size() - (sizeof...(T) - 1);
if (match<T...>(tup)) return {Result::offset_subtuple(tup.vals(), o)}; if (matches<T...>(tup)) return {Result::offset_subtuple(tup.vals(), o)};
return {}; return {};
} }
template<class Tuple> static inline option<Result> safe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> safe(Tuple const& tup, pattern<T...> const& p)
{ {
size_t o = tup.size() - (sizeof...(T) - 1); size_t o = tup.size() - (sizeof...(T) - 1);
if (match(tup, p)) return {Result::offset_subtuple(tup.vals(), o)}; if (matches(tup, p)) return {Result::offset_subtuple(tup.vals(), o)};
return {}; return {};
} }
template<class Tuple> static inline option<Result> unsafe(any_tuple const& tup, pattern<T...> const& p)
static inline option<Result> unsafe(Tuple const& 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, T...>::vmatch(tup, p))
...@@ -202,8 +190,7 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...> ...@@ -202,8 +190,7 @@ struct tuple_cast_impl<wildcard_position::leading, Result, T...>
} }
return {}; return {};
} }
template<class Tuple> static inline Result force(any_tuple const& tup, pattern<T...> const&)
static inline Result force(Tuple const& tup, pattern<T...> const&)
{ {
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);
......
...@@ -53,22 +53,23 @@ class tuple_vals : public abstract_tuple ...@@ -53,22 +53,23 @@ class tuple_vals : public abstract_tuple
typedef abstract_tuple super; typedef abstract_tuple super;
public:
typedef tdata<ElementTypes...> data_type; typedef tdata<ElementTypes...> data_type;
typedef types_array<ElementTypes...> element_types; typedef types_array<ElementTypes...> element_types;
data_type m_data;
static types_array<ElementTypes...> m_types;
public:
tuple_vals() : m_data() { } tuple_vals() : m_data() { }
tuple_vals(tuple_vals const& other) : super(), m_data(other.m_data) { } tuple_vals(tuple_vals const& other) : super(), m_data(other.m_data) { }
tuple_vals(ElementTypes const&... args) : m_data(args...) { } tuple_vals(ElementTypes const&... args) : m_data(args...) { }
inline data_type& data()
{
return m_data;
}
inline data_type const& data() const inline data_type const& data() const
{ {
return m_data; return m_data;
...@@ -92,6 +93,7 @@ class tuple_vals : public abstract_tuple ...@@ -92,6 +93,7 @@ class tuple_vals : public abstract_tuple
void* mutable_at(size_t pos) void* mutable_at(size_t pos)
{ {
CPPA_REQUIRE(pos < size());
return const_cast<void*>(at(pos)); return const_cast<void*>(at(pos));
} }
...@@ -122,6 +124,12 @@ class tuple_vals : public abstract_tuple ...@@ -122,6 +124,12 @@ class tuple_vals : public abstract_tuple
return detail::static_type_list<ElementTypes...>::list; return detail::static_type_list<ElementTypes...>::list;
} }
private:
data_type m_data;
static types_array<ElementTypes...> m_types;
}; };
template<typename... ElementTypes> template<typename... ElementTypes>
......
...@@ -31,156 +31,108 @@ ...@@ -31,156 +31,108 @@
#ifndef TUPLE_VIEW_HPP #ifndef TUPLE_VIEW_HPP
#define TUPLE_VIEW_HPP #define TUPLE_VIEW_HPP
#include <vector> #include "cppa/util/static_foreach.hpp"
#include <cstring>
#include "cppa/get.hpp" #include "cppa/detail/tuple_vals.hpp"
#include "cppa/tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/at.hpp" namespace cppa { namespace detail {
#include "cppa/util/type_list.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/detail/decorated_tuple.hpp" struct tuple_view_copy_helper
{
namespace cppa { size_t pos;
abstract_tuple* target;
template<size_t N, typename... Types> tuple_view_copy_helper(abstract_tuple* trgt) : pos(0), target(trgt) { }
typename util::at<N, Types...>::type& get_ref(tuple_view<Types...>& t); template<typename T>
void operator()(T const* value)
{
*(reinterpret_cast<T*>(target->mutable_at(pos++))) = *value;
}
};
/**
* @brief Describes a view of an fixed-length tuple.
*/
template<typename... ElementTypes> template<typename... ElementTypes>
class tuple_view class tuple_view : public abstract_tuple
{ {
template<size_t N, typename... Types> static_assert(sizeof...(ElementTypes) > 0,
friend typename util::at<N, Types...>::type& get_ref(tuple_view<Types...>&); "tuple_vals is not allowed to be empty");
void* m_data[sizeof...(ElementTypes)]; public:
tuple_view() { } typedef tdata<ElementTypes*...> data_type;
public: typedef types_array<ElementTypes...> element_types;
static constexpr size_t num_elements = sizeof...(ElementTypes); tuple_view() = delete;
tuple_view(tuple_view const&) = delete;
typedef util::type_list<ElementTypes...> types; /**
* @warning @p tuple_view does @b NOT takes ownership for given pointers
*/
tuple_view(ElementTypes*... args) : m_data(args...) { }
static tuple_view from(std::vector<type_value_pair> const& vec) inline data_type& data()
{ {
tuple_view result; return m_data;
size_t j = 0;
for (type_value_pair const& tvp : vec)
{
result.m_data[j++] = const_cast<void*>(tvp.second);
}
return std::move(result);
} }
static tuple_view from(std::vector<type_value_pair> const& vec, inline data_type const& data() const
util::fixed_vector<size_t, sizeof...(ElementTypes)> const& mv)
{ {
tuple_view result; return m_data;
for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
{
result.m_data[i] = const_cast<void*>(vec[mv[i]].second);
}
return std::move(result);
} }
tuple_view& operator=(tuple_view const& other) size_t size() const
{ {
memcpy(m_data, other.m_data, num_elements * sizeof(void*)); return sizeof...(ElementTypes);
return *this;
} }
tuple_view(tuple_view const& other) abstract_tuple* copy() const
{ {
memcpy(m_data, other.m_data, num_elements * sizeof(void*)); auto result = new tuple_vals<ElementTypes...>;
tuple_view_copy_helper f{result};
util::static_foreach<0, sizeof...(ElementTypes)>::_(m_data, f);
return result;
} }
inline size_t size() const void const* at(size_t pos) const
{ {
return sizeof...(ElementTypes); CPPA_REQUIRE(pos < size());
return m_data.at(pos);
} }
inline void const* at(size_t p) const { return m_data[p]; } void* mutable_at(size_t pos)
{
inline void* mutable_at(size_t p) { return m_data[p]; } CPPA_REQUIRE(pos < size());
return const_cast<void*>(at(pos));
}; }
template<size_t N, typename... Types>
const typename util::at<N, Types...>::type& get(tuple_view<Types...> const& t)
{
static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::at<N, Types...>::type result_t;
return *reinterpret_cast<result_t const*>(t.at(N));
}
template<size_t N, typename... Types>
typename util::at<N, Types...>::type& get_ref(tuple_view<Types...>& t)
{
static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::at<N, Types...>::type result_t;
return *reinterpret_cast<result_t*>(t.mutable_at(N));
}
template<typename TypeList> uniform_type_info const* type_at(size_t pos) const
struct tuple_view_from_type_list; {
CPPA_REQUIRE(pos < size());
return m_types[pos];
}
template<typename... Types> void const* type_token() const
struct tuple_view_from_type_list<util::type_list<Types...>> {
{ return detail::static_type_list<ElementTypes...>::list;
typedef tuple_view<Types...> type; }
};
template<typename... LhsTypes, typename... RhsTypes> std::type_info const* impl_type() const
inline bool operator==(tuple_view<LhsTypes...> const& lhs, {
tuple_view<RhsTypes...> const& rhs) return detail::static_type_list<ElementTypes...>::list;
{ }
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes> private:
inline bool operator==(tuple<LhsTypes...> const& lhs,
tuple_view<RhsTypes...> const& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes> data_type m_data;
inline bool operator==(tuple_view<LhsTypes...> const& lhs,
tuple<RhsTypes...> const& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes> static types_array<ElementTypes...> m_types;
inline bool operator!=(tuple_view<LhsTypes...> const& lhs,
tuple_view<RhsTypes...> const& rhs)
{
return !(lhs == rhs);
}
template<typename... LhsTypes, typename... RhsTypes> };
inline bool operator!=(tuple<LhsTypes...> const& lhs,
tuple_view<RhsTypes...> const& rhs)
{
return !(lhs == rhs);
}
template<typename... LhsTypes, typename... RhsTypes> template<typename... ElementTypes>
inline bool operator!=(tuple_view<LhsTypes...> const& lhs, types_array<ElementTypes...> tuple_view<ElementTypes...>::m_types;
tuple<RhsTypes...> const& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa } } // namespace cppa::detail
#endif // TUPLE_VIEW_HPP #endif // TUPLE_VIEW_HPP
...@@ -44,9 +44,6 @@ namespace detail { template<typename...> class tdata; } ...@@ -44,9 +44,6 @@ namespace detail { template<typename...> class tdata; }
// forward declaration of tuple // forward declaration of tuple
template<typename...> class tuple; template<typename...> class tuple;
// forward declaration of tuple_view
template<typename...> class tuple_view;
// forward declaration of get(detail::tdata<...> const&) // forward declaration of get(detail::tdata<...> const&)
template<size_t N, typename... Tn> template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&); const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
...@@ -55,10 +52,6 @@ const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&); ...@@ -55,10 +52,6 @@ const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
template<size_t N, typename... Tn> template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(tuple<Tn...> const&); const typename util::at<N, Tn...>::type& get(tuple<Tn...> const&);
// forward declarations of get(tuple_view<...> const&)
template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(tuple_view<Tn...> const&);
// forward declarations of get_ref(detail::tdata<...>&) // forward declarations of get_ref(detail::tdata<...>&)
template<size_t N, typename... Tn> template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&); typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
...@@ -67,10 +60,6 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&); ...@@ -67,10 +60,6 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
template<size_t N, typename... Tn> template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(tuple<Tn...>&); typename util::at<N, Tn...>::type& get_ref(tuple<Tn...>&);
// forward declarations of get_ref(tuple_view<...>&)
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(tuple_view<Tn...>&);
} // namespace cppa } // namespace cppa
#endif // GET_HPP #endif // GET_HPP
This diff is collapsed.
...@@ -38,8 +38,6 @@ ...@@ -38,8 +38,6 @@
#include "cppa/option.hpp" #include "cppa/option.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/type_value_pair.hpp" #include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
......
...@@ -33,15 +33,17 @@ ...@@ -33,15 +33,17 @@
#include <type_traits> #include <type_traits>
#include "cppa/match.hpp"
#include "cppa/option.hpp" #include "cppa/option.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_cast_impl.hpp" #include "cppa/detail/tuple_cast_impl.hpp"
namespace cppa { namespace cppa {
// cast using a pattern /**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple const& tup, pattern<T...> const& p) auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
-> option< -> option<
...@@ -56,7 +58,9 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p) ...@@ -56,7 +58,9 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
return detail::tuple_cast_impl<impl, tuple_type, T...>::safe(tup, p); return detail::tuple_cast_impl<impl, tuple_type, T...>::safe(tup, p);
} }
// cast using types /**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple const& tup) auto tuple_cast(any_tuple const& tup)
-> option< -> option<
......
...@@ -105,12 +105,18 @@ class type_value_pair_const_iterator ...@@ -105,12 +105,18 @@ class type_value_pair_const_iterator
}; };
/**
* @relates type_value_pair_const_iterator
*/
inline bool operator==(type_value_pair_const_iterator const& lhs, inline bool operator==(type_value_pair_const_iterator const& lhs,
type_value_pair_const_iterator const& rhs) type_value_pair_const_iterator const& rhs)
{ {
return lhs.base() == rhs.base(); return lhs.base() == rhs.base();
} }
/**
* @relates type_value_pair_const_iterator
*/
inline bool operator!=(type_value_pair_const_iterator const& lhs, inline bool operator!=(type_value_pair_const_iterator const& lhs,
type_value_pair_const_iterator const& rhs) type_value_pair_const_iterator const& rhs)
{ {
......
...@@ -263,12 +263,18 @@ class uniform_type_info ...@@ -263,12 +263,18 @@ class uniform_type_info
}; };
/**
* @relates uniform_type_info
*/
template<typename T> template<typename T>
inline uniform_type_info const* uniform_typeid() inline uniform_type_info const* uniform_typeid()
{ {
return uniform_typeid(typeid(T)); return uniform_typeid(typeid(T));
} }
/**
* @relates uniform_type_info
*/
inline bool operator==(uniform_type_info const& lhs, inline bool operator==(uniform_type_info const& lhs,
uniform_type_info const& rhs) uniform_type_info const& rhs)
{ {
...@@ -277,27 +283,42 @@ inline bool operator==(uniform_type_info const& lhs, ...@@ -277,27 +283,42 @@ inline bool operator==(uniform_type_info const& lhs,
return &lhs == &rhs; return &lhs == &rhs;
} }
/**
* @relates uniform_type_info
*/
inline bool operator!=(uniform_type_info const& lhs, inline bool operator!=(uniform_type_info const& lhs,
uniform_type_info const& rhs) uniform_type_info const& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/**
* @relates uniform_type_info
*/
inline bool operator==(uniform_type_info const& lhs, std::type_info const& rhs) inline bool operator==(uniform_type_info const& lhs, std::type_info const& rhs)
{ {
return lhs.equals(rhs); return lhs.equals(rhs);
} }
/**
* @relates uniform_type_info
*/
inline bool operator!=(uniform_type_info const& lhs, std::type_info const& rhs) inline bool operator!=(uniform_type_info const& lhs, std::type_info const& rhs)
{ {
return !(lhs.equals(rhs)); return !(lhs.equals(rhs));
} }
/**
* @relates uniform_type_info
*/
inline bool operator==(std::type_info const& lhs, uniform_type_info const& rhs) inline bool operator==(std::type_info const& lhs, uniform_type_info const& rhs)
{ {
return rhs.equals(lhs); return rhs.equals(lhs);
} }
/**
* @relates uniform_type_info
*/
inline bool operator!=(std::type_info const& lhs, uniform_type_info const& rhs) inline bool operator!=(std::type_info const& lhs, uniform_type_info const& rhs)
{ {
return !(rhs.equals(lhs)); return !(rhs.equals(lhs));
......
...@@ -67,7 +67,7 @@ class is_iterable ...@@ -67,7 +67,7 @@ class is_iterable
public: public:
static constexpr bool value = util::is_primitive<T>::value == false static constexpr bool value = util::is_primitive<T>::value == false
&& std::is_same<bool, result_type>::value; && std::is_same<bool, result_type>::value;
}; };
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#ifndef STATIC_FOREACH_HPP #ifndef STATIC_FOREACH_HPP
#define STATIC_FOREACH_HPP #define STATIC_FOREACH_HPP
#include "cppa/get.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
/** /**
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include <algorithm> #include <algorithm>
#include "cppa/self.hpp" #include "cppa/self.hpp"
#include "cppa/match.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
#include "cppa/detail/converted_thread_context.hpp" #include "cppa/detail/converted_thread_context.hpp"
...@@ -111,7 +111,7 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/ ...@@ -111,7 +111,7 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/
converted_thread_context::throw_on_exit_result converted_thread_context::throw_on_exit_result
converted_thread_context::throw_on_exit(any_tuple const& msg) converted_thread_context::throw_on_exit(any_tuple const& msg)
{ {
if (match(msg, m_exit_msg_pattern)) if (matches(msg, m_exit_msg_pattern))
{ {
auto reason = msg.get_as<std::uint32_t>(1); auto reason = msg.get_as<std::uint32_t>(1);
if (reason != exit_reason::normal) if (reason != exit_reason::normal)
......
...@@ -15,6 +15,7 @@ unit_tests_SOURCES = main.cpp \ ...@@ -15,6 +15,7 @@ unit_tests_SOURCES = main.cpp \
test__queue_performance.cpp \ test__queue_performance.cpp \
test__remote_actor.cpp \ test__remote_actor.cpp \
test__ripemd_160.cpp \ test__ripemd_160.cpp \
test__match.cpp \
test__serialization.cpp \ test__serialization.cpp \
test__spawn.cpp \ test__spawn.cpp \
test__tuple.cpp \ test__tuple.cpp \
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/match.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
#include "cppa/detail/demangle.hpp" #include "cppa/detail/demangle.hpp"
...@@ -86,10 +87,9 @@ std::vector<std::string> split(std::string const& str, char delim) ...@@ -86,10 +87,9 @@ std::vector<std::string> split(std::string const& str, char delim)
return result; return result;
} }
std::map<std::string, std::string> std::vector<string_pair> get_kv_pairs(int argc, char** argv, int begin = 1)
get_kv_pairs(int argc, char** argv, int begin = 1)
{ {
std::map<std::string, std::string> result; std::vector<string_pair> result;
for (int i = begin; i < argc; ++i) for (int i = begin; i < argc; ++i)
{ {
auto vec = split(argv[i], '='); auto vec = split(argv[i], '=');
...@@ -97,60 +97,18 @@ get_kv_pairs(int argc, char** argv, int begin = 1) ...@@ -97,60 +97,18 @@ get_kv_pairs(int argc, char** argv, int begin = 1)
{ {
cerr << "\"" << argv[i] << "\" is not a key-value pair" << endl; cerr << "\"" << argv[i] << "\" is not a key-value pair" << endl;
} }
else if (result.insert(std::make_pair(vec[0], vec[1])).second == false) else if (std::any_of(result.begin(), result.end(),
[&](string_pair const& p) { return p.first == vec[0]; }))
{ {
cerr << "key \"" << vec[0] << "\" is already defined" << endl; cerr << "key \"" << vec[0] << "\" is already defined" << endl;
exit(1);
} }
} else
return result;
}
template<typename Iterator, class Container, typename Key>
inline bool found_key(Iterator& i, Container& cont, Key&& key)
{
return (i = cont.find(std::forward<Key>(key))) != cont.end();
}
template<typename F, typename S>
any_tuple to_tuple(std::pair<F, S> const& p)
{
return make_tuple(p.first, p.second);
}
struct match_helper
{
any_tuple tup;
template<class... Args>
void operator()(partial_function&& pf, Args&&... args)
{
partial_function tmp;
tmp.splice(std::move(pf), std::forward<Args>(args)...);
tmp(tup);
}
};
template<typename F, typename S>
match_helper match(std::pair<F, S> const& what)
{
return {to_tuple(what)};
}
template<class Container>
struct match_each_helper
{
Container const& args;
template<typename... Args>
void operator()(partial_function&& pf, Args&&... args)
{
partial_function tmp;
tmp.splice(std::move(pf), std::forward<Args>(args)...);
for (auto& arg : args)
{ {
tmp(to_tuple(arg)); result.emplace_back(vec[0], vec[1]);
} }
} }
}; return result;
}
void usage(char const* argv0) void usage(char const* argv0)
{ {
...@@ -162,39 +120,67 @@ void usage(char const* argv0) ...@@ -162,39 +120,67 @@ void usage(char const* argv0)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
/*
std::string abc = "abc";
cout << "is_iterable<string> = " << cppa::util::is_iterable<std::string>::value << endl;
match(abc)
(
on("abc") >> []()
{
cout << "ABC" << endl;
}
);
match_each(argv + 1, argv + argc)
(
on_arg_match >> [](std::string const& str)
{
cout << "matched \"" << str << "\"" << endl;
}
);
pmatch_each(argv + 1, argv + argc, [](char const* cstr) { return split(cstr, '='); })
(
on_arg_match >> [](std::string const& key, std::string const& value)
{
cout << "key = \"" << key << "\", value = \"" << value << "\""
<< endl;
}
);
return 0;
*/
auto args = get_kv_pairs(argc, argv); auto args = get_kv_pairs(argc, argv);
for (auto& kvp : args) match_each(args)
{ (
match(kvp) on("run", arg_match) >> [&](std::string const& what)
( {
on("run", arg_match) >> [&](std::string const& what) if (what == "remote_actor")
{ {
if (what == "remote_actor") test__remote_actor(argv[0], true, args);
{ exit(0);
test__remote_actor(argv[0], true, args); }
exit(0); },
} on("scheduler", arg_match) >> [](std::string const& sched)
}, {
on("scheduler", arg_match) >> [](std::string const& sched) if (sched == "thread_pool_scheduler")
{ {
if (sched == "thread_pool_scheduler") cout << "using thread_pool_scheduler" << endl;
{ set_scheduler(new cppa::detail::thread_pool_scheduler);
cout << "using thread_pool_scheduler" << endl;
set_scheduler(new cppa::detail::thread_pool_scheduler);
}
else if (sched == "mock_scheduler")
{
cout << "using mock_scheduler" << endl;
set_scheduler(new cppa::detail::mock_scheduler);
}
else
{
cerr << "unknown scheduler: " << sched << endl;
exit(1);
}
} }
); else if (sched == "mock_scheduler")
} {
cout << "using mock_scheduler" << endl;
set_scheduler(new cppa::detail::mock_scheduler);
}
else
{
cerr << "unknown scheduler: " << sched << endl;
exit(1);
}
}
);
//print_node_id(); //print_node_id();
std::cout << std::boolalpha; std::cout << std::boolalpha;
size_t errors = 0; size_t errors = 0;
...@@ -203,6 +189,7 @@ int main(int argc, char** argv) ...@@ -203,6 +189,7 @@ int main(int argc, char** argv)
RUN_TEST(test__intrusive_containers); RUN_TEST(test__intrusive_containers);
RUN_TEST(test__uniform_type); RUN_TEST(test__uniform_type);
RUN_TEST(test__pattern); RUN_TEST(test__pattern);
RUN_TEST(test__match);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
RUN_TEST(test__type_list); RUN_TEST(test__type_list);
RUN_TEST(test__fixed_vector); RUN_TEST(test__fixed_vector);
......
#ifndef TEST_HPP #ifndef TEST_HPP
#define TEST_HPP #define TEST_HPP
#include <map> #include <vector>
#include <string> #include <string>
#include <cstddef> #include <cstddef>
#include <iostream> #include <iostream>
...@@ -88,14 +88,17 @@ std::cerr << err_msg << std::endl; \ ...@@ -88,14 +88,17 @@ std::cerr << err_msg << std::endl; \
#define CPPA_CHECK_NOT_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) != (rhs_loc))) #define CPPA_CHECK_NOT_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) != (rhs_loc)))
typedef std::pair<std::string, std::string> string_pair;
size_t test__yield_interface(); size_t test__yield_interface();
size_t test__remote_actor(const char* app_path, bool is_client, size_t test__remote_actor(char const* app_path, bool is_client,
const std::map<std::string, std::string>& args); std::vector<string_pair> const& args);
size_t test__ripemd_160(); size_t test__ripemd_160();
size_t test__uniform_type(); size_t test__uniform_type();
size_t test__type_list(); size_t test__type_list();
size_t test__atom(); size_t test__atom();
size_t test__tuple(); size_t test__tuple();
size_t test__match();
size_t test__spawn(); size_t test__spawn();
size_t test__pattern(); size_t test__pattern();
size_t test__intrusive_ptr(); size_t test__intrusive_ptr();
......
#include "test.hpp"
#include "cppa/match.hpp"
size_t test__match()
{
CPPA_TEST(test__match);
return CPPA_TEST_RESULT;
}
...@@ -16,9 +16,10 @@ using namespace cppa; ...@@ -16,9 +16,10 @@ using namespace cppa;
namespace { namespace {
void client_part(std::map<std::string, std::string> const& args) void client_part(std::vector<string_pair> const& args)
{ {
auto i = args.find("port"); auto i = std::find_if(args.begin(), args.end(),
[](string_pair const& p) { return p.first == "port"; });
if (i == args.end()) if (i == args.end())
{ {
throw std::runtime_error("no port specified"); throw std::runtime_error("no port specified");
...@@ -34,7 +35,7 @@ void client_part(std::map<std::string, std::string> const& args) ...@@ -34,7 +35,7 @@ void client_part(std::map<std::string, std::string> const& args)
} // namespace <anonymous> } // namespace <anonymous>
size_t test__remote_actor(char const* app_path, bool is_client, size_t test__remote_actor(char const* app_path, bool is_client,
std::map<std::string, std::string> const& args) std::vector<string_pair> const& args)
{ {
if (is_client) if (is_client)
{ {
......
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