1 /////////////////////////////////////////////////////////////////////////////// 2 /// \file apply.hpp 3 /// Proto transforms for applying MPL placeholder expressions. 4 // 5 // Copyright 2007 Eric Niebler. Distributed under the Boost 6 // Software License, Version 1.0. (See accompanying file 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_PROTO_TRANSFORM_APPLY_HPP_EAN_06_23_2007 10 #define BOOST_PROTO_TRANSFORM_APPLY_HPP_EAN_06_23_2007 11 12 #include <boost/xpressive/proto/detail/prefix.hpp> 13 #include <boost/mpl/apply.hpp> 14 #include <boost/xpressive/proto/detail/suffix.hpp> 15 16 namespace boost { namespace proto { namespace transform 17 { 18 namespace detail 19 { 20 struct any 21 { 22 template<typename T> anyboost::proto::transform::detail::any23 any(T const &) 24 {} 25 }; 26 27 struct default_factory 28 { default_factoryboost::proto::transform::detail::default_factory29 default_factory() 30 {} 31 operator ()boost::proto::transform::detail::default_factory32 default_factory const &operator()() const 33 { 34 return *this; 35 } 36 operator ()boost::proto::transform::detail::default_factory37 default_factory const &operator()(any) const 38 { 39 return *this; 40 } 41 operator ()boost::proto::transform::detail::default_factory42 default_factory const &operator()(any, any) const 43 { 44 return *this; 45 } 46 operator ()boost::proto::transform::detail::default_factory47 default_factory const &operator()(any, any, any) const 48 { 49 return *this; 50 } 51 52 template<typename T> operator Tboost::proto::transform::detail::default_factory53 operator T() const 54 { 55 return T(); 56 } 57 }; 58 } 59 60 // Always return the specified type/object 61 template<typename Grammar, typename Always, typename Factory> 62 struct always 63 : Grammar 64 { alwaysboost::proto::transform::always65 always() {} 66 67 template<typename, typename, typename> 68 struct apply 69 { 70 typedef Always type; 71 }; 72 73 template<typename Expr, typename State, typename Visitor> 74 static Always callboost::proto::transform::always75 call(Expr const &, State const &, Visitor &) 76 { 77 return Factory()(); 78 } 79 }; 80 81 // Apply an MPL lambda, passing just Expr 82 template<typename Grammar, typename Lambda, typename Factory> 83 struct apply1 84 : Grammar 85 { apply1boost::proto::transform::apply186 apply1() {} 87 88 template<typename Expr, typename State, typename Visitor> 89 struct apply 90 : mpl::apply1<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type> 91 {}; 92 93 template<typename Expr, typename State, typename Visitor> 94 static typename apply<Expr, State, Visitor>::type callboost::proto::transform::apply195 call(Expr const &expr, State const &state, Visitor &visitor) 96 { 97 return Factory()(Grammar::call(expr, state, visitor)); 98 } 99 }; 100 101 // Apply an MPL lambda, passing Expr and State 102 template<typename Grammar, typename Lambda, typename Factory> 103 struct apply2 104 : Grammar 105 { apply2boost::proto::transform::apply2106 apply2() {} 107 108 template<typename Expr, typename State, typename Visitor> 109 struct apply 110 : mpl::apply2<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type, State> 111 {}; 112 113 template<typename Expr, typename State, typename Visitor> 114 static typename apply<Expr, State, Visitor>::type callboost::proto::transform::apply2115 call(Expr const &expr, State const &state, Visitor &visitor) 116 { 117 return Factory()(Grammar::call(expr, state, visitor), state); 118 } 119 }; 120 121 // Apply an MPL lambda, passing Expr, State and Visitor 122 template<typename Grammar, typename Lambda, typename Factory> 123 struct apply3 124 : Grammar 125 { apply3boost::proto::transform::apply3126 apply3() {} 127 128 template<typename Expr, typename State, typename Visitor> 129 struct apply 130 : mpl::apply3<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor> 131 {}; 132 133 template<typename Expr, typename State, typename Visitor> 134 static typename apply<Expr, State, Visitor>::type callboost::proto::transform::apply3135 call(Expr const &expr, State const &state, Visitor &visitor) 136 { 137 return Factory()(Grammar::call(expr, state, visitor), state, visitor); 138 } 139 }; 140 141 }}} 142 143 namespace boost { namespace proto 144 { 145 template<typename Grammar, typename Always, typename Factory> 146 struct is_transform<transform::always<Grammar, Always, Factory> > 147 : mpl::true_ 148 {}; 149 150 template<typename Grammar, typename Lambda, typename Factory> 151 struct is_transform<transform::apply1<Grammar, Lambda, Factory> > 152 : mpl::true_ 153 {}; 154 155 template<typename Grammar, typename Lambda, typename Factory> 156 struct is_transform<transform::apply2<Grammar, Lambda, Factory> > 157 : mpl::true_ 158 {}; 159 160 template<typename Grammar, typename Lambda, typename Factory> 161 struct is_transform<transform::apply3<Grammar, Lambda, Factory> > 162 : mpl::true_ 163 {}; 164 }} 165 166 #endif 167