mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-08-03 12:49:50 +00:00
SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION をデフォルトで有効に変更
sprout/type/string.hpp 追加
This commit is contained in:
parent
86073fea83
commit
231910c863
43 changed files with 4816 additions and 16 deletions
926
sprout/breed/traits.hpp
Normal file
926
sprout/breed/traits.hpp
Normal file
|
@ -0,0 +1,926 @@
|
|||
#ifndef SPROUT_BREED_TRAITS_HPP
|
||||
#define SPROUT_BREED_TRAITS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/utility/pack.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/breed/breed_fwd.hpp>
|
||||
#include <sprout/breed/args.hpp>
|
||||
#include <sprout/breed/domain.hpp>
|
||||
#include <sprout/breed/transform/pass_through.hpp>
|
||||
#include <sprout/breed/detail/template_arity.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace breed {
|
||||
namespace detail {
|
||||
template<typename T, typename Void = void>
|
||||
struct if_vararg {};
|
||||
template<typename T>
|
||||
struct if_vararg<T, typename T::breed_is_vararg_>
|
||||
: public T
|
||||
{};
|
||||
|
||||
template<typename T, typename Void = void>
|
||||
struct is_callable2_
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_callable2_<T, typename T::breed_is_callable_>
|
||||
: public std::true_type
|
||||
{};
|
||||
template<typename T, long Arity = sprout::breed::detail::template_arity<T>::value>
|
||||
struct is_callable_
|
||||
: public sprout::breed::detail::is_callable2_<T>
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// is_callable
|
||||
//
|
||||
template<typename T>
|
||||
struct is_callable
|
||||
: public sprout::breed::detail::is_callable_<T>
|
||||
{};
|
||||
template<>
|
||||
struct is_callable<sprout::breed::_>
|
||||
: public std::true_type
|
||||
{};
|
||||
template<>
|
||||
struct is_callable<sprout::breed::callable>
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename PrimitiveTransform, typename X>
|
||||
struct is_callable<sprout::breed::transform<PrimitiveTransform, X> >
|
||||
: public std::false_type
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename Void>
|
||||
struct is_transform_
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_transform_<T, typename T::breed_is_transform_>
|
||||
: public std::true_type
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// is_transform
|
||||
//
|
||||
template<typename T>
|
||||
struct is_transform
|
||||
: public sprout::breed::detail::is_transform_<T>
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename Void>
|
||||
struct is_aggregate_
|
||||
: public std::is_pod<T>
|
||||
{};
|
||||
template<typename Tag, typename Args, long N>
|
||||
struct is_aggregate_<sprout::breed::expr<Tag, Args, N>, void>
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename Tag, typename Args, long N>
|
||||
struct is_aggregate_<sprout::breed::basic_expr<Tag, Args, N>, void>
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_aggregate_<T, typename T::breed_is_aggregate_>
|
||||
: public std::true_type
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// is_transform
|
||||
//
|
||||
template<typename T>
|
||||
struct is_aggregate
|
||||
: public sprout::breed::detail::is_aggregate_<T>
|
||||
{};
|
||||
|
||||
//
|
||||
// is_transform
|
||||
//
|
||||
template<typename T, typename Void>
|
||||
struct is_expr
|
||||
: public std::false_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_expr<T, typename T::breed_is_expr_>
|
||||
: public std::true_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_expr<T&, void>
|
||||
: public is_expr<T>
|
||||
{};
|
||||
|
||||
//
|
||||
// tag_of
|
||||
//
|
||||
template<typename Expr>
|
||||
struct tag_of {
|
||||
public:
|
||||
typedef typename Expr::breed_tag type;
|
||||
};
|
||||
template<typename Expr>
|
||||
struct tag_of<Expr&> {
|
||||
public:
|
||||
typedef typename Expr::breed_tag type;
|
||||
};
|
||||
|
||||
//
|
||||
// arity_of
|
||||
//
|
||||
template<typename Expr>
|
||||
struct arity_of
|
||||
: public Expr::breed_arity
|
||||
{};
|
||||
template<typename Expr>
|
||||
struct arity_of<Expr&>
|
||||
: public Expr::breed_arity
|
||||
{};
|
||||
|
||||
namespace result_of {
|
||||
//
|
||||
// as_expr
|
||||
//
|
||||
template<typename T, typename Domain>
|
||||
struct as_expr {
|
||||
public:
|
||||
typedef typename Domain::template as_expr<T>::result_type type;
|
||||
};
|
||||
|
||||
//
|
||||
// as_child
|
||||
//
|
||||
template<typename T, typename Domain>
|
||||
struct as_child {
|
||||
public:
|
||||
typedef typename Domain::template as_child<T>::result_type type;
|
||||
};
|
||||
|
||||
//
|
||||
// child
|
||||
//
|
||||
template<typename Expr, typename N>
|
||||
struct child
|
||||
: public child_c<Expr, N::value>
|
||||
{};
|
||||
|
||||
//
|
||||
// value
|
||||
//
|
||||
template<typename Expr>
|
||||
struct value {
|
||||
static_assert(0 == Expr::breed_arity_c, "0 == Expr::breed_arity_c");
|
||||
public:
|
||||
typedef typename Expr::template breed_child<0>::type value_type;
|
||||
typedef typename sprout::breed::detail::term_traits<value_type>::value_type type;
|
||||
};
|
||||
template<typename Expr>
|
||||
struct value<Expr&> {
|
||||
static_assert(0 == Expr::breed_arity_c, "0 == Expr::breed_arity_c");
|
||||
public:
|
||||
typedef typename Expr:template breed_child<0>::type value_type;
|
||||
typedef typename sprout::breed::detail::term_traits<value_type>::reference type;
|
||||
};
|
||||
template<typename Expr>
|
||||
struct value<Expr const&> {
|
||||
static_assert(0 == Expr::breed_arity_c, "0 == Expr::breed_arity_c");
|
||||
public:
|
||||
typedef typename Expr:template breed_child<0>::type value_type;
|
||||
typedef typename sprout::breed::detail::term_traits<value_type>::const_reference type;
|
||||
};
|
||||
|
||||
//
|
||||
// left
|
||||
//
|
||||
template<typename Expr>
|
||||
struct left
|
||||
: public sprout::breed::result_of::child_c<Expr, 0>
|
||||
{};
|
||||
//
|
||||
// right
|
||||
//
|
||||
template<typename Expr>
|
||||
struct right
|
||||
: public child_c<Expr, 1>
|
||||
{};
|
||||
} // namespace result_of
|
||||
|
||||
//
|
||||
// terminal
|
||||
//
|
||||
template<typename T>
|
||||
struct terminal
|
||||
: public sprout::breed::transform<sprout::breed::terminal<T>, int>
|
||||
{
|
||||
public:
|
||||
typedef sprout::breed::tag::terminal breed_tag;
|
||||
typedef sprout::breed::expr<sprout::breed::tag::terminal, sprout::breed::term<T>, 0> type;
|
||||
typedef sprout::breed::basic_expr<sprout::breed::tag::terminal, sprout::breed::term<T>, 0> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child
|
||||
: public sprout::tppack_at<N, T>
|
||||
{};
|
||||
public:
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::transform_impl<Expr, State, Data>
|
||||
{
|
||||
public:
|
||||
typedef Expr result_type;
|
||||
public:
|
||||
#ifdef SPROUT_BREED_STRICT_RESULT_OF
|
||||
SPROUT_CONSTEXPR result_type
|
||||
#else
|
||||
SPROUT_CONSTEXPR typename impl::expr_param
|
||||
#endif
|
||||
operator()(
|
||||
typename impl::expr_param e,
|
||||
typename impl::state_param,
|
||||
typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// if_else_
|
||||
//
|
||||
template<typename T, typename U, typename V>
|
||||
struct if_else_
|
||||
: public sprout::breed::transform<if_else_<T, U, V>, int>
|
||||
{
|
||||
public:
|
||||
typedef sprout::breed::tag::if_else_ breed_tag;
|
||||
typedef sprout::breed::expr<
|
||||
sprout::breed::tag::if_else_, sprout::breed::sprout::breed::list<T, U, V>,
|
||||
3
|
||||
> type;
|
||||
typedef sprout::breed::basic_expr<
|
||||
sprout::breed::tag::if_else_,
|
||||
sprout::breed::sprout::breed::list<T, U, V>,
|
||||
3
|
||||
> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child
|
||||
: public sprout::tppack_at<N, T, U, V>
|
||||
{};
|
||||
public:
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::detail::pass_through_impl<sprout::breed::if_else_, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
//
|
||||
// nullary_expr
|
||||
//
|
||||
template<typename Tag, typename T>
|
||||
struct nullary_expr
|
||||
: public sprout::breed::transform<sprout::breed::nullary_expr<Tag, T>, int>
|
||||
{
|
||||
public:
|
||||
typedef Tag breed_tag;
|
||||
typedef sprout::breed::expr<Tag, sprout::breed::term<T>, 0> type;
|
||||
typedef sprout::breed::basic_expr<Tag, sprout::breed::term<T>, 0> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child
|
||||
: public sprout::tppack_at<N, T>
|
||||
{};
|
||||
public:
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::transform_impl<Expr, State, Data>
|
||||
{
|
||||
public:
|
||||
typedef Expr result_type;
|
||||
public:
|
||||
#ifdef SPROUT_BREED_STRICT_RESULT_OF
|
||||
SPROUT_CONSTEXPR result_type
|
||||
#else
|
||||
SPROUT_CONSTEXPR typename impl::expr_param
|
||||
#endif
|
||||
operator()(
|
||||
typename impl::expr_param e,
|
||||
typename impl::state_param,
|
||||
typename impl::data_param
|
||||
) const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// unary_expr
|
||||
//
|
||||
template<typename Tag, typename T>
|
||||
struct unary_expr
|
||||
: public sprout::breed::transform<sprout::breed::unary_expr<Tag, T>, int>
|
||||
{
|
||||
public:
|
||||
typedef Tag breed_tag;
|
||||
typedef sprout::breed::expr<Tag, sprout::breed::sprout::breed::list<T>, 1> type;
|
||||
typedef sprout::breed::basic_expr<Tag, sprout::breed::sprout::breed::list<T>, 1> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child
|
||||
: public sprout::tppack_at<N, T>
|
||||
{};
|
||||
public:
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::detail::pass_through_impl<sprout::breed::unary_expr, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
//
|
||||
// binary_expr
|
||||
//
|
||||
template<typename Tag, typename T, typename U>
|
||||
struct binary_expr
|
||||
: public sprout::breed::transform<sprout::breed::binary_expr<Tag, T, U>, int>
|
||||
{
|
||||
public:
|
||||
typedef Tag breed_tag;
|
||||
typedef sprout::breed::expr<Tag, sprout::breed::list<T, U>, 2> type;
|
||||
typedef sprout::breed::basic_expr<Tag, sprout::breed::list<T, U>, 2> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child
|
||||
: public sprout::tppack_at<N, T, U>
|
||||
{};
|
||||
public:
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::detail::pass_through_impl<binary_expr, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
# define SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(op) \
|
||||
template<typename T> \
|
||||
struct op \
|
||||
: public sprout::breed::transform<op<T>, int> \
|
||||
{ \
|
||||
public: \
|
||||
typedef sprout::breed::tag::op breed_tag; \
|
||||
typedef sprout::breed::expr<sprout::breed::tag::op, sprout::breed::list<T>, 1> type; \
|
||||
typedef sprout::breed::basic_expr<sprout::breed::tag::op, sprout::breed::list<T>, 1> breed_grammar; \
|
||||
public: \
|
||||
template<long N> \
|
||||
struct breed_child \
|
||||
: public sprout::tppack_at<N, T> \
|
||||
{}; \
|
||||
public: \
|
||||
template<typename Expr, typename State, typename Data> \
|
||||
struct impl \
|
||||
: public sprout::breed::detail::pass_through_impl<op, Expr, State, Data> \
|
||||
{}; \
|
||||
};
|
||||
# define SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(op) \
|
||||
template<typename T, typename U> \
|
||||
struct op \
|
||||
: public sprout::breed::transform<op<T, U>, int> \
|
||||
{ \
|
||||
public: \
|
||||
typedef sprout::breed::tag::op breed_tag; \
|
||||
typedef sprout::breed::expr<sprout::breed::tag::op, sprout::breed::list<T, U>, 2> type; \
|
||||
typedef sprout::breed::basic_expr<sprout::breed::tag::op, sprout::breed::list<T, U>, 2> breed_grammar; \
|
||||
public: \
|
||||
template<long N> \
|
||||
struct breed_child \
|
||||
: public sprout::tppack_at<N, T, U> \
|
||||
{}; \
|
||||
public: \
|
||||
template<typename Expr, typename State, typename Data> \
|
||||
struct impl \
|
||||
: public sprout::breed::detail::pass_through_impl<op, Expr, State, Data> \
|
||||
{}; \
|
||||
};
|
||||
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(unary_plus)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(negate)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(dereference)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(complement)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(address_of)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(logical_not)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(pre_inc)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(pre_dec)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(post_inc)
|
||||
SPROUT_BREED_DEFINE_UNARY_METAFUNCTION(post_dec)
|
||||
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(shift_left)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(shift_right)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(multiplies)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(divides)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(modulus)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(plus)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(minus)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(less)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(greater)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(less_equal)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(greater_equal)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(equal_to)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(not_equal_to)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(logical_or)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(logical_and)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_or)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_and)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_xor)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(comma)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(mem_ptr)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(shift_left_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(shift_right_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(multiplies_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(divides_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(modulus_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(plus_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(minus_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(subscript)
|
||||
SPROUT_BREED_DEFINE_BINARY_METAFUNCTION(member)
|
||||
|
||||
# undef SPROUT_BREED_DEFINE_UNARY_METAFUNCTION
|
||||
# undef SPROUT_BREED_DEFINE_BINARY_METAFUNCTION
|
||||
|
||||
//
|
||||
// function
|
||||
//
|
||||
template<typename... Args>
|
||||
struct function
|
||||
: public sprout::breed::transform<
|
||||
sprout::breed::function<Args...>,
|
||||
int
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::breed::tag::function breed_tag;
|
||||
typedef sprout::breed::expr<
|
||||
sprout::breed::tag::function, sprout::breed::list<Args...>,
|
||||
sizeof...(Args)
|
||||
> type;
|
||||
typedef sprout::breed::basic_expr<
|
||||
sprout::breed::tag::function, sprout::breed::list<Args...>,
|
||||
sizeof...(Args)
|
||||
> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child {
|
||||
public:
|
||||
typedef std::conditional<
|
||||
N < sizeof...(Args),
|
||||
sprout::tppack_at<N, Args...>,
|
||||
sprout::breed::detail::if_vararg<typename sprout::tppack_at<sizeof...(Args) - 1, Args...>::type>
|
||||
>::type::type
|
||||
};
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::detail::pass_through_impl<function, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
//
|
||||
// nary_expr
|
||||
//
|
||||
template<typename Tag, typename... Args>
|
||||
struct nary_expr
|
||||
: public sprout::breed::transform<
|
||||
sprout::breed::nary_expr<Tag, Args...>,
|
||||
int
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Tag breed_tag;
|
||||
typedef sprout::breed::expr<
|
||||
Tag,
|
||||
sprout::breed::list<Args...>,
|
||||
sizeof...(Args)
|
||||
> type;
|
||||
typedef sprout::breed::basic_expr<
|
||||
Tag,
|
||||
sprout::breed::list<Args...>,
|
||||
sizeof...(Args)
|
||||
> breed_grammar;
|
||||
public:
|
||||
template<long N>
|
||||
struct breed_child {
|
||||
public:
|
||||
typedef std::conditional<
|
||||
N < sizeof...(Args),
|
||||
sprout::tppack_at<N, Args...>,
|
||||
sprout::breed::detail::if_vararg<typename sprout::tppack_at<sizeof...(Args) - 1, Args...>::type>
|
||||
>::type::type
|
||||
};
|
||||
template<typename Expr, typename State, typename Data>
|
||||
struct impl
|
||||
: public sprout::breed::detail::pass_through_impl<sprout::breed::nary_expr, Expr, State, Data>
|
||||
{};
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<template<typename...> class T, typename... Args>
|
||||
struct is_callable_<T<Args...>, sizeof...(Args)>
|
||||
: public std::is_same<
|
||||
typename sprout::tppack_at<sizeof...(Args) - 1, Args...>::type,
|
||||
sprout::breed::callable
|
||||
>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
namespace result_of {
|
||||
//
|
||||
// child_c
|
||||
//
|
||||
template<typename Expr, long N>
|
||||
struct child_c {
|
||||
static_assert(0 != Expr::proto_arity_c, "0 != Expr::proto_arity_c");
|
||||
public:
|
||||
typedef typename Expr::template breed_child<N>::type value_type;
|
||||
typedef typename sprout::breed::detail::expr_traits<value_type>::value_type type;
|
||||
};
|
||||
template<typename Expr, long N>
|
||||
struct child_c<Expr&, N> {
|
||||
static_assert(0 != Expr::proto_arity_c, "0 != Expr::proto_arity_c");
|
||||
public:
|
||||
typedef typename Expr::template breed_child<N>::type value_type;
|
||||
typedef typename detail::expr_traits<value_type>::reference type;
|
||||
public:
|
||||
static type call(Expr& e) {
|
||||
return e.proto_base().breed child<N>();
|
||||
}
|
||||
};
|
||||
template<typename Expr, long N>
|
||||
struct child_c<Expr const&, N> {
|
||||
static_assert(0 != Expr::proto_arity_c, "0 != Expr::proto_arity_c");
|
||||
public:
|
||||
typedef typename Expr::template breed_child<N>::type value_type;
|
||||
typedef typename detail::expr_traits<value_type>::const_reference type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR type call(Expr const& e) {
|
||||
return e.proto_base().breed child<N>();
|
||||
}
|
||||
};
|
||||
} // namespace result_of
|
||||
|
||||
namespace functional {
|
||||
//
|
||||
// as_expr
|
||||
//
|
||||
template<typename Domain>
|
||||
struct as_expr {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename T>
|
||||
struct result<This(T)> {
|
||||
typedef typename Domain::template as_expr<T>::result_type type;
|
||||
};
|
||||
template<typename This, typename T>
|
||||
struct result<This(T&)> {
|
||||
typedef typename Domain::template as_expr<T>::result_type type;
|
||||
};
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename result<sprout::breed::as_expr(T const&)>::type
|
||||
>::type operator()(T const& t) const {
|
||||
return typename Domain::template as_expr<T const>()(t);
|
||||
}
|
||||
template<typename T>
|
||||
typename std::add_const<
|
||||
typename result<sprout::breed::as_expr(T&)>::type
|
||||
>::type operator()(T& t) const {
|
||||
return typename Domain::template as_expr<T>()(t);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// as_child
|
||||
//
|
||||
template<typename Domain>
|
||||
struct as_child {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename T>
|
||||
struct result<This(T)> {
|
||||
public:
|
||||
typedef typename Domain::template as_child<T>::result_type type;
|
||||
};
|
||||
template<typename This, typename T>
|
||||
struct result<This(T&)> {
|
||||
public:
|
||||
typedef typename Domain::template as_child<T>::result_type type;
|
||||
};
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename result<as_child(T const&)>::type
|
||||
>::type operator()(T const& t) const {
|
||||
return typename Domain::template as_child<T const>()(t);
|
||||
}
|
||||
template<typename T>
|
||||
typename std::add_const<
|
||||
typename result<as_child(T&)>::type
|
||||
>::type operator()(T& t) const {
|
||||
return typename Domain::template as_child<T const>()(t);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// child_c
|
||||
//
|
||||
template<long N>
|
||||
struct child_c {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)> {
|
||||
public:
|
||||
typedef typename result_of::child_c<Expr, N>::type type;
|
||||
};
|
||||
public:
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename result_of::child_c<Expr const&, N>::type operator()(Expr const& e) const {
|
||||
return result_of::child_c<Expr const&, N>::call(e);
|
||||
}
|
||||
template<typename Expr>
|
||||
typename result_of::child_c<Expr const&, N>::type operator()(Expr& e) const {
|
||||
return result_of::child_c<Expr&, N>::call(e);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// child
|
||||
//
|
||||
template<typename N>
|
||||
struct child {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)> {
|
||||
public:
|
||||
typedef typename result_of::child<Expr, N>::type type;
|
||||
};
|
||||
public:
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename result_of::child<Expr const&, N>::type operator()(Expr const& e) const {
|
||||
return result_of::child<Expr const&, N>::call(e);
|
||||
}
|
||||
template<typename Expr>
|
||||
typename result_of::child<Expr&, N>::type operator()(Expr const& e) const {
|
||||
return result_of::child<Expr&, N>::call(e);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// value
|
||||
//
|
||||
struct value {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)> {
|
||||
public:
|
||||
typedef typename result_of::value<Expr>::type type;
|
||||
};
|
||||
public:
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename result_of::value<Expr const&>::type operator()(Expr const& e) const {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename result_of::value<Expr&>::type operator()(Expr& e) const {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// left
|
||||
//
|
||||
struct left {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)> {
|
||||
public:
|
||||
typedef typename result_of::left<Expr>::type type;
|
||||
};
|
||||
public:
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename result_of::value<Expr const&>::type operator()(Expr const& e) const {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename result_of::value<Expr&>::type operator()(Expr& e) const {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// right
|
||||
//
|
||||
struct right {
|
||||
public:
|
||||
SPROUT_BREED_CALLABLE()
|
||||
public:
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
template<typename This, typename Expr>
|
||||
struct result<This(Expr)> {
|
||||
public:
|
||||
typedef typename result_of::right<Expr>::type type;
|
||||
};
|
||||
public:
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename result_of::value<Expr const&>::type operator()(Expr const& e) const {
|
||||
return e.breed_base().template child<1>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename result_of::value<Expr&>::type operator()(Expr& e) const {
|
||||
return e.breed_base().template child<1>();
|
||||
}
|
||||
};
|
||||
} // namespace functional
|
||||
|
||||
//
|
||||
// as_expr
|
||||
//
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename sprout::breed::result_of::as_expr<T const, sprout::breed::default_domain>::type
|
||||
>::type as_expr(T const& t) {
|
||||
return sprout::breed::default_domain::as_expr<T const>()(t);
|
||||
}
|
||||
template<typename T>
|
||||
typename std::add_const<
|
||||
typename sprout::breed::result_of::as_expr<T, sprout::breed::default_domain>::type
|
||||
>::type as_expr(T& t) {
|
||||
return sprout::breed::default_domain::as_expr<T>()(t);
|
||||
}
|
||||
template<typename Domain, typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename sprout::breed::result_of::as_expr<T const, Domain>::type
|
||||
>::type as_expr(T const& t) {
|
||||
return typename Domain::template as_expr<T const>()(t);
|
||||
}
|
||||
template<typename Domain, typename T>
|
||||
typename std::add_const<
|
||||
typename sprout::breed::result_of::as_expr<T, Domain>::type
|
||||
>::type as_expr(T& t) {
|
||||
return typename Domain::template as_expr<T>()(t);
|
||||
}
|
||||
|
||||
//
|
||||
// as_child
|
||||
//
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename sprout::breed::result_of::as_child<T const, sprout::breed::default_domain>::type
|
||||
>::type as_child(T const& t)
|
||||
{
|
||||
return sprout::breed::default_domain::as_child<T const>()(t);
|
||||
}
|
||||
template<typename T>
|
||||
typename std::add_const<
|
||||
typename sprout::breed::result_of::as_child<T, sprout::breed::default_domain>::type
|
||||
>::type as_child(T& t)
|
||||
{
|
||||
return sprout::breed::default_domain::as_child<T>()(t);
|
||||
}
|
||||
template<typename Domain, typename T>
|
||||
SPROUT_CONSTEXPR typename std::add_const<
|
||||
typename sprout::breed::result_of::as_child<T const, Domain>::type
|
||||
>::type as_child(T const& t)
|
||||
{
|
||||
return typename Domain::template as_child<T const>()(t);
|
||||
}
|
||||
template<typename Domain, typename T>
|
||||
typename std::add_const<
|
||||
typename sprout::breed::result_of::as_child<T, Domain>::type
|
||||
>::type as_child(T& t)
|
||||
{
|
||||
return typename Domain::template as_child<T>()(t);
|
||||
}
|
||||
|
||||
//
|
||||
// child
|
||||
//
|
||||
template<typename N, typename Expr>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::result_of::child<Expr const&, N>::type child(Expr const& e) {
|
||||
return sprout::breed::result_of::child<Expr const&, N>::call(e);
|
||||
}
|
||||
template<typename N, typename Expr>
|
||||
typename sprout::breed::result_of::child<Expr&, N>::type child(Expr& e) {
|
||||
return sprout::breed::result_of::child<Expr&, N>::call(e);
|
||||
}
|
||||
template<typename Expr2>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::detail::expr_traits<
|
||||
typename Expr2::breed_base_expr:template breed_child<0>::type
|
||||
>::const_reference child(Expr2 const& expr2) {
|
||||
return expr2.breed_base().template child<0>();
|
||||
}
|
||||
template<typename Expr2>
|
||||
typename sprout::breed::detail::expr_traits<
|
||||
typename Expr2::breed_base_expr:template breed_child<0>::type
|
||||
>::reference child(Expr2& expr2) {
|
||||
return expr2.breed_base().template child<0>();
|
||||
}
|
||||
|
||||
//
|
||||
// child_c
|
||||
//
|
||||
template<long N, typename Expr>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::result_of::child_c<Expr const&, N>::type child_c(Expr const& e) {
|
||||
return sprout::breed::result_of::child_c<Expr const&, N>::call(e);
|
||||
}
|
||||
template<long N, typename Expr>
|
||||
typename sprout::breed::result_of::child_c<Expr&, N>::type child_c(Expr& e) {
|
||||
return sprout::breed::result_of::child_c<Expr&, N>::call(e);
|
||||
}
|
||||
|
||||
//
|
||||
// value
|
||||
//
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::result_of::value<Expr const&>::type value(Expr const& e) {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename sprout::breed::result_of::value<Expr&>::type value(Expr& e) {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
|
||||
//
|
||||
// left
|
||||
//
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::result_of::left<Expr const&>::type left(Expr const& e) {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename sprout::breed::result_of::left<Expr&>::type left(Expr& e) {
|
||||
return e.breed_base().template child<0>();
|
||||
}
|
||||
|
||||
//
|
||||
// right
|
||||
//
|
||||
template<typename Expr>
|
||||
SPROUT_CONSTEXPR typename sprout::breed::result_of::right<Expr const&>::type right(Expr const& e) {
|
||||
return e.breed_base().template child<1>();
|
||||
}
|
||||
template<typename Expr>
|
||||
typename sprout::breed::result_of::right<Expr&>::type right(Expr& e) {
|
||||
return e.breed_base().template child<1>();
|
||||
}
|
||||
|
||||
//
|
||||
// is_callable
|
||||
//
|
||||
template<typename Domain>
|
||||
struct is_callable<sprout::breed::functional::as_expr<Domain> >
|
||||
: public std::true_type
|
||||
{};
|
||||
template<typename Domain>
|
||||
struct is_callable<sprout::breed::functional::as_child<Domain> >
|
||||
: public std::true_type
|
||||
{};
|
||||
template<long N>
|
||||
struct is_callable<sprout::breed::functional::child_c<N> >
|
||||
: public std::true_type
|
||||
{};
|
||||
template<typename N>
|
||||
struct is_callable<sprout::breed::functional::child<N> >
|
||||
: public std::true_type
|
||||
{};
|
||||
} // namespace breed
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BREED_TRAITS_HPP
|
Loading…
Add table
Add a link
Reference in a new issue