Commit cc1c3445 authored by neverlord's avatar neverlord

pattern matching

parent 05b61ecf
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define TDATA_HPP #define TDATA_HPP
#include <typeinfo> #include <typeinfo>
#include <functional>
#include "cppa/get.hpp" #include "cppa/get.hpp"
#include "cppa/option.hpp" #include "cppa/option.hpp"
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#include "cppa/util/arg_match_t.hpp" #include "cppa/util/arg_match_t.hpp"
#include "cppa/detail/boxed.hpp" #include "cppa/detail/boxed.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp" #include "cppa/detail/implicit_conversions.hpp"
...@@ -66,6 +68,36 @@ inline void* ptr_to(T* what) { return what; } ...@@ -66,6 +68,36 @@ inline void* ptr_to(T* what) { return what; }
template<typename T> template<typename T>
inline void const* ptr_to(T const* what) { return what; } inline void const* ptr_to(T const* what) { return what; }
template<typename T>
inline void* ptr_to(std::reference_wrapper<T> const& what)
{
return &(what.get());
}
template<typename T>
inline void const* ptr_to(std::reference_wrapper<const T> const& what)
{
return &(what.get());
}
template<typename T>
inline uniform_type_info const* utype_of(T const&)
{
return static_types_array<T>::arr[0];
}
template<typename T>
inline uniform_type_info const* utype_of(std::reference_wrapper<T> const&)
{
return static_types_array<typename util::rm_ref<T>::type>::arr[0];
}
template<typename T>
inline uniform_type_info const* utype_of(T const* ptr)
{
return utype_of(*ptr);
}
template<typename T> template<typename T>
struct boxed_or_void struct boxed_or_void
{ {
...@@ -78,8 +110,20 @@ struct boxed_or_void<util::void_type> ...@@ -78,8 +110,20 @@ struct boxed_or_void<util::void_type>
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<typename T>
struct unbox_ref
{
typedef T type;
};
template<typename T>
struct unbox_ref<std::reference_wrapper<T> >
{
typedef T type;
};
/* /*
* "enhanced std::tuple" * "enhanced" std::tuple
*/ */
template<typename...> template<typename...>
struct tdata; struct tdata;
...@@ -112,21 +156,27 @@ struct tdata<> ...@@ -112,21 +156,27 @@ struct tdata<>
inline tdata(tdata&&) { } inline tdata(tdata&&) { }
inline tdata(tdata const&) { } inline tdata(tdata const&) { }
//// swallow "arg_match" silently inline size_t size() const { return num_elements; }
//constexpr tdata(util::wrapped<util::arg_match_t> const&) { }
tdata<>& tail() { return *this; } tdata<>& tail() { return *this; }
tdata<> const& tail() const { return *this; } tdata<> const& tail() const { return *this; }
tdata<> const& ctail() const { return *this; }
inline void const* at(size_t) const inline void const* at(size_t) const
{ {
throw std::out_of_range(""); throw std::out_of_range("tdata<>");
}
inline void* mutable_at(size_t)
{
throw std::out_of_range("tdata<>");
} }
inline uniform_type_info const* type_at(size_t) const inline uniform_type_info const* type_at(size_t) const
{ {
throw std::out_of_range(""); throw std::out_of_range("tdata<>");
} }
inline void set() { } inline void set() { }
...@@ -187,7 +237,10 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -187,7 +237,10 @@ struct tdata<Head, Tail...> : tdata<Tail...>
typedef tdata<Tail...> super; typedef tdata<Tail...> super;
typedef util::type_list<Head, Tail...> types; typedef util::type_list<
typename unbox_ref<Head>::type,
typename unbox_ref<Tail>::type...>
types;
Head head; Head head;
...@@ -216,16 +269,7 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -216,16 +269,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
tdata(tdata const&) = default; tdata(tdata const&) = default;
// allow partial initialization
//template<typename... Args>
//tdata(Head const& v0, Args const&... vals) : super(vals...), head(v0) { }
// allow partial initialization
//template<typename... Args>
//tdata(Head&& v0, Args const&... vals) : super(vals...), head(std::move(v0)) { }
// allow (partial) initialization from a different tdata // allow (partial) initialization from a different tdata
// with traling extra arguments to initialize additional arguments
template<typename... Y> template<typename... Y>
tdata(tdata<Y...>& other) : super(other.tail()), head(other.head) tdata(tdata<Y...>& other) : super(other.tail()), head(other.head)
...@@ -243,42 +287,6 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -243,42 +287,6 @@ struct tdata<Head, Tail...> : tdata<Tail...>
{ {
} }
/*
template<typename... Y>
tdata(Head const& arg, tdata<Y...> const& other)
: super(other), head(arg)
{
}
template<typename... Y>
tdata(tdata<Head> const& arg, tdata<Y...> const& other)
: super(other), head(arg.head)
{
}
template<typename ExtraArg, typename Y0, typename Y1, typename... Y>
tdata(tdata<Y0, Y1, Y...> const& other, ExtraArg const& arg)
: super(other.tail(), arg), head(other.head)
{
}
template<typename ExtraArg, typename Y0>
tdata(tdata<Y0> const& other, ExtraArg const& arg,
typename util::enable_if_c< std::is_same<ExtraArg, ExtraArg>::value
&& (sizeof...(Tail) > 0)>::type* = 0)
: super(arg), head(other.head)
{
}
template<typename ExtraArg, typename Y0>
tdata(tdata<Y0> const& other, ExtraArg const& arg,
typename util::enable_if_c< std::is_same<ExtraArg, ExtraArg>::value
&& (sizeof...(Tail) == 0)>::type* = 0)
: super(), head(other.head, arg)
{
}
*/
template<typename... Y> template<typename... Y>
tdata& operator=(tdata<Y...> const& other) tdata& operator=(tdata<Y...> const& other)
{ {
...@@ -293,20 +301,39 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -293,20 +301,39 @@ struct tdata<Head, Tail...> : tdata<Tail...>
super::set(std::forward<Args>(args)...); super::set(std::forward<Args>(args)...);
} }
inline size_t size() const { return num_elements; }
// upcast // upcast
inline tdata<Tail...>& tail() { return *this; } inline tdata<Tail...>& tail() { return *this; }
inline tdata<Tail...> const& tail() const { return *this; } inline tdata<Tail...> const& tail() const { return *this; }
inline tdata<Tail...> const& ctail() const { return *this; }
inline void const* at(size_t p) const inline void const* at(size_t p) const
{ {
return (p == 0) ? ptr_to(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 void* mutable_at(size_t p)
{ {
return (p == 0) ? uniform_typeid(typeid(Head)) : super::type_at(p-1); if (p == 0)
{
# ifdef CPPA_DEBUG
if (std::is_same<decltype(ptr_to(head)), void const*>::value)
{
throw std::logic_error{"mutable_at with const head"};
}
# endif
return const_cast<void*>(ptr_to(head));
}
return super::mutable_at(p - 1);
} }
inline uniform_type_info const* type_at(size_t p) const
{
return (p == 0) ? utype_of(head) : super::type_at(p-1);
}
Head& _back(std::integral_constant<size_t, 0>) Head& _back(std::integral_constant<size_t, 0>)
{ {
......
...@@ -108,7 +108,7 @@ class tuple_view : public abstract_tuple ...@@ -108,7 +108,7 @@ class tuple_view : public abstract_tuple
void* mutable_at(size_t pos) void* mutable_at(size_t pos)
{ {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
return const_cast<void*>(at(pos)); return m_data.mutable_at(pos);
} }
uniform_type_info const* type_at(size_t pos) const uniform_type_info const* type_at(size_t pos) const
......
...@@ -322,12 +322,16 @@ struct ge_mutable_reference_wrapper ...@@ -322,12 +322,16 @@ struct ge_mutable_reference_wrapper
T* value; T* value;
ge_mutable_reference_wrapper() : value(nullptr) { } ge_mutable_reference_wrapper() : value(nullptr) { }
ge_mutable_reference_wrapper(T&&) = delete; ge_mutable_reference_wrapper(T&&) = delete;
ge_mutable_reference_wrapper(T const&) = delete;
ge_mutable_reference_wrapper(T& vref) : value(&vref) { } ge_mutable_reference_wrapper(T& vref) : value(&vref) { }
ge_mutable_reference_wrapper(ge_mutable_reference_wrapper const&) = default; ge_mutable_reference_wrapper(ge_mutable_reference_wrapper const&) = default;
ge_mutable_reference_wrapper& operator=(T& vref)
{
value = &vref;
return *this;
}
ge_mutable_reference_wrapper& operator=(ge_mutable_reference_wrapper const&) = default; ge_mutable_reference_wrapper& operator=(ge_mutable_reference_wrapper const&) = default;
T& get() { CPPA_REQUIRE(value != 0); return *value; } T& get() const { CPPA_REQUIRE(value != 0); return *value; }
operator T& () { CPPA_REQUIRE(value != 0); return *value; } operator T& () const { CPPA_REQUIRE(value != 0); return *value; }
}; };
template<typename T> template<typename T>
...@@ -338,6 +342,11 @@ struct ge_reference_wrapper ...@@ -338,6 +342,11 @@ struct ge_reference_wrapper
ge_reference_wrapper() : value(nullptr) { } ge_reference_wrapper() : value(nullptr) { }
ge_reference_wrapper(T const& val_ref) : value(&val_ref) { } ge_reference_wrapper(T const& val_ref) : value(&val_ref) { }
ge_reference_wrapper(ge_reference_wrapper const&) = default; ge_reference_wrapper(ge_reference_wrapper const&) = default;
ge_reference_wrapper& operator=(T const& vref)
{
value = &vref;
return *this;
}
ge_reference_wrapper& operator=(ge_reference_wrapper const&) = default; ge_reference_wrapper& operator=(ge_reference_wrapper const&) = default;
T const& get() const { CPPA_REQUIRE(value != 0); return *value; } T const& get() const { CPPA_REQUIRE(value != 0); return *value; }
operator T const& () const { CPPA_REQUIRE(value != 0); return *value; } operator T const& () const { CPPA_REQUIRE(value != 0); return *value; }
...@@ -352,9 +361,9 @@ struct ge_reference_wrapper<bool> ...@@ -352,9 +361,9 @@ struct ge_reference_wrapper<bool>
ge_reference_wrapper(bool const& val_ref) : value(&val_ref) { } ge_reference_wrapper(bool const& val_ref) : value(&val_ref) { }
ge_reference_wrapper(ge_reference_wrapper const&) = default; ge_reference_wrapper(ge_reference_wrapper const&) = default;
ge_reference_wrapper& operator=(ge_reference_wrapper const&) = default; ge_reference_wrapper& operator=(ge_reference_wrapper const&) = default;
bool get() const { return *value; } bool get() const { CPPA_REQUIRE(value != 0); return *value; }
operator bool () const { return *value; } operator bool () const { CPPA_REQUIRE(value != 0); return *value; }
bool operator()() const { return *value; } bool operator()() const { CPPA_REQUIRE(value != 0); return *value; }
}; };
/** /**
......
...@@ -53,6 +53,16 @@ struct static_foreach_impl ...@@ -53,6 +53,16 @@ struct static_foreach_impl
::_ref(c, f, std::forward<Args>(args)...); ::_ref(c, f, std::forward<Args>(args)...);
} }
template<typename Container, typename Fun, typename... Args> template<typename Container, typename Fun, typename... Args>
static inline void _auto(Container& c, Fun& f, Args&&... args)
{
_ref(c, f, std::forward<Args>(args)...);
}
template<typename Container, typename Fun, typename... Args>
static inline void _auto(Container const& c, Fun& f, Args&&... args)
{
_(c, f, std::forward<Args>(args)...);
}
template<typename Container, typename Fun, typename... Args>
static inline bool eval(Container const& c, Fun& f, Args&&... args) static inline bool eval(Container const& c, Fun& f, Args&&... args)
{ {
return f(get<Begin>(c), std::forward<Args>(args)...) return f(get<Begin>(c), std::forward<Args>(args)...)
...@@ -76,6 +86,8 @@ struct static_foreach_impl<false, X, Y> ...@@ -76,6 +86,8 @@ struct static_foreach_impl<false, X, Y>
template<typename... Args> template<typename... Args>
static inline void _ref(Args&&...) { } static inline void _ref(Args&&...) { }
template<typename... Args> template<typename... Args>
static inline void _auto(Args&&...) { }
template<typename... Args>
static inline bool eval(Args&&...) { return true; } static inline bool eval(Args&&...) { return true; }
template<typename... Args> template<typename... Args>
static inline bool eval_or(Args&&...) { return false; } static inline bool eval_or(Args&&...) { return false; }
......
...@@ -243,7 +243,15 @@ struct tl_find_if ...@@ -243,7 +243,15 @@ struct tl_find_if
// list first_n(size_t) // list first_n(size_t)
template<size_t N, class List, typename... T> template<size_t N, class List, typename... T>
struct tl_first_n_impl; struct tl_first_n_impl
{
typedef typename tl_first_n_impl<
N - 1,
typename List::tail,
T..., typename List::head
>::type
type;
};
template<class List, typename... T> template<class List, typename... T>
struct tl_first_n_impl<0, List, T...> struct tl_first_n_impl<0, List, T...>
...@@ -251,12 +259,6 @@ struct tl_first_n_impl<0, List, T...> ...@@ -251,12 +259,6 @@ struct tl_first_n_impl<0, List, T...>
typedef type_list<T...> type; typedef type_list<T...> type;
}; };
template<size_t N, typename L0, typename... L, typename... T>
struct tl_first_n_impl<N, type_list<L0, L...>, T...>
{
typedef typename tl_first_n_impl<N-1, type_list<L...>, T..., L0>::type type;
};
/** /**
* @brief Creates a new list from the first @p N elements of @p List. * @brief Creates a new list from the first @p N elements of @p List.
*/ */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment