Commit cdd9aa4d authored by Dominik Charousset's avatar Dominik Charousset

improved pattern matching

parent 68086d89
...@@ -40,6 +40,7 @@ libcppa_la_SOURCES = \ ...@@ -40,6 +40,7 @@ libcppa_la_SOURCES = \
src/object.cpp \ src/object.cpp \
src/object_array.cpp \ src/object_array.cpp \
src/partial_function.cpp \ src/partial_function.cpp \
src/pattern.cpp \
src/post_office.cpp \ src/post_office.cpp \
src/post_office_msg.cpp \ src/post_office_msg.cpp \
src/primitive_variant.cpp \ src/primitive_variant.cpp \
...@@ -191,6 +192,7 @@ nobase_library_include_HEADERS = \ ...@@ -191,6 +192,7 @@ nobase_library_include_HEADERS = \
cppa/util/enable_if.hpp \ cppa/util/enable_if.hpp \
cppa/util/fiber.hpp \ cppa/util/fiber.hpp \
cppa/util/fixed_vector.hpp \ cppa/util/fixed_vector.hpp \
cppa/util/guard.hpp \
cppa/util/if_else.hpp \ cppa/util/if_else.hpp \
cppa/util/is_array_of.hpp \ cppa/util/is_array_of.hpp \
cppa/util/is_builtin.hpp \ cppa/util/is_builtin.hpp \
......
...@@ -258,3 +258,5 @@ cppa/detail/tuple_view.hpp ...@@ -258,3 +258,5 @@ cppa/detail/tuple_view.hpp
cppa/detail/container_tuple_view.hpp cppa/detail/container_tuple_view.hpp
cppa/detail/matches.hpp cppa/detail/matches.hpp
unit_testing/test__match.cpp unit_testing/test__match.cpp
src/pattern.cpp
cppa/util/guard.hpp
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
#ifndef ANY_TUPLE_HPP #ifndef ANY_TUPLE_HPP
#define ANY_TUPLE_HPP #define ANY_TUPLE_HPP
#include <iostream>
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp" #include "cppa/cow_ptr.hpp"
...@@ -183,7 +181,7 @@ class any_tuple ...@@ -183,7 +181,7 @@ class any_tuple
static constexpr bool can_optimize = static constexpr bool can_optimize =
std::is_same<converted, vtype>::value std::is_same<converted, vtype>::value
&& std::is_reference<T>::value && std::is_reference<T>::value
&& !std::is_const<T>::value; && !std::is_const<typename std::remove_reference<T>::type>::value;
std::integral_constant<bool, can_optimize> token; std::integral_constant<bool, can_optimize> token;
return any_tuple{simple_view(std::forward<T>(value), token)}; return any_tuple{simple_view(std::forward<T>(value), token)};
} }
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#ifndef UNBOXED_HPP #ifndef UNBOXED_HPP
#define UNBOXED_HPP #define UNBOXED_HPP
#include <memory>
#include "cppa/util/guard.hpp"
#include "cppa/util/wrapped.hpp" #include "cppa/util/wrapped.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -65,6 +68,12 @@ struct unboxed<util::wrapped<T> (*)()> ...@@ -65,6 +68,12 @@ struct unboxed<util::wrapped<T> (*)()>
typedef typename util::wrapped<T>::type type; typedef typename util::wrapped<T>::type type;
}; };
template<typename T>
struct unboxed<std::unique_ptr<util::guard<T>>>
{
typedef T type;
};
} } // namespace cppa::detail } } // namespace cppa::detail
#endif // UNBOXED_HPP #endif // UNBOXED_HPP
...@@ -81,7 +81,7 @@ class uniform_type_info_map ...@@ -81,7 +81,7 @@ class uniform_type_info_map
// maps uniform names to uniform type informations // maps uniform names to uniform type informations
uti_map m_by_uname; uti_map m_by_uname;
// maps sizeof(-integer_type-) to { raw-names-set, uniform-names-set } // maps sizeof(-integer_type-) to { signed-names-set, unsigned-names-set }
int_map m_ints; int_map m_ints;
}; };
......
...@@ -73,6 +73,26 @@ struct match_each_helper ...@@ -73,6 +73,26 @@ struct match_each_helper
} }
}; };
template<class Container>
struct copying_match_each_helper
{
copying_match_each_helper(copying_match_each_helper const&) = delete;
copying_match_each_helper& operator=(copying_match_each_helper const&) = delete;
Container vec;
copying_match_each_helper(Container tmp) : vec(std::move(tmp)) { }
copying_match_each_helper(copying_match_each_helper&&) = default;
template<typename... Args>
void operator()(partial_function&& arg0, Args&&... args)
{
partial_function tmp;
tmp.splice(std::move(arg0), std::forward<Args>(args)...);
for (auto& i : vec)
{
tmp(any_tuple::view(i));
}
}
};
template<typename Iterator, typename Projection> template<typename Iterator, typename Projection>
struct pmatch_each_helper struct pmatch_each_helper
{ {
...@@ -112,9 +132,9 @@ inline detail::match_helper match(any_tuple t) ...@@ -112,9 +132,9 @@ inline detail::match_helper match(any_tuple t)
* @brief Match expression. * @brief Match expression.
*/ */
template<typename T> template<typename T>
detail::match_helper match(T& what) detail::match_helper match(T&& what)
{ {
return any_tuple::view(what); return any_tuple::view(std::forward<T>(what));
} }
/** /**
...@@ -127,6 +147,16 @@ auto match_each(Container& what) ...@@ -127,6 +147,16 @@ auto match_each(Container& what)
return {std::begin(what), std::end(what)}; return {std::begin(what), std::end(what)};
} }
template<typename T>
auto match_each(std::initializer_list<T> list)
-> detail::copying_match_each_helper<std::vector<typename detail::strip_and_convert<T>::type>>
{
std::vector<typename detail::strip_and_convert<T>::type> vec;
vec.reserve(list.size());
for (auto& i : list) vec.emplace_back(std::move(i));
return vec;
}
template<typename InputIterator> template<typename InputIterator>
auto match_each(InputIterator first, InputIterator last) auto match_each(InputIterator first, InputIterator last)
-> detail::match_each_helper<InputIterator> -> detail::match_each_helper<InputIterator>
......
...@@ -260,11 +260,11 @@ constexpr boxed_arg_match_t arg_match = boxed_arg_match_t(); ...@@ -260,11 +260,11 @@ constexpr boxed_arg_match_t arg_match = boxed_arg_match_t();
constexpr detail::on_the_fly_rvalue_builder on_arg_match; constexpr detail::on_the_fly_rvalue_builder on_arg_match;
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
detail::rvalue_builder<typename detail::unboxed<Arg0>::type, detail::rvalue_builder<typename detail::unboxed<typename util::rm_ref<Arg0>::type>::type,
typename detail::unboxed<Args>::type...> typename detail::unboxed<typename util::rm_ref<Args>::type>::type...>
on(Arg0 const& arg0, Args const&... args) on(Arg0&& arg0, Args&&... args)
{ {
return { arg0, args... }; return {std::forward<Arg0>(arg0), std::forward<Args>(args)...};
} }
template<typename... TypeList> template<typename... TypeList>
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "cppa/type_value_pair.hpp" #include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/guard.hpp"
#include "cppa/util/tbind.hpp" #include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/arg_match_t.hpp" #include "cppa/util/arg_match_t.hpp"
...@@ -106,6 +107,11 @@ struct cmp_helper ...@@ -106,6 +107,11 @@ struct cmp_helper
return what == tup.get_as<T>(i++); return what == tup.get_as<T>(i++);
} }
template<typename T> template<typename T>
inline bool operator()(std::unique_ptr<util::guard<T> > const& g)
{
return (*g)(tup.get_as<T>(i++));
}
template<typename T>
inline bool operator()(util::wrapped<T> const&) inline bool operator()(util::wrapped<T> const&)
{ {
++i; ++i;
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 GUARD_HPP
#define GUARD_HPP
namespace cppa { namespace util {
template<typename T>
struct guard
{
virtual ~guard() { }
virtual bool operator()(T const&) const = 0;
};
} } // namespace cppa::util
#endif // GUARD_HPP
...@@ -46,6 +46,9 @@ struct rm_ref<T const&> { typedef T type; }; ...@@ -46,6 +46,9 @@ struct rm_ref<T const&> { typedef T type; };
template<typename T> template<typename T>
struct rm_ref<T&> { typedef T type; }; struct rm_ref<T&> { typedef T type; };
template<typename T>
struct rm_ref<const T> { typedef T type; };
template<> template<>
struct rm_ref<void> { }; struct rm_ref<void> { };
......
...@@ -135,11 +135,4 @@ void demonitor(actor_ptr& whom) ...@@ -135,11 +135,4 @@ void demonitor(actor_ptr& whom)
if (whom) whom->detach(mtoken); if (whom) whom->detach(mtoken);
} }
value_matcher::~value_matcher() { }
bool dummy_matcher::operator()(any_tuple const&)
{
return true;
}
} // namespace cppa } // namespace cppa
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/>. *
\******************************************************************************/
#include "cppa/pattern.hpp"
namespace cppa {
value_matcher::~value_matcher() { }
bool dummy_matcher::operator()(any_tuple const&)
{
return true;
}
} // namespace cppa
...@@ -264,5 +264,4 @@ std::string to_uniform_name(const std::type_info& tinfo) ...@@ -264,5 +264,4 @@ std::string to_uniform_name(const std::type_info& tinfo)
return to_uniform_name(demangle(tinfo.name())); return to_uniform_name(demangle(tinfo.name()));
} }
} } // namespace cppa::detail } } // namespace cppa::detail
...@@ -112,14 +112,14 @@ typedef std::set<std::string> string_set; ...@@ -112,14 +112,14 @@ typedef std::set<std::string> string_set;
template<typename Int> template<typename Int>
void push(std::map<int, std::pair<string_set, string_set>>& ints, void push(std::map<int, std::pair<string_set, string_set>>& ints,
std::integral_constant<bool, true>) std::integral_constant<bool, true>) // signed version
{ {
ints[sizeof(Int)].first.insert(raw_name<Int>()); ints[sizeof(Int)].first.insert(raw_name<Int>());
} }
template<typename Int> template<typename Int>
void push(std::map<int, std::pair<string_set, string_set>>& ints, void push(std::map<int, std::pair<string_set, string_set>>& ints,
std::integral_constant<bool, false>) std::integral_constant<bool, false>) // unsigned version
{ {
ints[sizeof(Int)].second.insert(raw_name<Int>()); ints[sizeof(Int)].second.insert(raw_name<Int>());
} }
...@@ -625,25 +625,19 @@ class int_tinfo : public detail::default_uniform_type_info_impl<T> ...@@ -625,25 +625,19 @@ class int_tinfo : public detail::default_uniform_type_info_impl<T>
public: public:
bool equals(const std::type_info& tinfo) const bool equals(std::type_info const& tinfo) const
{ {
// TODO: string comparsion sucks & is slow; find a nicer solution // TODO: string comparsion sucks & is slow; find a nicer solution
auto map_iter = uti_map().int_names().find(sizeof(T)); auto map_iter = uti_map().int_names().find(sizeof(T));
const string_set& st = is_signed<T>::value ? map_iter->second.first string_set const& st = is_signed<T>::value ? map_iter->second.first
: map_iter->second.second; : map_iter->second.second;
auto end = st.end(); auto x = raw_name(tinfo);
for (auto i = st.begin(); i != end; ++i) return std::any_of(st.begin(), st.end(),
{ [&](std::string const& y) { return x == y; });
if ((*i) == raw_name(tinfo)) return true;
}
return false;
} }
}; };
//} } } // namespace cppa::detail::<anonymous>
//namespace cppa { namespace detail {
using std::is_integral; using std::is_integral;
using util::enable_if; using util::enable_if;
using util::disable_if; using util::disable_if;
...@@ -655,14 +649,12 @@ class uniform_type_info_map_helper ...@@ -655,14 +649,12 @@ class uniform_type_info_map_helper
typedef uniform_type_info_map* this_ptr; typedef uniform_type_info_map* this_ptr;
static void insert(this_ptr d, uniform_type_info* uti, static void insert(this_ptr d,
const std::set<std::string>& tnames) uniform_type_info* uti,
std::set<std::string> const& tnames)
{ {
if (tnames.empty()) CPPA_REQUIRE(tnames.empty() == false);
{ for (std::string const& tname : tnames)
throw std::logic_error("tnames.empty()");
}
for (const std::string& tname : tnames)
{ {
d->m_by_rname.insert(std::make_pair(tname, uti)); d->m_by_rname.insert(std::make_pair(tname, uti));
} }
...@@ -671,16 +663,15 @@ class uniform_type_info_map_helper ...@@ -671,16 +663,15 @@ class uniform_type_info_map_helper
template<typename T> template<typename T>
static inline void insert(this_ptr d, static inline void insert(this_ptr d,
const std::set<std::string>& tnames, std::set<std::string> const& tnames,
typename enable_if<is_integral<T>>::type* = 0) typename enable_if<is_integral<T>>::type* = 0)
{ {
//insert(new default_uniform_type_info_impl<T>(), tnames);
insert(d, new int_tinfo<T>, tnames); insert(d, new int_tinfo<T>, tnames);
} }
template<typename T> template<typename T>
static inline void insert(this_ptr d, static inline void insert(this_ptr d,
const std::set<std::string>& tnames, std::set<std::string> const& tnames,
typename disable_if<is_integral<T>>::type* = 0) typename disable_if<is_integral<T>>::type* = 0)
{ {
insert(d, new default_uniform_type_info_impl<T>(), tnames); insert(d, new default_uniform_type_info_impl<T>(), tnames);
...@@ -689,7 +680,7 @@ class uniform_type_info_map_helper ...@@ -689,7 +680,7 @@ class uniform_type_info_map_helper
template<typename T> template<typename T>
static inline void insert(this_ptr d) static inline void insert(this_ptr d)
{ {
insert<T>(d, { std::string(raw_name<T>()) }); insert<T>(d, {std::string(raw_name<T>())});
} }
static void init(this_ptr d) static void init(this_ptr d)
...@@ -707,6 +698,8 @@ class uniform_type_info_map_helper ...@@ -707,6 +698,8 @@ class uniform_type_info_map_helper
insert(d, new addr_msg_tinfo, {raw_name<detail::addressed_message>() }); insert(d, new addr_msg_tinfo, {raw_name<detail::addressed_message>() });
insert(d, new void_type_tinfo, { raw_name<void_type>() }); insert(d, new void_type_tinfo, { raw_name<void_type>() });
insert<float>(d); insert<float>(d);
insert<double>(d);
/*
if (sizeof(double) == sizeof(long double)) if (sizeof(double) == sizeof(long double))
{ {
std::string dbl = raw_name<double>(); std::string dbl = raw_name<double>();
...@@ -718,6 +711,7 @@ class uniform_type_info_map_helper ...@@ -718,6 +711,7 @@ class uniform_type_info_map_helper
insert<double>(d); insert<double>(d);
insert<long double>(d); insert<long double>(d);
} }
*/
// first: signed // first: signed
// second: unsigned // second: unsigned
push<char, push<char,
......
...@@ -11,94 +11,106 @@ using namespace cppa; ...@@ -11,94 +11,106 @@ using namespace cppa;
using std::vector; using std::vector;
using std::string; using std::string;
template<typename T> #define CPPA_GUARD_IMPL(GuardOperator) \
std::function<bool (T const&)> is_any_of(std::vector<T> vec) struct impl : util::guard<T> \
{ { \
return [=](T const& value) T m_val; \
{ impl(T&& val) : m_val(std::move(val)) { } \
return std::any_of(vec.begin(), vec.end(), bool operator()(T const& other) const { return other < m_val; } \
[&](T const& v) { return value == v; }); }; return std::unique_ptr<util::guard<T>>{new impl{std::move(value)}}
};
}
template<typename T> struct pattern_placeholder
std::function<bool (T const&)> is_none_of(std::vector<T> vec)
{ {
return [=](T const& value) constexpr pattern_placeholder() { }
{
return std::none_of(vec.begin(), vec.end(),
[&](T const& v) { return value == v; });
};
}
struct placeholder
{
constexpr placeholder() { }
template<typename T> template<typename T>
std::function<bool (T const&)> operator<(T const& value) const std::unique_ptr<util::guard<T>> operator<(T value) const
{ {
return [=](T const& other) { return other < value; }; CPPA_GUARD_IMPL(<);
} }
template<typename T> template<typename T>
std::function<bool (T const&)> operator<=(T const& value) const std::unique_ptr<util::guard<T>> operator<=(T value) const
{ {
return [=](T const& other) { return other <= value; }; CPPA_GUARD_IMPL(<=);
} }
template<typename T> template<typename T>
std::function<bool (T const&)> operator>(T const& value) const std::unique_ptr<util::guard<T>> operator>(T value) const
{ {
return [=](T const& other) { return other > value; }; CPPA_GUARD_IMPL(>);
} }
template<typename T> template<typename T>
std::function<bool (T const&)> operator>=(T const& value) const std::unique_ptr<util::guard<T>> operator>=(T value) const
{ {
return [=](T const& other) { return other >= value; }; CPPA_GUARD_IMPL(>=);
} }
template<typename T> template<typename T>
std::function<bool (T const&)> operator==(T const& value) const T operator==(T value) const
{ {
return [=](T const& other) { return other == value; }; return value;
} }
template<typename T> template<typename T>
std::function<bool (T const&)> operator!=(T const& value) const std::unique_ptr<util::guard<T>> operator!=(T value) const
{ {
return [=](T const& other) { return other != value; }; CPPA_GUARD_IMPL(!=);
} }
template<typename T> template<typename T>
std::function<bool (T const&)> any_of(std::vector<T> vec) const std::unique_ptr<util::guard<T>> any_of(std::vector<T> vec) const
{ {
return [=](T const& value) cout << "guard<vector<" << detail::demangle(typeid(T).name()) << ">>" << endl;
typedef std::vector<T> vector_type;
struct impl : util::guard<T>
{ {
return std::any_of(vec.begin(), vec.end(), vector_type m_vec;
[&](T const& v) { return value == v; }); impl(vector_type&& v) : m_vec(std::move(v)) { }
bool operator()(T const& value) const
{
cout << "guard<vector<" << detail::demangle(typeid(T).name()) << ">>::operator()(" << value << ")" << endl;
return std::any_of(m_vec.begin(), m_vec.end(),
[&](T const& val) { return val == value; });
}
}; };
return std::unique_ptr<util::guard<T>>{new impl{std::move(vec)}};
} }
template<typename T> template<typename T>
std::function<bool (typename detail::implicit_conversions<T>::type const&)> std::unique_ptr<util::guard<typename detail::strip_and_convert<T>::type>>
any_of(std::initializer_list<T> list) const any_of(std::initializer_list<T> list) const
{ {
typedef typename detail::implicit_conversions<T>::type ctype; typedef typename detail::strip_and_convert<T>::type sc_type;
vector<ctype> vec; std::vector<sc_type> vec;
vec.reserve(list.size());
for (auto& i : list) vec.emplace_back(i); for (auto& i : list) vec.emplace_back(i);
//vec.insert(vec.begin(), list.begin(), list.end()); return this->any_of(std::move(vec));
return [vec](ctype const& value)
{
return std::any_of(vec.begin(), vec.end(),
[&](ctype const& v) { return value == v; });
};
} }
template<typename T> template<typename T>
std::function<bool (T const&)> none_of(std::vector<T> vec) const std::unique_ptr<util::guard<typename detail::strip_and_convert<T>::type>>
starts_with(T substr) const
{ {
return [=](T const& value) typedef typename detail::strip_and_convert<T>::type str_type;
struct impl : util::guard<str_type>
{ {
return std::none_of(vec.begin(), vec.end(), str_type m_str;
[&](T const& v) { return value == v; }); impl(str_type str) : m_str(std::move(str)) { }
bool operator()(str_type const& str) const
{
return m_str.size() <= str.size()
&& std::equal(m_str.begin(), m_str.end(), str.begin());
}
}; };
return std::unique_ptr<util::guard<str_type>>{new impl{std::move(substr)}};
} }
}; };
static constexpr placeholder _x; static constexpr pattern_placeholder _x;
template<typename... Args> template<typename... Args>
void _on(Args&&...) void _on(Args&&...)
...@@ -109,6 +121,7 @@ size_t test__match() ...@@ -109,6 +121,7 @@ size_t test__match()
{ {
CPPA_TEST(test__match); CPPA_TEST(test__match);
/*
auto xfun = _x.any_of<int>({1, 2, 3}); auto xfun = _x.any_of<int>({1, 2, 3});
cout << "xfun(4) = " << xfun(4) << endl; cout << "xfun(4) = " << xfun(4) << endl;
cout << "xfun(2) = " << xfun(2) << endl; cout << "xfun(2) = " << xfun(2) << endl;
...@@ -126,6 +139,7 @@ size_t test__match() ...@@ -126,6 +139,7 @@ size_t test__match()
auto hfun = _x.any_of({"-h", "--help"}); auto hfun = _x.any_of({"-h", "--help"});
cout << "hfun(-h) = " << hfun("-h") << endl; cout << "hfun(-h) = " << hfun("-h") << endl;
cout << "hfun(-r) = " << hfun("-r") << endl; cout << "hfun(-r) = " << hfun("-r") << endl;
*/
bool invoked = false; bool invoked = false;
match("abc") match("abc")
...@@ -138,6 +152,39 @@ size_t test__match() ...@@ -138,6 +152,39 @@ size_t test__match()
if (!invoked) { CPPA_ERROR("match(\"abc\") failed"); } if (!invoked) { CPPA_ERROR("match(\"abc\") failed"); }
invoked = false; invoked = false;
match_each({"-h", "-wtf"})
(
on(_x.any_of({"-h", "--help"})) >> []()
{
cout << "AWESOME!!!" << endl;
},
on(_x.starts_with("-")) >> [](std::string const& str)
{
match_each(str.begin() + 1, str.end())
(
on<char>() >> [](char c)
//on(_x.any_of({'w', 't', 'f'})) >> [](char c)
{
cout << c;
},
others() >> [](any_tuple const& tup)
{
cout << "oops: " << to_string(tup) << endl;
}
);
cout << endl;
}
);
match(5)
(
on(_x < 6) >> [](int i)
{
cout << i << " < 6 !!! :)" << endl;
}
);
vector<string> vec{"a", "b", "c"}; vector<string> vec{"a", "b", "c"};
match(vec) match(vec)
( (
......
...@@ -190,6 +190,37 @@ size_t test__pattern() ...@@ -190,6 +190,37 @@ size_t test__pattern()
); );
CPPA_CHECK_EQUAL(true, invoked); CPPA_CHECK_EQUAL(true, invoked);
pattern<char, short, int, long> p12;
pattern<char, short, int, long> p13{char(0), short(1), int(2), long(3)};
any_tuple t4 = make_cow_tuple(char(0), short(1), int(2), long(3));
CPPA_CHECK((detail::matches(t4, p12)));
CPPA_CHECK(p12._matches_values(t4));
CPPA_CHECK((detail::matches(t4, p13)));
CPPA_CHECK(p13._matches_values(t4));
invoked = false;
match('a')
(
on<char>() >> [&](char c)
{
invoked = true;
CPPA_CHECK_EQUAL('a', c);
}
);
CPPA_CHECK_EQUAL(true, invoked);
invoked = false;
const char muhaha = 'a';
match(muhaha)
(
on<char>() >> [&](char c)
{
invoked = true;
CPPA_CHECK_EQUAL('a', c);
}
);
CPPA_CHECK_EQUAL(true, invoked);
/* /*
CPPA_CHECK(p0(x)); CPPA_CHECK(p0(x));
CPPA_CHECK(p1(x)); CPPA_CHECK(p1(x));
......
...@@ -89,11 +89,6 @@ size_t test__uniform_type() ...@@ -89,11 +89,6 @@ size_t test__uniform_type()
"@channel", // cppa::channel_ptr "@channel", // cppa::channel_ptr
"cppa::util::duration" "cppa::util::duration"
}; };
if (sizeof(double) != sizeof(long double))
{
// long double is only present if it's not an alias for double
expected.insert("long double");
}
// holds the type names we see at runtime // holds the type names we see at runtime
std::set<std::string> found; std::set<std::string> found;
// fetch all available type names // fetch all available type names
......
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