1 /////////////////////////////////////////////////////////////////////////////// 2 /// \file impl.hpp 3 /// Contains definition of transform<> and transform_impl<> helpers. 4 // 5 // Copyright 2008 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_IMPL_HPP_EAN_04_03_2008 10 #define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008 11 12 #include <boost/config.hpp> 13 #include <boost/mpl/bool.hpp> 14 #include <boost/type_traits/add_const.hpp> 15 #include <boost/type_traits/add_reference.hpp> 16 #include <boost/proto/proto_fwd.hpp> 17 #include <boost/proto/detail/any.hpp> 18 #include <boost/proto/detail/static_const.hpp> 19 20 #if defined(_MSC_VER) 21 # pragma warning(push) 22 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined 23 #endif 24 25 namespace boost { namespace proto 26 { 27 namespace envns_ 28 { 29 //////////////////////////////////////////////////////////////////////////////////////////// 30 struct key_not_found 31 {}; 32 33 //////////////////////////////////////////////////////////////////////////////////////////// 34 // empty_env 35 struct empty_env 36 { 37 typedef void proto_environment_; 38 39 template<typename OtherTag, typename OtherValue = key_not_found> 40 struct lookup 41 { 42 typedef OtherValue type; 43 typedef 44 typename add_reference<typename add_const<OtherValue>::type>::type 45 const_reference; 46 }; 47 operator []boost::proto::envns_::empty_env48 key_not_found operator[](detail::any) const 49 { 50 return key_not_found(); 51 } 52 53 template<typename T> atboost::proto::envns_::empty_env54 T const &at(detail::any, T const &t) const 55 { 56 return t; 57 } 58 }; 59 } 60 61 //////////////////////////////////////////////////////////////////////////////////////////// 62 // is_env 63 template<typename T, typename Void> 64 struct is_env 65 : mpl::false_ 66 {}; 67 68 template<typename T> 69 struct is_env<T, typename T::proto_environment_> 70 : mpl::true_ 71 {}; 72 73 template<typename T> 74 struct is_env<T &, void> 75 : is_env<T> 76 {}; 77 78 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES 79 80 /// INTERNAL ONLY 81 /// 82 #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \ 83 BOOST_PROTO_CALLABLE() \ 84 typedef X proto_is_transform_; \ 85 typedef PrimitiveTransform transform_type; \ 86 \ 87 template<typename Sig> \ 88 struct result \ 89 { \ 90 typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \ 91 }; \ 92 \ 93 template<typename Expr> \ 94 BOOST_FORCEINLINE \ 95 typename boost::proto::detail::apply_transform<transform_type(Expr &)>::result_type \ 96 operator ()(Expr &e) const \ 97 { \ 98 boost::proto::empty_state s = 0; \ 99 boost::proto::empty_env d; \ 100 return boost::proto::detail::apply_transform<transform_type(Expr &)>()(e, s, d); \ 101 } \ 102 \ 103 template<typename Expr> \ 104 BOOST_FORCEINLINE \ 105 typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \ 106 operator ()(Expr const &e) const \ 107 { \ 108 boost::proto::empty_state s = 0; \ 109 boost::proto::empty_env d; \ 110 return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \ 111 } \ 112 \ 113 template<typename Expr, typename State> \ 114 BOOST_FORCEINLINE \ 115 typename boost::proto::detail::apply_transform<transform_type(Expr &, State &)>::result_type \ 116 operator ()(Expr &e, State &s) const \ 117 { \ 118 boost::proto::empty_env d; \ 119 return boost::proto::detail::apply_transform<transform_type(Expr &, State &)>()(e, s, d); \ 120 } \ 121 \ 122 template<typename Expr, typename State> \ 123 BOOST_FORCEINLINE \ 124 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>::result_type \ 125 operator ()(Expr const &e, State &s) const \ 126 { \ 127 boost::proto::empty_env d; \ 128 return boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>()(e, s, d); \ 129 } \ 130 \ 131 template<typename Expr, typename State> \ 132 BOOST_FORCEINLINE \ 133 typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>::result_type \ 134 operator ()(Expr &e, State const &s) const \ 135 { \ 136 boost::proto::empty_env d; \ 137 return boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>()(e, s, d); \ 138 } \ 139 \ 140 template<typename Expr, typename State> \ 141 BOOST_FORCEINLINE \ 142 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \ 143 operator ()(Expr const &e, State const &s) const \ 144 { \ 145 boost::proto::empty_env d; \ 146 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \ 147 } \ 148 \ 149 template<typename Expr, typename State, typename Data> \ 150 BOOST_FORCEINLINE \ 151 typename boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>::result_type \ 152 operator ()(Expr &e, State &s, Data &d) const \ 153 { \ 154 return boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>()(e, s, d); \ 155 } \ 156 \ 157 template<typename Expr, typename State, typename Data> \ 158 BOOST_FORCEINLINE \ 159 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>::result_type \ 160 operator ()(Expr const &e, State &s, Data &d) const \ 161 { \ 162 return boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>()(e, s, d); \ 163 } \ 164 \ 165 template<typename Expr, typename State, typename Data> \ 166 BOOST_FORCEINLINE \ 167 typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>::result_type \ 168 operator ()(Expr &e, State const &s, Data &d) const \ 169 { \ 170 return boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>()(e, s, d); \ 171 } \ 172 \ 173 template<typename Expr, typename State, typename Data> \ 174 BOOST_FORCEINLINE \ 175 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>::result_type \ 176 operator ()(Expr const &e, State const &s, Data &d) const \ 177 { \ 178 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>()(e, s, d); \ 179 } \ 180 /**/ 181 182 #else 183 184 /// INTERNAL ONLY 185 /// 186 #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \ 187 BOOST_PROTO_CALLABLE() \ 188 typedef X proto_is_transform_; \ 189 typedef PrimitiveTransform transform_type; \ 190 \ 191 template<typename Sig> \ 192 struct result \ 193 { \ 194 typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \ 195 }; \ 196 \ 197 template<typename Expr> \ 198 BOOST_FORCEINLINE \ 199 typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \ 200 operator ()(Expr &&e) const \ 201 { \ 202 boost::proto::empty_state s = 0; \ 203 boost::proto::empty_env d; \ 204 return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \ 205 } \ 206 \ 207 template<typename Expr, typename State> \ 208 BOOST_FORCEINLINE \ 209 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \ 210 operator ()(Expr &&e, State &&s) const \ 211 { \ 212 boost::proto::empty_env d; \ 213 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \ 214 } \ 215 \ 216 template<typename Expr, typename State, typename Data> \ 217 BOOST_FORCEINLINE \ 218 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>::result_type \ 219 operator ()(Expr &&e, State &&s, Data &&d) const \ 220 { \ 221 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>()(e, s, d); \ 222 } \ 223 /**/ 224 225 #endif 226 227 #define BOOST_PROTO_TRANSFORM(PrimitiveTransform) \ 228 BOOST_PROTO_TRANSFORM_(PrimitiveTransform, void) \ 229 /**/ 230 231 namespace detail 232 { 233 template<typename Sig> 234 struct apply_transform; 235 236 template<typename PrimitiveTransform, typename Expr> 237 struct apply_transform<PrimitiveTransform(Expr)> 238 : PrimitiveTransform::template impl<Expr, empty_state, empty_env> 239 {}; 240 241 template<typename PrimitiveTransform, typename Expr, typename State> 242 struct apply_transform<PrimitiveTransform(Expr, State)> 243 : PrimitiveTransform::template impl<Expr, State, empty_env> 244 {}; 245 246 template<typename PrimitiveTransform, typename Expr, typename State, typename Data> 247 struct apply_transform<PrimitiveTransform(Expr, State, Data)> 248 : PrimitiveTransform::template impl<Expr, State, Data> 249 {}; 250 } 251 252 template<typename PrimitiveTransform, typename X> 253 struct transform 254 { 255 BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) 256 }; 257 258 template<typename Expr, typename State, typename Data> 259 struct transform_impl 260 { 261 typedef Expr const expr; 262 typedef Expr const &expr_param; 263 typedef State const state; 264 typedef State const &state_param; 265 typedef Data const data; 266 typedef Data const &data_param; 267 }; 268 269 template<typename Expr, typename State, typename Data> 270 struct transform_impl<Expr &, State, Data> 271 { 272 typedef Expr expr; 273 typedef Expr &expr_param; 274 typedef State const state; 275 typedef State const &state_param; 276 typedef Data const data; 277 typedef Data const &data_param; 278 }; 279 280 template<typename Expr, typename State, typename Data> 281 struct transform_impl<Expr, State &, Data> 282 { 283 typedef Expr const expr; 284 typedef Expr const &expr_param; 285 typedef State state; 286 typedef State &state_param; 287 typedef Data const data; 288 typedef Data const &data_param; 289 }; 290 291 template<typename Expr, typename State, typename Data> 292 struct transform_impl<Expr, State, Data &> 293 { 294 typedef Expr const expr; 295 typedef Expr const &expr_param; 296 typedef State const state; 297 typedef State const &state_param; 298 typedef Data data; 299 typedef Data &data_param; 300 }; 301 302 template<typename Expr, typename State, typename Data> 303 struct transform_impl<Expr &, State &, Data> 304 { 305 typedef Expr expr; 306 typedef Expr &expr_param; 307 typedef State state; 308 typedef State &state_param; 309 typedef Data const data; 310 typedef Data const &data_param; 311 }; 312 313 template<typename Expr, typename State, typename Data> 314 struct transform_impl<Expr &, State, Data &> 315 { 316 typedef Expr expr; 317 typedef Expr &expr_param; 318 typedef State const state; 319 typedef State const &state_param; 320 typedef Data data; 321 typedef Data &data_param; 322 }; 323 324 template<typename Expr, typename State, typename Data> 325 struct transform_impl<Expr, State &, Data &> 326 { 327 typedef Expr const expr; 328 typedef Expr const &expr_param; 329 typedef State state; 330 typedef State &state_param; 331 typedef Data data; 332 typedef Data &data_param; 333 }; 334 335 template<typename Expr, typename State, typename Data> 336 struct transform_impl<Expr &, State &, Data &> 337 { 338 typedef Expr expr; 339 typedef Expr &expr_param; 340 typedef State state; 341 typedef State &state_param; 342 typedef Data data; 343 typedef Data &data_param; 344 }; 345 346 }} // namespace boost::proto 347 348 #if defined(_MSC_VER) 349 # pragma warning(pop) 350 #endif 351 352 #endif 353