Commit f360df15 authored by Dominik Charousset's avatar Dominik Charousset

pattern matching

parent cc1c3445
...@@ -78,7 +78,8 @@ class tpartial_function ...@@ -78,7 +78,8 @@ class tpartial_function
tpartial_function(tpartial_function const&) = default; tpartial_function(tpartial_function const&) = default;
bool defined_at(typename util::rm_ref<Args>::type const&... args) const //bool defined_at(typename util::rm_ref<Args>::type const&... args) const
bool defined_at(Args... args) const
{ {
return m_guard(args...); return m_guard(args...);
} }
......
...@@ -143,8 +143,8 @@ template<typename Result, typename F, ...@@ -143,8 +143,8 @@ template<typename Result, typename F,
template<typename...> class Tuple, typename... T> template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple(F&& fun, Tuple<T...>& tup) Result unchecked_apply_tuple(F&& fun, Tuple<T...>& tup)
{ {
return unchecked_apply_tuple_in_range<Result, 0, sizeof...(T) - 1> return apply_tuple_util<Result, true, 0, sizeof...(T) - 1>
(std::forward<F>(fun), tup); ::apply(std::forward<F>(fun), tup);
} }
} } // namespace cppa::util } } // namespace cppa::util
......
...@@ -133,7 +133,8 @@ struct is_callable ...@@ -133,7 +133,8 @@ struct is_callable
static void _fun(void*) { } static void _fun(void*) { }
typedef decltype(_fun(static_cast<T*>(nullptr))) result_type; typedef decltype(_fun(static_cast<typename rm_ref<T>::type*>(nullptr)))
result_type;
public: public:
......
...@@ -76,8 +76,11 @@ bool compare_tuples(LhsTuple<LhsTypes...> const& lhs, ...@@ -76,8 +76,11 @@ bool compare_tuples(LhsTuple<LhsTypes...> const& lhs,
static_assert(sizeof...(LhsTypes) == sizeof...(RhsTypes), static_assert(sizeof...(LhsTypes) == sizeof...(RhsTypes),
"could not compare tuples of different size"); "could not compare tuples of different size");
static_assert(tl_zipped_forall<type_list<type_pair<LhsTypes,RhsTypes>...>, static_assert(tl_binary_forall<
is_comparable>::value, type_list<LhsTypes...>,
type_list<RhsTypes...>,
is_comparable
>::value,
"types of lhs are not comparable to the types of rhs"); "types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(sizeof...(LhsTypes) - 1), return detail::cmp_helper<(sizeof...(LhsTypes) - 1),
...@@ -90,20 +93,16 @@ template<template<typename...> class LhsTuple, typename... LhsTypes, ...@@ -90,20 +93,16 @@ template<template<typename...> class LhsTuple, typename... LhsTypes,
bool compare_first_elements(LhsTuple<LhsTypes...> const& lhs, bool compare_first_elements(LhsTuple<LhsTypes...> const& lhs,
RhsTuple<RhsTypes...> const& rhs) RhsTuple<RhsTypes...> const& rhs)
{ {
static constexpr size_t cmp_size = (sizeof...(LhsTypes) < sizeof...(RhsTypes)) typedef typename tl_zip<
? sizeof...(LhsTypes) util::type_list<LhsTypes...>,
: sizeof...(RhsTypes); util::type_list<RhsTypes...>
>::type
zipped_types;
typedef util::type_list<LhsTypes...> lhs_tlist; static_assert(tl_zipped_forall<zipped_types, is_comparable>::value,
typedef util::type_list<RhsTypes...> rhs_tlist;
typedef typename tl_first_n<lhs_tlist, cmp_size>::type lhs_sublist;
typedef typename tl_first_n<rhs_tlist, cmp_size>::type rhs_sublist;
typedef typename tl_zip<lhs_sublist, rhs_sublist>::type zipped_sublists;
static_assert(tl_zipped_forall<zipped_sublists, is_comparable>::value,
"types of lhs are not comparable to the types of rhs"); "types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(cmp_size - 1), return detail::cmp_helper<(zipped_types::size - 1),
LhsTuple<LhsTypes...>, LhsTuple<LhsTypes...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs); RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
} }
......
...@@ -101,7 +101,87 @@ struct is_type_list<type_list<Ts...> > ...@@ -101,7 +101,87 @@ struct is_type_list<type_list<Ts...> >
static constexpr bool value = true; static constexpr bool value = true;
}; };
// static list zip(list, list) // list slice(size_t, size_t)
template<size_t LeftOffset, size_t Remaining,
typename PadType, class List, typename... T>
struct tl_slice_impl
{
typedef typename tl_slice_impl<
LeftOffset - 1,
Remaining,
PadType,
typename List::tail,
T...
>::type
type;
};
template<size_t Remaining, typename PadType, class List, typename... T>
struct tl_slice_impl<0, Remaining, PadType, List, T...>
{
typedef typename tl_slice_impl<
0,
Remaining - 1,
PadType,
typename List::tail,
T..., typename List::head
>::type
type;
};
template<size_t Remaining, typename PadType, typename... T>
struct tl_slice_impl<0, Remaining, PadType, type_list<>, T...>
{
typedef typename tl_slice_impl<
0,
Remaining - 1,
PadType,
type_list<>,
T..., PadType
>::type
type;
};
template<typename PadType, class List, typename... T>
struct tl_slice_impl<0, 0, PadType, List, T...>
{
typedef type_list<T...> type;
};
template<typename PadType, typename... T>
struct tl_slice_impl<0, 0, PadType, type_list<>, T...>
{
typedef type_list<T...> type;
};
template<class List, size_t ListSize, size_t First, size_t Last,
typename PadType = void_type>
struct tl_slice_
{
typedef typename tl_slice_impl<
First,
(Last - First),
PadType, List
>::type
type;
};
template<class List, size_t ListSize, typename PadType>
struct tl_slice_<List, ListSize, 0, ListSize, PadType>
{
typedef List type;
};
/**
* @brief Creates a new list from range (First, Last].
*/
template<class List, size_t First, size_t Last>
struct tl_slice
{
static_assert(First <= Last, "First > Last");
typedef typename tl_slice_<List, List::size, First, Last>::type type;
};
/** /**
* @brief Zips two lists of equal size. * @brief Zips two lists of equal size.
...@@ -112,11 +192,11 @@ struct is_type_list<type_list<Ts...> > ...@@ -112,11 +192,11 @@ struct is_type_list<type_list<Ts...> >
*/ */
template<class ListA, class ListB, template<class ListA, class ListB,
template<typename, typename> class Fun = to_type_pair> template<typename, typename> class Fun = to_type_pair>
struct tl_zip; struct tl_zip_impl;
template<typename... LhsElements, typename... RhsElements, template<typename... LhsElements, typename... RhsElements,
template<typename, typename> class Fun> template<typename, typename> class Fun>
struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...>, Fun> struct tl_zip_impl<type_list<LhsElements...>, type_list<RhsElements...>, Fun>
{ {
static_assert(sizeof...(LhsElements) == static_assert(sizeof...(LhsElements) ==
sizeof...(RhsElements), sizeof...(RhsElements),
...@@ -124,6 +204,51 @@ struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...>, Fun> ...@@ -124,6 +204,51 @@ struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...>, Fun>
typedef type_list<typename Fun<LhsElements, RhsElements>::type...> type; typedef type_list<typename Fun<LhsElements, RhsElements>::type...> type;
}; };
template<class ListA, class ListB,
template<typename, typename> class Fun = to_type_pair>
struct tl_zip
{
static constexpr size_t result_size =
(ListA::size < ListB::size) ? ListA::size
: ListB::size;
typedef typename tl_zip_impl<
typename tl_slice<ListA, 0, result_size>::type,
typename tl_slice<ListB, 0, result_size>::type,
Fun
>::type
type;
};
template<class ListA,
class ListB,
typename PadA = void_type,
typename PadB = void_type,
template<typename, typename> class Fun = to_type_pair>
struct tl_zip_all
{
static constexpr size_t result_size =
(ListA::size > ListB::size) ? ListA::size
: ListB::size;
typedef typename tl_zip_impl<
typename tl_slice_<
ListA,
ListA::size,
0,
result_size
>::type,
typename tl_slice_<
ListB,
ListB::size,
0,
result_size
>::type,
Fun
>::type
type;
};
template<class ListA> template<class ListA>
struct tl_unzip; struct tl_unzip;
...@@ -240,102 +365,53 @@ struct tl_find_if ...@@ -240,102 +365,53 @@ struct tl_find_if
static constexpr int value = tl_find_impl<List, Predicate, Pos>::value; static constexpr int value = tl_find_impl<List, Predicate, Pos>::value;
}; };
// list first_n(size_t) // bool forall(predicate)
template<size_t N, class List, typename... T>
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>
struct tl_first_n_impl<0, List, T...>
{
typedef type_list<T...> type;
};
/** /**
* @brief Creates a new list from the first @p N elements of @p List. * @brief Tests whether a predicate holds for all elements of a list.
*/ */
template<class List, size_t N> template<class List, template<typename> class Predicate>
struct tl_first_n struct tl_forall
{
static_assert(List::size >= N, "List::size < N");
typedef typename tl_first_n_impl<N, List>::type type;
};
template<class List>
struct tl_first_n<List, 0>
{
typedef type_list<> type;
};
// list last_n(size_t)
template<size_t TargetSize, size_t Size, class List, typename... T>
struct tl_last_n_impl;
template<size_t TargetSize, size_t Size, typename T0, typename... T>
struct tl_last_n_impl<TargetSize, Size, type_list<>, T0, T...>
{
typedef typename tl_last_n_impl<
TargetSize, Size-1,
type_list<>, T...
>::type
type;
};
template<size_t Size, typename... T>
struct tl_last_n_impl<Size, Size, type_list<>, T...>
{ {
typedef type_list<T...> type; static constexpr bool value =
Predicate<typename List::head>::value
&& tl_forall<typename List::tail, Predicate>::value;
}; };
template<size_t TargetSize, size_t Size, typename L0, typename... L, typename... T> template<template<typename> class Predicate>
struct tl_last_n_impl<TargetSize, Size, type_list<L0, L...>, T...> struct tl_forall<type_list<>, Predicate>
{ {
typedef typename tl_last_n_impl<TargetSize, Size, static constexpr bool value = true;
type_list<L...>, T..., L0>::type type;
}; };
/** template<class ListA, class ListB, template<typename, typename> class Predicate>
* @brief Creates a new list from the first @p N elements of @p List. struct tl_forall2_impl
*/
template<class List, size_t N>
struct tl_last_n
{ {
static_assert(List::size >= N, "List::size < N"); static constexpr bool value =
typedef typename tl_last_n_impl<N, List::size, List>::type type; Predicate<typename ListA::head, typename ListB::head>::value
&& tl_forall2_impl<
typename ListA::tail,
typename ListB::tail,
Predicate
>::value;
}; };
template<class List> template<template<typename, typename> class Predicate>
struct tl_last_n<List, 0> struct tl_forall2_impl<type_list<>, type_list<>, Predicate>
{ {
typedef type_list<> type; static constexpr bool value = true;
}; };
// bool forall(predicate)
/** /**
* @brief Tests whether a predicate holds for all elements of a list. * @brief Tests whether a binary predicate holds for all
* corresponding elements of @p ListA and @p ListB.
*/ */
template<class List, template<typename> class Predicate> template<class ListA, class ListB, template<typename, typename> class Predicate>
struct tl_forall struct tl_binary_forall
{ {
static constexpr bool value = static constexpr bool value =
Predicate<class List::head>::value ListA::size == ListB::size
&& tl_forall<class List::tail, Predicate>::value; && tl_forall2_impl<ListA, ListB, Predicate>::value;
};
template<template<typename> class Predicate>
struct tl_forall<type_list<>, Predicate>
{
static constexpr bool value = true;
}; };
/** /**
...@@ -677,7 +753,7 @@ struct tl_pad_right_impl; ...@@ -677,7 +753,7 @@ struct tl_pad_right_impl;
template<class List, size_t OldSize, size_t NewSize, typename FillType> template<class List, size_t OldSize, size_t NewSize, typename FillType>
struct tl_pad_right_impl<List, false, OldSize, NewSize, FillType> struct tl_pad_right_impl<List, false, OldSize, NewSize, FillType>
{ {
typedef typename tl_first_n<List, NewSize>::type type; typedef typename tl_slice<List, 0, NewSize>::type type;
}; };
template<class List, size_t Size, typename FillType> template<class List, size_t Size, typename FillType>
...@@ -703,7 +779,7 @@ struct tl_pad_right_impl<List, true, OldSize, NewSize, FillType> ...@@ -703,7 +779,7 @@ struct tl_pad_right_impl<List, true, OldSize, NewSize, FillType>
* @brief Resizes the list to contain @p NewSize elements and uses * @brief Resizes the list to contain @p NewSize elements and uses
* @p FillType to initialize the new elements with. * @p FillType to initialize the new elements with.
*/ */
template<class List, size_t NewSize, typename FillType> template<class List, size_t NewSize, typename FillType = void_type>
struct tl_pad_right struct tl_pad_right
{ {
typedef typename tl_pad_right_impl< typedef typename tl_pad_right_impl<
......
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