Commit f360df15 authored by Dominik Charousset's avatar Dominik Charousset

pattern matching

parent cc1c3445
......@@ -78,7 +78,8 @@ class tpartial_function
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...);
}
......
......@@ -143,8 +143,8 @@ template<typename Result, typename F,
template<typename...> class Tuple, typename... T>
Result unchecked_apply_tuple(F&& fun, Tuple<T...>& tup)
{
return unchecked_apply_tuple_in_range<Result, 0, sizeof...(T) - 1>
(std::forward<F>(fun), tup);
return apply_tuple_util<Result, true, 0, sizeof...(T) - 1>
::apply(std::forward<F>(fun), tup);
}
} } // namespace cppa::util
......
......@@ -133,7 +133,8 @@ struct is_callable
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:
......
......@@ -76,8 +76,11 @@ bool compare_tuples(LhsTuple<LhsTypes...> const& lhs,
static_assert(sizeof...(LhsTypes) == sizeof...(RhsTypes),
"could not compare tuples of different size");
static_assert(tl_zipped_forall<type_list<type_pair<LhsTypes,RhsTypes>...>,
is_comparable>::value,
static_assert(tl_binary_forall<
type_list<LhsTypes...>,
type_list<RhsTypes...>,
is_comparable
>::value,
"types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(sizeof...(LhsTypes) - 1),
......@@ -90,20 +93,16 @@ template<template<typename...> class LhsTuple, typename... LhsTypes,
bool compare_first_elements(LhsTuple<LhsTypes...> const& lhs,
RhsTuple<RhsTypes...> const& rhs)
{
static constexpr size_t cmp_size = (sizeof...(LhsTypes) < sizeof...(RhsTypes))
? sizeof...(LhsTypes)
: sizeof...(RhsTypes);
typedef typename tl_zip<
util::type_list<LhsTypes...>,
util::type_list<RhsTypes...>
>::type
zipped_types;
typedef util::type_list<LhsTypes...> lhs_tlist;
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,
static_assert(tl_zipped_forall<zipped_types, is_comparable>::value,
"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...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
}
......
......@@ -101,7 +101,87 @@ struct is_type_list<type_list<Ts...> >
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.
......@@ -112,11 +192,11 @@ struct is_type_list<type_list<Ts...> >
*/
template<class ListA, class ListB,
template<typename, typename> class Fun = to_type_pair>
struct tl_zip;
struct tl_zip_impl;
template<typename... LhsElements, typename... RhsElements,
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) ==
sizeof...(RhsElements),
......@@ -124,6 +204,51 @@ struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...>, Fun>
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>
struct tl_unzip;
......@@ -240,102 +365,53 @@ struct tl_find_if
static constexpr int value = tl_find_impl<List, Predicate, Pos>::value;
};
// list first_n(size_t)
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;
};
// bool forall(predicate)
/**
* @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>
struct tl_first_n
{
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...>
template<class List, template<typename> class Predicate>
struct tl_forall
{
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>
struct tl_last_n_impl<TargetSize, Size, type_list<L0, L...>, T...>
template<template<typename> class Predicate>
struct tl_forall<type_list<>, Predicate>
{
typedef typename tl_last_n_impl<TargetSize, Size,
type_list<L...>, T..., L0>::type type;
static constexpr bool value = true;
};
/**
* @brief Creates a new list from the first @p N elements of @p List.
*/
template<class List, size_t N>
struct tl_last_n
template<class ListA, class ListB, template<typename, typename> class Predicate>
struct tl_forall2_impl
{
static_assert(List::size >= N, "List::size < N");
typedef typename tl_last_n_impl<N, List::size, List>::type type;
static constexpr bool value =
Predicate<typename ListA::head, typename ListB::head>::value
&& tl_forall2_impl<
typename ListA::tail,
typename ListB::tail,
Predicate
>::value;
};
template<class List>
struct tl_last_n<List, 0>
template<template<typename, typename> class Predicate>
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>
struct tl_forall
template<class ListA, class ListB, template<typename, typename> class Predicate>
struct tl_binary_forall
{
static constexpr bool value =
Predicate<class List::head>::value
&& tl_forall<class List::tail, Predicate>::value;
};
template<template<typename> class Predicate>
struct tl_forall<type_list<>, Predicate>
{
static constexpr bool value = true;
ListA::size == ListB::size
&& tl_forall2_impl<ListA, ListB, Predicate>::value;
};
/**
......@@ -677,7 +753,7 @@ struct tl_pad_right_impl;
template<class List, size_t OldSize, size_t NewSize, typename 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>
......@@ -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
* @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
{
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