#ifndef SPROUT_BREED_TRANSFORM_PASS_THROUGH_HPP #define SPROUT_BREED_TRANSFORM_PASS_THROUGH_HPP #include #include #include #include #include #include #include namespace sprout { namespace breed { namespace detail { template< typename Grammar, typename Expr, typename State, typename Data, long Arity = sprout::breed::arity_of::value > struct pass_through_impl : public sprout::breed::transform_impl { public: typedef typename pass_through_impl::expr unref_expr; private: template struct list_impl {}; template struct list_impl > { public: typedef sprout::breed::list< typename Grammar::template breed_child::type::template impl< typename sprout::breed::result_of::child_c::type, State, Data >::result_type... > type; }; public: typedef typename sprout::breed::base_expr< typename unref_expr::breed_domain, typename unref_expr::breed_tag, typename list_impl::type>::type >::type expr_type; typedef typename unref_expr::breed_generator breed_generator; typedef typename sprout::breed::detail::std_result_of< breed_generator(expr_type) >::type result_type; private: template SPROUT_CONSTEXPR result_type call_impl( typename pass_through_impl::expr_param e, typename pass_through_impl::state_param s, typename pass_through_impl::data_param d, sprout::index_tuple ) const { return breed_generator()( expr_type( typename Grammar::template breed_child::type::template impl< typename sprout::breed::result_of::child_c::type, State, Data >()(e.proto_base().template child(), s, d)... ) ); } public: SPROUT_CONSTEXPR result_type operator()( typename pass_through_impl::expr_param e, typename pass_through_impl::state_param s, typename pass_through_impl::data_param d ) const { return call_impl(e, s, d, sprout::make_index_tuple::make()); } }; template struct pass_through_impl : public sprout::breed::transform_impl { public: typedef Expr result_type; public: #ifdef SPROUT_BREED_STRICT_RESULT_OF SPROUT_CONSTEXPR result_type #else SPROUT_CONSTEXPR typename pass_through_impl::expr_param #endif operator()( typename pass_through_impl::expr_param e, typename pass_through_impl::state_param, typename pass_through_impl::data_param ) const { return e; } }; } // namespace detail // // pass_through // template struct pass_through : public sprout::breed::transform > { public: template struct impl : public sprout::breed::detail::pass_through_impl {}; }; // // is_callable // template struct is_callable > : public std::true_type {}; } // namespace breed } // namespace sprout #endif // #ifndef SPROUT_BREED_TRANSFORM_PASS_THROUGH_HPP