Commit c1d882fb authored by neverlord's avatar neverlord

apply_tuple

parent 04c83d3c
......@@ -168,6 +168,7 @@ nobase_library_include_HEADERS = \
cppa/tuple_view.hpp \
cppa/uniform_type_info.hpp \
cppa/util/abstract_uniform_type_info.hpp \
cppa/util/apply_tuple.hpp \
cppa/util/arg_match_t.hpp \
cppa/util/at.hpp \
cppa/util/callable_trait.hpp \
......@@ -192,6 +193,8 @@ nobase_library_include_HEADERS = \
cppa/util/is_forward_iterator.hpp \
cppa/util/is_iterable.hpp \
cppa/util/is_legal_tuple_type.hpp \
cppa/util/is_manipulator.hpp \
cppa/util/is_mutable_ref.hpp \
cppa/util/is_one_of.hpp \
cppa/util/is_primitive.hpp \
cppa/util/option.hpp \
......
......@@ -249,3 +249,6 @@ cppa/util/tbind.hpp
cppa/util/option.hpp
cppa/tuple_cast.hpp
cppa/detail/matches.hpp
cppa/util/is_mutable_ref.hpp
cppa/util/is_manipulator.hpp
cppa/util/apply_tuple.hpp
......@@ -56,9 +56,6 @@ class any_tuple
template<typename... Args>
any_tuple(tuple<Args...> const& t) : m_vals(t.vals()) { }
template<typename... Args>
any_tuple(tuple_view<Args...> const& t) : m_vals(t.vals()) { }
explicit any_tuple(detail::abstract_tuple*);
any_tuple(any_tuple&&);
......
......@@ -48,7 +48,7 @@
namespace cppa {
template<typename... MatchRules>
typename tuple_view_type_from_type_list<typename util::lt_filter_not<util::type_list<MatchRules...>, util::tbind<std::is_same, anything>::type>::type>::type
typename tuple_view_type_from_type_list<typename util::tl_filter_not<util::type_list<MatchRules...>, util::tbind<std::is_same, anything>::type>::type>::type
get_view(any_tuple const& ut)
{
pattern<MatchRules...> p;
......
......@@ -103,7 +103,7 @@ class invoke_rule_builder
std::unique_ptr<pattern_type> m_ptr;
typedef typename pattern_type::tuple_view_type tuple_view_type;
typedef typename tuple_view_type_from_type_list<typename pattern_type::filtered_types>::type tuple_view_type;
template<typename F>
invoke_rules cr_rules(F&& f, std::integral_constant<bool, true>)
......@@ -122,7 +122,10 @@ class invoke_rule_builder
typedef typename tl_apply<raw_types,rm_ref>::type new_types;
typedef typename tl_concat<converted_types,new_types>::type types;
typedef typename pattern_from_type_list<types>::type epattern;
typedef typename epattern::tuple_view_type tuple_view_type;
//typedef typename epattern::tuple_view_type tuple_view_type;
typedef typename tuple_view_type_from_type_list<typename epattern::filtered_types>::type tuple_view_type;
typedef invokable_impl<tuple_view_type, epattern, F> impl;
std::unique_ptr<epattern> pptr(extend_pattern<epattern>(m_ptr.get()));
return invokable_ptr(new impl(std::move(pptr), std::forward<F>(f)));
......@@ -164,7 +167,10 @@ class on_the_fly_invoke_rule_builder
static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_types,rm_ref>::type types;
typedef typename pattern_from_type_list<types>::type pattern_type;
typedef typename pattern_type::tuple_view_type tuple_view_type;
//typedef typename pattern_type::tuple_view_type tuple_view_type;
typedef typename tuple_view_type_from_type_list<typename pattern_type::filtered_types>::type tuple_view_type;
typedef invokable_impl<tuple_view_type, pattern_type, F> impl;
std::unique_ptr<pattern_type> pptr(new pattern_type);
return invokable_ptr(new impl(std::move(pptr), std::forward<F>(f)));
......
......@@ -42,6 +42,7 @@
#include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/arg_match_t.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/tdata.hpp"
......@@ -49,10 +50,16 @@
namespace cppa {
template<class ExtendedType, class BasicType>
ExtendedType* extend_pattern(BasicType const* p);
template<typename... Types>
class pattern
{
template<class ExtendedType, class BasicType>
friend ExtendedType* extend_pattern(BasicType const* p);
static_assert(sizeof...(Types) > 0, "empty pattern");
pattern(pattern const&) = delete;
......@@ -64,13 +71,10 @@ class pattern
typedef util::type_list<Types...> types;
typedef typename util::lt_filter_not<types, util::tbind<std::is_same, anything>::type>::type
typedef typename util::tl_filter_not<types, util::tbind<std::is_same, anything>::type>::type
filtered_types;
typedef typename tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type;
typedef typename tuple_view_type::mapping_vector mapping_vector;
typedef util::fixed_vector<size_t, filtered_types::size> mapping_vector;
class const_iterator
{
......@@ -150,6 +154,8 @@ class pattern
}
}
private:
detail::tdata<Types...> m_data;
static detail::types_array<Types...> m_utis;
void const* m_data_ptr[size];
......
......@@ -55,9 +55,6 @@ template<typename... ElementTypes>
class tuple_view
{
//static_assert(sizeof...(ElementTypes) > 0,
// "could not declare an empty tuple_view");
template<size_t N, typename... Types>
friend typename util::at<N, Types...>::type& get_ref(tuple_view<Types...>&);
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 APPLY_TUPLE_HPP
#define APPLY_TUPLE_HPP
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/is_manipulator.hpp"
#include "cppa/util/callable_trait.hpp"
namespace cppa { namespace util {
template<size_t... Range>
struct apply_tuple_impl
{
template<typename F, template<typename...> class Tuple, typename... T>
static auto apply(F&& f, Tuple<T...> const& args,
typename disable_if<is_manipulator<F>, int>::type = 0)
-> typename get_result_type<F>::type
{
return f(get<Range>(args)...);
}
template<typename F, template<typename...> class Tuple, typename... T>
static auto apply(F&& f, Tuple<T...>& args,
typename enable_if<is_manipulator<F>, int>::type = 0)
-> typename get_result_type<F>::type
{
return f(get_ref<Range>(args)...);
}
};
template<int From, int To, int... Args>
struct apply_tuple_util : apply_tuple_util<From, To-1, To, Args...>
{
};
template<int X, int... Args>
struct apply_tuple_util<X, X, Args...> : apply_tuple_impl<X, Args...>
{
};
template<typename F, template<typename...> class Tuple, typename... T>
auto apply_tuple(F&& fun, Tuple<T...>& tup)
-> typename get_result_type<F>::type
{
typedef typename get_arg_types<F>::types fun_args;
static constexpr size_t tup_size = sizeof...(T);
static_assert(tup_size >= fun_args::size,
"cannot conjure up additional arguments");
static constexpr size_t from = tup_size - fun_args::size;
static constexpr size_t to = tup_size - 1;
return apply_tuple_util<from, to>::apply(std::forward<F>(fun), tup);
}
template<typename F, template<typename...> class Tuple, typename... T>
auto apply_tuple(F&& fun, Tuple<T...> const& tup)
-> typename get_result_type<F>::type
{
typedef typename get_arg_types<F>::types fun_args;
static constexpr size_t tup_size = sizeof...(T);
static_assert(tup_size >= fun_args::size,
"cannot conjure up additional arguments");
static constexpr size_t from = tup_size - fun_args::size;
static constexpr size_t to = tup_size - 1;
return apply_tuple_util<from, to>::apply(std::forward<F>(fun), tup);
}
} } // namespace cppa::util
#endif // APPLY_TUPLE_HPP
......@@ -33,6 +33,7 @@
#include <type_traits>
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
......@@ -40,6 +41,7 @@ namespace cppa { namespace util {
template<typename Signature>
struct callable_trait;
// member function pointer (const)
template<class C, typename ResultType, typename... Args>
struct callable_trait<ResultType (C::*)(Args...) const>
{
......@@ -47,6 +49,7 @@ struct callable_trait<ResultType (C::*)(Args...) const>
typedef type_list<Args...> arg_types;
};
// member function pointer
template<class C, typename ResultType, typename... Args>
struct callable_trait<ResultType (C::*)(Args...)>
{
......@@ -54,6 +57,7 @@ struct callable_trait<ResultType (C::*)(Args...)>
typedef type_list<Args...> arg_types;
};
// good ol' function
template<typename ResultType, typename... Args>
struct callable_trait<ResultType (Args...)>
{
......@@ -61,6 +65,7 @@ struct callable_trait<ResultType (Args...)>
typedef type_list<Args...> arg_types;
};
// good ol' function pointer
template<typename ResultType, typename... Args>
struct callable_trait<ResultType (*)(Args...)>
{
......@@ -77,21 +82,37 @@ struct get_callable_trait_helper
template<typename C>
struct get_callable_trait_helper<false, false, C>
{
// assuming functor
typedef callable_trait<decltype(&C::operator())> type;
};
template<typename C>
struct get_callable_trait
{
typedef typename rm_ref<C>::type fun_type;
typedef typename
get_callable_trait_helper<
( std::is_function<C>::value
|| std::is_function<typename std::remove_pointer<C>::type>::value),
std::is_member_function_pointer<C>::value,
C>::type
( std::is_function<fun_type>::value
|| std::is_function<typename std::remove_pointer<fun_type>::type>::value),
std::is_member_function_pointer<fun_type>::value,
fun_type>::type
type;
};
template<typename C>
struct get_arg_types
{
typedef typename get_callable_trait<C>::type trait_type;
typedef typename trait_type::arg_types types;
};
template<typename C>
struct get_result_type
{
typedef typename get_callable_trait<C>::type trait_type;
typedef typename trait_type::result_type type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_CALLABLE_TRAIT
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 IS_MANIPULATOR_HPP
#define IS_MANIPULATOR_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_mutable_ref.hpp"
#include "cppa/util/callable_trait.hpp"
namespace cppa { namespace util {
// A manipulator is a function that manipulates its arguments via
// mutable references.
template<typename F>
struct is_manipulator
{
static constexpr bool value =
tl_exists<typename get_arg_types<F>::types, is_mutable_ref>::value;
};
} } // namespace cppa::util
#endif // IS_MANIPULATOR_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 IS_MUTABLE_REF_HPP
#define IS_MUTABLE_REF_HPP
namespace cppa { namespace util {
template<typename T>
struct is_mutable_ref
{
static constexpr bool value = false;
};
template<typename T>
struct is_mutable_ref<T const&>
{
static constexpr bool value = false;
};
template<typename T>
struct is_mutable_ref<T&>
{
static constexpr bool value = true;
};
} } // namespace cppa::util
#endif // IS_MUTABLE_REF_HPP
......@@ -192,6 +192,23 @@ struct tl_forall<type_list<>, Predicate>
static constexpr bool value = true;
};
/**
* @brief Tests whether a predicate holds for some of the elements of a list.
*/
template<class List, template <typename> class Predicate>
struct tl_exists
{
static constexpr bool value =
Predicate<typename List::head>::value
|| tl_exists<typename List::tail, Predicate>::value;
};
template<template <typename> class Predicate>
struct tl_exists<type_list<>, Predicate>
{
static constexpr bool value = false;
};
// bool list::zipped_forall(predicate)
/**
......@@ -226,15 +243,6 @@ struct tl_concat<type_list<ListATypes...>, type_list<ListBTypes...> >
typedef type_list<ListATypes..., ListBTypes...> type;
};
template<class List, typename Element>
struct tl_prepend;
template<typename E0, typename... E>
struct tl_prepend<type_list<E...>, E0>
{
typedef type_list<E0, E...> type;
};
// list list::appy(trait)
/**
......@@ -280,17 +288,17 @@ struct tl_pop_back
// type list::at(size_t)
template<size_t N, typename... E>
struct lt_at_impl;
struct tl_at_impl;
template<size_t N, typename E0, typename... E>
struct lt_at_impl<N, E0, E...>
struct tl_at_impl<N, E0, E...>
{
typedef typename lt_at_impl<N-1, E...>::type type;
typedef typename tl_at_impl<N-1, E...>::type type;
};
template<typename E0, typename... E>
struct lt_at_impl<0, E0, E...>
struct tl_at_impl<0, E0, E...>
{
typedef E0 type;
};
......@@ -299,13 +307,13 @@ struct lt_at_impl<0, E0, E...>
* @brief Gets element at index @p N of @p List.
*/
template<class List, size_t N>
struct lt_at;
struct tl_at;
template<size_t N, typename... E>
struct lt_at<type_list<E...>, N>
struct tl_at<type_list<E...>, N>
{
static_assert(N < sizeof...(E), "N >= List::size");
typedef typename lt_at_impl<N, E...>::type type;
typedef typename tl_at_impl<N, E...>::type type;
};
// list list::prepend(type)
......@@ -314,10 +322,10 @@ struct lt_at<type_list<E...>, N>
* @brief Creates a new list with @p What prepended to @p List.
*/
template<class List, typename What>
struct lt_prepend;
struct tl_prepend;
template<typename What, typename... T>
struct lt_prepend<type_list<T...>, What>
struct tl_prepend<type_list<T...>, What>
{
typedef type_list<What, T...> type;
};
......@@ -326,36 +334,36 @@ struct lt_prepend<type_list<T...>, What>
// list list::filter(predicate)
template<class List, bool... Selected>
struct lt_filter_impl;
struct tl_filter_impl;
template<>
struct lt_filter_impl< type_list<> >
struct tl_filter_impl< type_list<> >
{
typedef type_list<> type;
};
template<typename T0, typename... T, bool... S>
struct lt_filter_impl<type_list<T0, T...>, false, S...>
struct tl_filter_impl<type_list<T0, T...>, false, S...>
{
typedef typename lt_filter_impl<type_list<T...>, S...>::type type;
typedef typename tl_filter_impl<type_list<T...>, S...>::type type;
};
template<typename T0, typename... T, bool... S>
struct lt_filter_impl<type_list<T0, T...>, true, S...>
struct tl_filter_impl<type_list<T0, T...>, true, S...>
{
typedef typename lt_prepend<typename lt_filter_impl<type_list<T...>, S...>::type, T0>::type type;
typedef typename tl_prepend<typename tl_filter_impl<type_list<T...>, S...>::type, T0>::type type;
};
/**
* @brief Create a new list containing all elements which satisfy @p Predicate.
*/
template<class List, template<typename> class Predicate>
struct lt_filter;
struct tl_filter;
template<template<typename> class Predicate, typename... T>
struct lt_filter<type_list<T...>, Predicate>
struct tl_filter<type_list<T...>, Predicate>
{
typedef typename lt_filter_impl<type_list<T...>, Predicate<T>::value...>::type type;
typedef typename tl_filter_impl<type_list<T...>, Predicate<T>::value...>::type type;
};
/**
......@@ -363,12 +371,12 @@ struct lt_filter<type_list<T...>, Predicate>
* do not satisfy @p Predicate.
*/
template<class List, template<typename> class Predicate>
struct lt_filter_not;
struct tl_filter_not;
template<template<typename> class Predicate, typename... T>
struct lt_filter_not<type_list<T...>, Predicate>
struct tl_filter_not<type_list<T...>, Predicate>
{
typedef typename lt_filter_impl<type_list<T...>, !Predicate<T>::value...>::type type;
typedef typename tl_filter_impl<type_list<T...>, !Predicate<T>::value...>::type type;
};
} } // namespace cppa::util
......
......@@ -12,8 +12,10 @@
#include "cppa/util/option.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/conjunction.hpp"
#include "cppa/util/is_primitive.hpp"
#include "cppa/util/is_mutable_ref.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
......@@ -47,6 +49,8 @@ struct match_helper
}
};
using namespace cppa::util;
match_helper match(any_tuple const& x)
{
......@@ -55,9 +59,6 @@ match_helper match(any_tuple const& x)
size_t test__pattern()
{
//std::vector<int> ivec = {1, 2, 3};
match(make_tuple(1,2,3))
(
on_arg_match >> [](int a, int b, int c)
......
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