#ifndef SPROUT_BREED_GENERATE_HPP #define SPROUT_BREED_GENERATE_HPP #include #include #include #include #include #include namespace sprout { namespace breed { namespace detail { template struct by_value_generator_; template struct by_value_generator_, 0> > { public: typedef breed::expr< Tag, sprout::breed::term::value_type>, 0 > type; public: static SPROUT_CONSTEXPR type call(breed::expr, 0> const& e) { return type(e.template child<0>()); } }; template struct by_value_generator_, 0> > { public: typedef breed::expr< Tag, sprout::breed::term::value_type>, 0 > type; public: static SPROUT_CONSTEXPR type call(breed::expr, 0> const& e) { return type(e.template child<0>()); } }; template struct by_value_generator_< sprout::breed::expr, sizeof...(Args)> > { public: typedef sprout::breed::list src_args; typedef sprout::breed::list::type...> dst_args; typedef sprout::breed::expr src_type; typedef sprout::breed::expr type; private: template static SPROUT_CONSTEXPR type call_impl(src_type const& e, sprout::index_tuple) { return type(e.template child()...); } public: static SPROUT_CONSTEXPR type call(src_type const& e) { return call_impl(typename sprout::index_range<0, sizeof...(Args)>::type()); } }; template struct by_value_generator_< sprout::breed::basic_expr, sizeof...(Args)> > { public: typedef sprout::breed::list src_args; typedef sprout::breed::list::type...> dst_args; typedef sprout::breed::basic_expr src_type; typedef sprout::breed::basic_expr type; private: template static SPROUT_CONSTEXPR type call_impl(src_type const& e, sprout::index_tuple) { return type(e.template child()...); } public: static SPROUT_CONSTEXPR type call(src_type const& e) { return call_impl(typename sprout::index_range<0, sizeof...(Args)>::type()); } }; } // namespace detail // // use_basic_expr // template struct use_basic_expr : public Generator { public: SPROUT_BREED_USE_BASIC_EXPR(); }; // // default_generator // struct default_generator { public: SPROUT_BREED_CALLABLE() public: template struct result; template struct result { public: typedef Expr type; }; public: template #ifdef SPROUT_BREED_STRICT_RESULT_OF SPROUT_CONSTEXPR Expr #else SPROUT_CONSTEXPR Expr const& #endif operator()(Expr const& e) const { return e; } }; // // basic_default_generator // struct basic_default_generator : public sprout::breed::use_basic_expr {}; // // generator // template class Extends> struct generator { SPROUT_BREED_CALLABLE() SPROUT_BREED_USE_BASIC_EXPR() public: template struct result; template struct result { public: typedef Extends type; }; template struct result { public: typedef Extends type; }; template struct result { public: typedef Extends type; }; public: template SPROUT_CONSTEXPR Extends operator()(Expr const& e) const { return Extends(e); } }; // // pod_generator // template class Extends> struct pod_generator { public: SPROUT_BREED_CALLABLE() SPROUT_BREED_USE_BASIC_EXPR() public: template struct result; template struct result { public: typedef Extends type; }; template struct result { public: typedef Extends type; }; template struct result { public: typedef Extends type; }; public: template SPROUT_CONSTEXPR Extends operator()(Expr const& e) const { return Extends(e); } }; // // by_value_generator // struct by_value_generator { public: SPROUT_BREED_CALLABLE() public: template struct result; template struct result { public: typedef typename sprout::breed::detail::by_value_generator_::type type; }; template struct result { public: typedef typename sprout::breed::detail::by_value_generator_::type type; }; template struct result { public: typedef typename sprout::breed::detail::by_value_generator_::type type; }; public: template SPROUT_CONSTEXPR typename result::type operator()(Expr const& e) const { return sprout::breed::detail::by_value_generator_::call(e); } }; // // compose_generators // template struct compose_generators { public: SPROUT_BREED_CALLABLE() public: template struct result; template struct result { public: typedef typename Second::template result< Second(typename First::template result::type) >::type type; }; template struct result { public: typedef typename Second::template result< Second(typename First::template result::type) >::type type; }; template struct result { public: typedef typename Second::template result< Second(typename First::template result::type) >::type type; }; public: template SPROUT_CONSTEXPR typename result::type operator()(Expr const& e) const { return Second()(First()(e)); } }; // // wants_basic_expr // template struct wants_basic_expr : public std::false_type {}; template struct wants_basic_expr : public std::true_type {}; // // is_callable // template<> struct is_callable : public std::true_type {}; template class Extends> struct is_callable > : public std::true_type {}; template class Extends> struct is_callable > : public std::true_type {}; template<> struct is_callable : public std::true_type {}; template struct is_callable > : public std::true_type {}; namespace detail { template struct std_result_of { public: typedef Expr type; }; template struct std_result_of { public: typedef Expr type; }; template struct std_result_of { public: typedef Expr type; }; template struct std_result_of { public: typedef Expr type; }; } // namespace detail } // namespace breed } // namespace sprout #endif // #ifndef SPROUT_BREED_GENERATE_HPP