|
#pragma once |
|
|
|
// Copyright plasma-effect 2015 |
|
// Distributed under the Boost Software License, Version 1.0. |
|
// (See http://www.boost.org/LICENSE_1_0.txt) |
|
#include<tuple> |
|
#include<utility> |
|
#include<list> |
|
#include<memory> |
|
#include<vector> |
|
#include<type_traits> |
|
|
|
#include<boost/variant.hpp> |
|
|
|
#ifdef _MSC_VER |
|
#define PLASMA_ADT_TEMPLATE |
|
#else |
|
#define PLASMA_ADT_TEMPLATE template |
|
#endif |
|
|
|
namespace plasma_adt |
|
{ |
|
struct recursion_tag {}; |
|
namespace function_flag |
|
{ |
|
template<int N>struct function_flag_t |
|
{ |
|
static constexpr int flag = N; |
|
}; |
|
|
|
constexpr auto recursion_flag = function_flag_t<0b01>(); |
|
constexpr auto memoization_flag = function_flag_t<0b10>(); |
|
constexpr auto dual_flag = function_flag_t<0b11>(); |
|
constexpr auto no_option_flag = function_flag_t<0b00>(); |
|
|
|
template<int N, int M>constexpr auto operator+(function_flag_t<N>, function_flag_t<M>) |
|
{ |
|
return function_flag_t<(N | M)>(); |
|
} |
|
|
|
template<class>struct is_function_flag :std::false_type {}; |
|
template<>struct is_function_flag<function_flag_t<0>> :std::true_type {}; |
|
template<>struct is_function_flag<function_flag_t<1>> :std::true_type {}; |
|
template<>struct is_function_flag<function_flag_t<2>> :std::true_type {}; |
|
template<>struct is_function_flag<function_flag_t<3>> :std::true_type {}; |
|
template<class>struct is_tuple :std::false_type {}; |
|
template<class... Ts>struct is_tuple<std::tuple<Ts...>> :std::true_type {}; |
|
} |
|
|
|
|
|
template<class... Types>class data_type |
|
{ |
|
typedef std::tuple<Types...> template_parameter_tuple; |
|
template<std::size_t Id>using parameter_type = std::tuple_element_t<Id, template_parameter_tuple>; |
|
typedef data_type<Types...> this_type; |
|
template<class>struct container_t; |
|
typedef container_t<std::make_index_sequence<sizeof...(Types)>> container; |
|
typedef std::list<container> list_type; |
|
typedef typename list_type::const_iterator iterator_type; |
|
|
|
static list_type instances; |
|
iterator_type iterator_; |
|
data_type(iterator_type ite) :iterator_(ite) {} |
|
|
|
template<class T, class = void>struct value_data_t |
|
{ |
|
typedef T true_name; |
|
T value_; |
|
|
|
value_data_t(T const& v):value_(v){} |
|
value_data_t(value_data_t const&) = default; |
|
value_data_t(value_data_t&&) = default; |
|
value_data_t& operator=(value_data_t const&) = default; |
|
value_data_t& operator=(value_data_t&&) = default; |
|
~value_data_t() = default; |
|
|
|
T get_value()const |
|
{ |
|
return value_; |
|
} |
|
bool operator==(value_data_t<T>const& rhs)const |
|
{ |
|
return value_ == rhs.value_; |
|
} |
|
}; |
|
template<class T>struct value_data_t<T, std::enable_if_t<std::is_same<T, recursion_tag>::value>> |
|
{ |
|
typedef this_type true_name; |
|
iterator_type iterator_; |
|
|
|
value_data_t(true_name const& v) :iterator_(v.iterator_) {} |
|
value_data_t(value_data_t const&) = default; |
|
value_data_t(value_data_t&&) = default; |
|
value_data_t& operator=(value_data_t const&) = default; |
|
value_data_t& operator=(value_data_t&&) = default; |
|
~value_data_t() = default; |
|
|
|
this_type get_value()const |
|
{ |
|
return this_type(iterator_); |
|
} |
|
bool operator==(value_data_t<T>const& rhs)const |
|
{ |
|
return *iterator_ == *rhs.iterator_; |
|
} |
|
}; |
|
template<class T>using true_name = typename value_data_t<T>::true_name; |
|
|
|
template<std::size_t Id, class T>struct inside_data_t |
|
{ |
|
value_data_t<T> value_; |
|
|
|
inside_data_t(true_name<T> const& v) :value_(v) {} |
|
inside_data_t() = default; |
|
inside_data_t(inside_data_t const&) = default; |
|
inside_data_t(inside_data_t&&) = default; |
|
inside_data_t& operator=(inside_data_t const&) = default; |
|
inside_data_t& operator=(inside_data_t&&) = default; |
|
~inside_data_t() = default; |
|
|
|
template<class ReturnType, class Funcs> |
|
ReturnType function_call(Funcs const& funcs)const |
|
{ |
|
return std::get<Id>(funcs)(value_.get_value()); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion> |
|
ReturnType recursion_call(Funcs const& funcs, Recursion const& recur)const |
|
{ |
|
return std::get<Id>(funcs)(recur, value_.get_value()); |
|
} |
|
template<class ReturnType, class Funcs, class Tuple,std::size_t... Is> |
|
ReturnType function_call_with_argument(Funcs const& funcs, Tuple const& arg,std::index_sequence<Is...>)const |
|
{ |
|
return std::get<Id>(funcs)(value_.get_value(), std::get<Is>(arg)...); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion, class Tuple, std::size_t... Is> |
|
ReturnType recursion_call_with_argument(Funcs const& funcs,Recursion const& recur, Tuple const& arg, std::index_sequence<Is...>)const |
|
{ |
|
return std::get<Id>(funcs)(recur, value_.get_value(), std::get<Is>(arg)...); |
|
} |
|
|
|
bool operator==(inside_data_t<Id, T>const& rhs)const |
|
{ |
|
return value_ == rhs.value_; |
|
} |
|
}; |
|
template<std::size_t Id, class... Ts>struct inside_data_t<Id, std::tuple<Ts...>> |
|
{ |
|
std::tuple<value_data_t<Ts>...> value_; |
|
|
|
inside_data_t(true_name<Ts>const&... args) :value_(args...) {} |
|
inside_data_t() = default; |
|
inside_data_t(inside_data_t const&) = default; |
|
inside_data_t(inside_data_t&&) = default; |
|
inside_data_t& operator=(inside_data_t const&) = default; |
|
inside_data_t& operator=(inside_data_t&&) = default; |
|
~inside_data_t() = default; |
|
|
|
template<class>struct func_t; |
|
template<std::size_t... Is>struct func_t<std::index_sequence<Is...>> |
|
{ |
|
template<class ReturnType,class Funcs> |
|
static ReturnType function_call(std::tuple<value_data_t<Ts>...> const& v, Funcs const& funcs) |
|
{ |
|
return std::get<Id>(funcs)(std::get<Is>(v).get_value()...); |
|
} |
|
template<class ReturnType, class Funcs,class Recursion> |
|
static ReturnType recursion_call(std::tuple<value_data_t<Ts>...> const& v, Funcs const& funcs,Recursion const& recur) |
|
{ |
|
return std::get<Id>(funcs)(recur, std::get<Is>(v).get_value()...); |
|
} |
|
template<class ReturnType, class Funcs,class Tuple,std::size_t... Us> |
|
static ReturnType function_call_with_argument(std::tuple<value_data_t<Ts>...> const& v, Funcs const& funcs, Tuple const& arg, std::index_sequence<Us...>) |
|
{ |
|
return std::get<Id>(funcs)(std::get<Is>(v).get_value()..., std::get<Us>(arg)...); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion,class Tuple,std::size_t... Us> |
|
static ReturnType recursion_call_with_argument(std::tuple<value_data_t<Ts>...> const& v, Funcs const& funcs, Recursion const& recur, Tuple const& arg, std::index_sequence<Us...>) |
|
{ |
|
return std::get<Id>(funcs)(recur, std::get<Is>(v).get_value()..., std::get<Us>(arg)...); |
|
} |
|
}; |
|
typedef func_t<std::make_index_sequence<sizeof...(Ts)>> function_t; |
|
template<class ReturnType, class Funcs> |
|
ReturnType function_call(Funcs const& funcs)const |
|
{ |
|
return function_t::PLASMA_ADT_TEMPLATE function_call<ReturnType>(value_, funcs); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion> |
|
ReturnType recursion_call(Funcs const& funcs, Recursion const& recur)const |
|
{ |
|
return function_t::PLASMA_ADT_TEMPLATE recursion_call<ReturnType>(value_, funcs, recur); |
|
} |
|
template<class ReturnType, class Funcs, class Tuple, std::size_t... Is> |
|
ReturnType function_call_with_argument(Funcs const& funcs, Tuple const& arg, std::index_sequence<Is...>)const |
|
{ |
|
return function_t::PLASMA_ADT_TEMPLATE function_call_with_argument<ReturnType>(value_, funcs, arg, std::index_sequence<Is...>()); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion, class Tuple, std::size_t... Is> |
|
ReturnType recursion_call_with_argument(Funcs const& funcs, Recursion const& recur, Tuple const& arg, std::index_sequence<Is...>)const |
|
{ |
|
return function_t::PLASMA_ADT_TEMPLATE recursion_call_with_argument<ReturnType>(value_, funcs, recur, arg, std::index_sequence<Is...>()); |
|
} |
|
bool operator==(inside_data_t<Id, std::tuple<Ts...>>const& rhs)const |
|
{ |
|
return value_ == rhs.value_; |
|
} |
|
bool operator!=(inside_data_t<Id, std::tuple<Ts...>>const& rhs)const |
|
{ |
|
return !(value_ == rhs.value_); |
|
} |
|
|
|
}; |
|
template<std::size_t Id>struct inside_data_t<Id, void> |
|
{ |
|
inside_data_t() = default; |
|
inside_data_t(inside_data_t const&) = default; |
|
inside_data_t(inside_data_t&&) = default; |
|
inside_data_t& operator=(inside_data_t const&) = default; |
|
inside_data_t& operator=(inside_data_t&&) = default; |
|
~inside_data_t() = default; |
|
template<class ReturnType, class Funcs> |
|
|
|
ReturnType function_call(Funcs const& funcs)const |
|
{ |
|
return std::get<Id>(funcs)(); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion> |
|
ReturnType recursion_call(Funcs const& funcs, Recursion const& recur)const |
|
{ |
|
return std::get<Id>(funcs)(recur); |
|
} |
|
template<class ReturnType, class Funcs, class Tuple, std::size_t... Is> |
|
ReturnType function_call_with_argument(Funcs const& funcs, Tuple const& arg, std::index_sequence<Is...>)const |
|
{ |
|
return std::get<Id>(funcs)(std::get<Is>(arg)...); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion, class Tuple, std::size_t... Is> |
|
ReturnType recursion_call_with_argument(Funcs const& funcs, Recursion const& recur, Tuple const& arg, std::index_sequence<Is...>)const |
|
{ |
|
return std::get<Id>(funcs)(recur, std::get<Is>(arg)...); |
|
} |
|
bool operator==(inside_data_t<Id, void>const&)const |
|
{ |
|
return true; |
|
} |
|
}; |
|
|
|
template<std::size_t... Is>struct container_t<std::index_sequence<Is...>> |
|
{ |
|
boost::variant<inside_data_t<Is, Types>...> data_; |
|
template<class T>container_t(T const& v) :data_(v) {} |
|
container_t() = default; |
|
container_t(container_t const&) = default; |
|
container_t(container_t&&) = default; |
|
container_t& operator=(container_t const&) = default; |
|
container_t& operator=(container_t&&) = default; |
|
~container_t() = default; |
|
|
|
template<class ReturnType, class Funcs>ReturnType function_call(Funcs const& funcs)const |
|
{ |
|
return boost::apply_visitor([&](auto const&v) {return v.PLASMA_ADT_TEMPLATE function_call<ReturnType>(funcs);}, data_); |
|
} |
|
template<class ReturnType, class Funcs, class Recursion>ReturnType recursion_call(Funcs const& funcs, Recursion const& recur)const |
|
{ |
|
return boost::apply_visitor([&](auto const&v) {return v.PLASMA_ADT_TEMPLATE recursion_call<ReturnType>(funcs, recur);}, data_); |
|
} |
|
template<class ReturnType, class Funcs,class Tuple>ReturnType function_call_with_argument(Funcs const& funcs,Tuple const& arg)const |
|
{ |
|
return boost::apply_visitor([&](auto const&v) {return v.PLASMA_ADT_TEMPLATE function_call_with_argument<ReturnType>(funcs, arg, std::make_index_sequence<std::tuple_size<Tuple>::value>());}, data_); |
|
} |
|
template<class ReturnType, class Funcs,class Recursion,class Tuple>ReturnType recursion_call_with_argument(Funcs const& funcs, Recursion const& recur,Tuple const& arg)const |
|
{ |
|
return boost::apply_visitor([&](auto const&v) {return v.PLASMA_ADT_TEMPLATE |
|
recursion_call_with_argument<ReturnType>(funcs, recur, arg, std::make_index_sequence<std::tuple_size<Tuple>::value>());}, data_); |
|
} |
|
bool operator==(container_t<std::index_sequence<Is...>> const& rhs)const |
|
{ |
|
return data_ == rhs.data_; |
|
} |
|
}; |
|
public: |
|
template<std::size_t Id, class T>struct instance_t |
|
{ |
|
static this_type run(true_name<T>const& v) |
|
{ |
|
instances.emplace_back(inside_data_t<Id, T>(v)); |
|
return this_type(std::prev(instances.end())); |
|
} |
|
}; |
|
template<std::size_t Id, class... Ts>struct instance_t<Id, std::tuple<Ts...>> |
|
{ |
|
static this_type run(true_name<Ts>const&... v) |
|
{ |
|
instances.emplace_back(inside_data_t<Id, std::tuple<Ts...>>(v...)); |
|
return this_type(std::prev(instances.end())); |
|
} |
|
}; |
|
template<std::size_t Id>struct instance_t<Id, void> |
|
{ |
|
static this_type run() |
|
{ |
|
instances.emplace_back(inside_data_t<Id, void>()); |
|
return this_type(std::prev(instances.end())); |
|
} |
|
}; |
|
template<std::size_t Id>using instance_type = instance_t<Id, parameter_type<Id>>; |
|
template<std::size_t Id>static auto get_instance_function() |
|
{ |
|
return instance_type<Id>::run; |
|
} |
|
|
|
data_type(data_type const&) = default; |
|
data_type(data_type&&) = default; |
|
data_type& operator=(data_type const&) = default; |
|
data_type& operator=(data_type&&) = default; |
|
|
|
bool operator==(this_type const& rhs)const |
|
{ |
|
return *iterator_ == *rhs.iterator_; |
|
} |
|
|
|
template<class ReturnType, class Funcs>struct pattern_match_t |
|
{ |
|
Funcs funcs; |
|
ReturnType operator()(this_type const& v)const |
|
{ |
|
return v.iterator_->PLASMA_ADT_TEMPLATE function_call<ReturnType>(funcs); |
|
} |
|
}; |
|
template<class ReturnType, class Funcs>struct recursion_match_t |
|
{ |
|
Funcs funcs; |
|
ReturnType operator()(this_type const& v)const |
|
{ |
|
return v.iterator_->PLASMA_ADT_TEMPLATE recursion_call<ReturnType>(funcs, std::cref(*this)); |
|
} |
|
}; |
|
template<class ReturnType, class Tuple, class Funcs>struct pattern_match_with_argument_t; |
|
template<class ReturnType, class Funcs, class... Ts>struct pattern_match_with_argument_t<ReturnType, std::tuple<Ts...>, Funcs> |
|
{ |
|
Funcs funcs; |
|
ReturnType operator()(this_type const& v, Ts const&... args)const |
|
{ |
|
return v.iterator_->PLASMA_ADT_TEMPLATE function_call_with_argument<ReturnType>(funcs, std::make_tuple(std::cref(args)...)); |
|
} |
|
}; |
|
template<class ReturnType, class Tuple, class Funcs>struct recursion_match_with_argument_t; |
|
template<class ReturnType, class Funcs, class... Ts>struct recursion_match_with_argument_t<ReturnType, std::tuple<Ts...>, Funcs> |
|
{ |
|
Funcs funcs; |
|
ReturnType operator()(this_type const& v, Ts const&... args)const |
|
{ |
|
return v.iterator_->PLASMA_ADT_TEMPLATE recursion_call_with_argument<ReturnType>(funcs, std::cref(*this), std::make_tuple(std::cref(args)...)); |
|
} |
|
}; |
|
|
|
template<class ReturnType, class Funcs>struct memoization_pattern_match_t |
|
{ |
|
Funcs funcs; |
|
std::shared_ptr<std::vector<std::pair<container, ReturnType>>> data_ptr_; |
|
ReturnType operator()(this_type const& arg)const |
|
{ |
|
for (auto const& d : *data_ptr_) |
|
{ |
|
if (d.first == *arg.iterator_) |
|
{ |
|
return d.second; |
|
} |
|
} |
|
auto ret = arg.iterator_->PLASMA_ADT_TEMPLATE function_call<ReturnType>(funcs); |
|
data_ptr_->emplace_back(*arg.iterator_, ret); |
|
return ret; |
|
} |
|
}; |
|
template<class ReturnType, class Funcs>struct memoization_recursion_match_t |
|
{ |
|
Funcs funcs; |
|
std::shared_ptr<std::vector<std::pair<container, ReturnType>>> data_ptr_; |
|
ReturnType operator()(this_type const& arg)const |
|
{ |
|
for (auto const& d : *data_ptr_) |
|
{ |
|
if (d.first == *arg.iterator_) |
|
{ |
|
return d.second; |
|
} |
|
} |
|
auto ret = arg.iterator_->PLASMA_ADT_TEMPLATE recursion_call<ReturnType>(funcs, std::cref(*this)); |
|
data_ptr_->emplace_back(*arg.iterator_, ret); |
|
return ret; |
|
} |
|
}; |
|
template<class ReturnType, class Tuple>struct make_shared_t; |
|
template<class ReturnType, class... Ts>struct make_shared_t<ReturnType, std::tuple<Ts...>> |
|
{ |
|
static auto run() |
|
{ |
|
return std::make_shared<std::vector<std::pair<std::tuple<container, Ts...>, ReturnType>>>(); |
|
} |
|
}; |
|
template<class ReturnType, class Tuple, class Funcs>struct memoization_pattern_match_with_argument_t; |
|
template<class ReturnType, class Funcs, class... Ts>struct memoization_pattern_match_with_argument_t<ReturnType, std::tuple<Ts...>, Funcs> |
|
{ |
|
Funcs funcs; |
|
std::shared_ptr<std::vector<std::pair<std::tuple<container, Ts...>, ReturnType>>> data_ptr_; |
|
ReturnType operator()(this_type const& v, Ts const&... args)const |
|
{ |
|
auto t = std::make_tuple(*v.iterator_, args...); |
|
for (auto const& d : *data_ptr_) |
|
{ |
|
if (t == d.first) |
|
{ |
|
return d.second; |
|
} |
|
} |
|
auto ret = v.iterator_->PLASMA_ADT_TEMPLATE function_call_with_argument<ReturnType>(funcs, std::make_tuple(std::cref(args)...)); |
|
data_ptr_->emplace_back(t, ret); |
|
return ret; |
|
} |
|
}; |
|
template<class ReturnType, class Tuple, class Funcs>struct memoization_recursion_match_with_argument_t; |
|
template<class ReturnType, class Funcs, class... Ts>struct memoization_recursion_match_with_argument_t<ReturnType, std::tuple<Ts...>, Funcs> |
|
{ |
|
Funcs funcs; |
|
std::shared_ptr<std::vector<std::pair<std::tuple<container, Ts...>, ReturnType>>> data_ptr_; |
|
ReturnType operator()(this_type const& v, Ts const&... args)const |
|
{ |
|
auto t = std::make_tuple(*v.iterator_, args...); |
|
for (auto const& d : *data_ptr_) |
|
{ |
|
if (t == d.first) |
|
{ |
|
return d.second; |
|
} |
|
} |
|
auto ret = v.iterator_->PLASMA_ADT_TEMPLATE recursion_call_with_argument<ReturnType>(funcs, std::cref(*this), std::make_tuple(std::cref(args)...)); |
|
data_ptr_->emplace_back(t, ret); |
|
return ret; |
|
} |
|
}; |
|
private: |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b00>* = nullptr) |
|
{ |
|
return pattern_match_t<ReturnType, Funcs>{funcs}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b01>* = nullptr) |
|
{ |
|
return recursion_match_t<ReturnType, Funcs>{funcs}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b10>* = nullptr) |
|
{ |
|
return memoization_pattern_match_t<ReturnType, Funcs>{funcs, std::make_shared<std::vector<std::pair<container, ReturnType>>>()}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b11>* = nullptr) |
|
{ |
|
return memoization_recursion_match_t<ReturnType, Funcs>{funcs, std::make_shared<std::vector<std::pair<container, ReturnType>>>()}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function_with(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b00>* = nullptr) |
|
{ |
|
return pattern_match_with_argument_t<ReturnType, ArgumentTuple, Funcs>{funcs}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function_with(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b01>* = nullptr) |
|
{ |
|
return recursion_match_with_argument_t<ReturnType, ArgumentTuple, Funcs>{funcs}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function_with(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b10>* = nullptr) |
|
{ |
|
return memoization_pattern_match_with_argument_t<ReturnType, ArgumentTuple, Funcs>{funcs, make_shared_t<ReturnType, ArgumentTuple>::run()}; |
|
} |
|
template<class ReturnType, class FunctionFlag, class ArgumentTuple, class Funcs> |
|
static auto make_function_with(Funcs const& funcs, std::enable_if_t<FunctionFlag::flag == 0b11>* = nullptr) |
|
{ |
|
return memoization_recursion_match_with_argument_t<ReturnType, ArgumentTuple, Funcs>{funcs, make_shared_t<ReturnType, ArgumentTuple>::run()}; |
|
} |
|
public: |
|
template<class ReturnType, class ArgumentTuple, class FunctionFlag, class... Funcs>static auto make_pattern_match(FunctionFlag const&, Funcs const&... funcs) |
|
->typename std::enable_if< |
|
function_flag::is_function_flag<FunctionFlag>::value&&function_flag::is_tuple<ArgumentTuple>::value |
|
, decltype(make_function_with<ReturnType, FunctionFlag, ArgumentTuple>(std::make_tuple(funcs...)))>::type |
|
{ |
|
return make_function_with<ReturnType, FunctionFlag, ArgumentTuple>(std::make_tuple(funcs...)); |
|
} |
|
template<class ReturnType, class ArgumentTuple,class F, class... Funcs>static auto make_pattern_match(F const& func, Funcs const&... funcs) |
|
->typename std::enable_if< |
|
function_flag::is_tuple<ArgumentTuple>::value && !function_flag::is_function_flag<F>::value |
|
, decltype(make_function_with<ReturnType, function_flag::function_flag_t<0b00>, ArgumentTuple>(std::make_tuple(func, funcs...)))>::type |
|
{ |
|
return make_function_with<ReturnType, function_flag::function_flag_t<0b00>, ArgumentTuple>(std::make_tuple(func, funcs...)); |
|
} |
|
template<class ReturnType, class FunctionFlag, class... Funcs>static auto make_pattern_match(FunctionFlag const&, Funcs const&... funcs) |
|
->typename std::enable_if< |
|
function_flag::is_function_flag<FunctionFlag>::value |
|
, decltype(make_function<ReturnType, FunctionFlag, std::tuple<void>>(std::make_tuple(funcs...)))>::type |
|
{ |
|
return make_function<ReturnType, FunctionFlag, std::tuple<void>>(std::make_tuple(funcs...)); |
|
} |
|
template<class ReturnType,class F, class... Funcs>static auto make_pattern_match(F const& func, Funcs const&... funcs) |
|
->typename std::enable_if< |
|
!function_flag::is_function_flag<F>::value |
|
,decltype(make_function<ReturnType, function_flag::function_flag_t<0b00>, std::tuple<void>>(std::make_tuple(func, funcs...)))>::type |
|
{ |
|
return make_function<ReturnType, function_flag::function_flag_t<0b00>, std::tuple<void>>(std::make_tuple(func, funcs...)); |
|
} |
|
|
|
}; |
|
template<class... Types>typename data_type<Types...>::list_type data_type<Types...>::instances; |
|
} |