353 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			353 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /////////////////////////////////////////////////////////////////////////////// | ||
|  | /// \file impl.hpp | ||
|  | /// Contains definition of transform<> and transform_impl<> helpers. | ||
|  | // | ||
|  | //  Copyright 2008 Eric Niebler. Distributed under the Boost | ||
|  | //  Software License, Version 1.0. (See accompanying file | ||
|  | //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | #ifndef BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008 | ||
|  | #define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008 | ||
|  | 
 | ||
|  | #include <boost/config.hpp> | ||
|  | #include <boost/mpl/bool.hpp> | ||
|  | #include <boost/type_traits/add_const.hpp> | ||
|  | #include <boost/type_traits/add_reference.hpp> | ||
|  | #include <boost/proto/proto_fwd.hpp> | ||
|  | #include <boost/proto/detail/any.hpp> | ||
|  | #include <boost/proto/detail/static_const.hpp> | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) | ||
|  | # pragma warning(push) | ||
|  | # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined | ||
|  | #endif | ||
|  | 
 | ||
|  | namespace boost { namespace proto | ||
|  | { | ||
|  |     namespace envns_ | ||
|  |     { | ||
|  |         //////////////////////////////////////////////////////////////////////////////////////////// | ||
|  |         struct key_not_found | ||
|  |         {}; | ||
|  | 
 | ||
|  |         //////////////////////////////////////////////////////////////////////////////////////////// | ||
|  |         // empty_env | ||
|  |         struct empty_env | ||
|  |         { | ||
|  |             typedef void proto_environment_; | ||
|  | 
 | ||
|  |             template<typename OtherTag, typename OtherValue = key_not_found> | ||
|  |             struct lookup | ||
|  |             { | ||
|  |                 typedef OtherValue type; | ||
|  |                 typedef | ||
|  |                     typename add_reference<typename add_const<OtherValue>::type>::type | ||
|  |                 const_reference; | ||
|  |             }; | ||
|  | 
 | ||
|  |             key_not_found operator[](detail::any) const | ||
|  |             { | ||
|  |                 return key_not_found(); | ||
|  |             } | ||
|  | 
 | ||
|  |             template<typename T> | ||
|  |             T const &at(detail::any, T const &t) const | ||
|  |             { | ||
|  |                 return t; | ||
|  |             } | ||
|  |         }; | ||
|  |     } | ||
|  | 
 | ||
|  |     //////////////////////////////////////////////////////////////////////////////////////////// | ||
|  |     // is_env | ||
|  |     template<typename T, typename Void> | ||
|  |     struct is_env | ||
|  |       : mpl::false_ | ||
|  |     {}; | ||
|  | 
 | ||
|  |     template<typename T> | ||
|  |     struct is_env<T, typename T::proto_environment_> | ||
|  |       : mpl::true_ | ||
|  |     {}; | ||
|  | 
 | ||
|  |     template<typename T> | ||
|  |     struct is_env<T &, void> | ||
|  |       : is_env<T> | ||
|  |     {}; | ||
|  | 
 | ||
|  | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | ||
|  | 
 | ||
|  |     /// INTERNAL ONLY | ||
|  |     /// | ||
|  |     #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X)                                                       \ | ||
|  |     BOOST_PROTO_CALLABLE()                                                                                      \ | ||
|  |     typedef X proto_is_transform_;                                                                              \ | ||
|  |     typedef PrimitiveTransform transform_type;                                                                  \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Sig>                                                                                      \ | ||
|  |     struct result                                                                                               \ | ||
|  |     {                                                                                                           \ | ||
|  |         typedef typename boost::proto::detail::apply_transform<Sig>::result_type type;                          \ | ||
|  |     };                                                                                                          \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr>                                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr &)>::result_type                         \ | ||
|  |     operator ()(Expr &e) const                                                                                  \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_state s = 0;                                                                        \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr &)>()(e, s, d);                        \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr>                                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type                   \ | ||
|  |     operator ()(Expr const &e) const                                                                            \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_state s = 0;                                                                        \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d);                  \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State>                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr &, State &)>::result_type                \ | ||
|  |     operator ()(Expr &e, State &s) const                                                                        \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr &, State &)>()(e, s, d);               \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State>                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>::result_type          \ | ||
|  |     operator ()(Expr const &e, State &s) const                                                                  \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>()(e, s, d);         \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State>                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>::result_type          \ | ||
|  |     operator ()(Expr &e, State const &s) const                                                                  \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>()(e, s, d);         \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State>                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type    \ | ||
|  |     operator ()(Expr const &e, State const &s) const                                                            \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d);   \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State, typename Data>                                                      \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>::result_type        \ | ||
|  |     operator ()(Expr &e, State &s, Data &d) const                                                               \ | ||
|  |     {                                                                                                           \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>()(e, s, d);       \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State, typename Data>                                                      \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>::result_type  \ | ||
|  |     operator ()(Expr const &e, State &s, Data &d) const                                                         \ | ||
|  |     {                                                                                                           \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>()(e, s, d); \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State, typename Data>                                                      \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>::result_type  \ | ||
|  |     operator ()(Expr &e, State const &s, Data &d) const                                                         \ | ||
|  |     {                                                                                                           \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>()(e, s, d); \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State, typename Data>                                                      \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>::result_type  \ | ||
|  |     operator ()(Expr const &e, State const &s, Data &d) const                                                   \ | ||
|  |     {                                                                                                           \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>()(e, s, d); \ | ||
|  |     }                                                                                                           \ | ||
|  |     /**/ | ||
|  | 
 | ||
|  | #else | ||
|  | 
 | ||
|  |     /// INTERNAL ONLY | ||
|  |     /// | ||
|  |     #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X)                                                       \ | ||
|  |     BOOST_PROTO_CALLABLE()                                                                                      \ | ||
|  |     typedef X proto_is_transform_;                                                                              \ | ||
|  |     typedef PrimitiveTransform transform_type;                                                                  \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Sig>                                                                                      \ | ||
|  |     struct result                                                                                               \ | ||
|  |     {                                                                                                           \ | ||
|  |         typedef typename boost::proto::detail::apply_transform<Sig>::result_type type;                          \ | ||
|  |     };                                                                                                          \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr>                                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type                   \ | ||
|  |     operator ()(Expr &&e) const                                                                                 \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_state s = 0;                                                                        \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d);                  \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State>                                                                     \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type    \ | ||
|  |     operator ()(Expr &&e, State &&s) const                                                                      \ | ||
|  |     {                                                                                                           \ | ||
|  |         boost::proto::empty_env d;                                                                              \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d);   \ | ||
|  |     }                                                                                                           \ | ||
|  |                                                                                                                 \ | ||
|  |     template<typename Expr, typename State, typename Data>                                                      \ | ||
|  |     BOOST_FORCEINLINE                                                                                           \ | ||
|  |     typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>::result_type \ | ||
|  |     operator ()(Expr &&e, State &&s, Data &&d) const                                                            \ | ||
|  |     {                                                                                                           \ | ||
|  |         return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>()(e, s, d); \ | ||
|  |     }                                                                                                           \ | ||
|  |     /**/ | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  |     #define BOOST_PROTO_TRANSFORM(PrimitiveTransform)                                                           \ | ||
|  |         BOOST_PROTO_TRANSFORM_(PrimitiveTransform, void)                                                        \ | ||
|  |         /**/ | ||
|  | 
 | ||
|  |     namespace detail | ||
|  |     { | ||
|  |         template<typename Sig> | ||
|  |         struct apply_transform; | ||
|  | 
 | ||
|  |         template<typename PrimitiveTransform, typename Expr> | ||
|  |         struct apply_transform<PrimitiveTransform(Expr)> | ||
|  |           : PrimitiveTransform::template impl<Expr, empty_state, empty_env> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template<typename PrimitiveTransform, typename Expr, typename State> | ||
|  |         struct apply_transform<PrimitiveTransform(Expr, State)> | ||
|  |           : PrimitiveTransform::template impl<Expr, State, empty_env> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template<typename PrimitiveTransform, typename Expr, typename State, typename Data> | ||
|  |         struct apply_transform<PrimitiveTransform(Expr, State, Data)> | ||
|  |           : PrimitiveTransform::template impl<Expr, State, Data> | ||
|  |         {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     template<typename PrimitiveTransform, typename X> | ||
|  |     struct transform | ||
|  |     { | ||
|  |         BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl | ||
|  |     { | ||
|  |         typedef Expr const expr; | ||
|  |         typedef Expr const &expr_param; | ||
|  |         typedef State const state; | ||
|  |         typedef State const &state_param; | ||
|  |         typedef Data const data; | ||
|  |         typedef Data const &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr &, State, Data> | ||
|  |     { | ||
|  |         typedef Expr expr; | ||
|  |         typedef Expr &expr_param; | ||
|  |         typedef State const state; | ||
|  |         typedef State const &state_param; | ||
|  |         typedef Data const data; | ||
|  |         typedef Data const &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr, State &, Data> | ||
|  |     { | ||
|  |         typedef Expr const expr; | ||
|  |         typedef Expr const &expr_param; | ||
|  |         typedef State state; | ||
|  |         typedef State &state_param; | ||
|  |         typedef Data const data; | ||
|  |         typedef Data const &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr, State, Data &> | ||
|  |     { | ||
|  |         typedef Expr const expr; | ||
|  |         typedef Expr const &expr_param; | ||
|  |         typedef State const state; | ||
|  |         typedef State const &state_param; | ||
|  |         typedef Data data; | ||
|  |         typedef Data &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr &, State &, Data> | ||
|  |     { | ||
|  |         typedef Expr expr; | ||
|  |         typedef Expr &expr_param; | ||
|  |         typedef State state; | ||
|  |         typedef State &state_param; | ||
|  |         typedef Data const data; | ||
|  |         typedef Data const &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr &, State, Data &> | ||
|  |     { | ||
|  |         typedef Expr expr; | ||
|  |         typedef Expr &expr_param; | ||
|  |         typedef State const state; | ||
|  |         typedef State const &state_param; | ||
|  |         typedef Data data; | ||
|  |         typedef Data &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr, State &, Data &> | ||
|  |     { | ||
|  |         typedef Expr const expr; | ||
|  |         typedef Expr const &expr_param; | ||
|  |         typedef State state; | ||
|  |         typedef State &state_param; | ||
|  |         typedef Data data; | ||
|  |         typedef Data &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Expr, typename State, typename Data> | ||
|  |     struct transform_impl<Expr &, State &, Data &> | ||
|  |     { | ||
|  |         typedef Expr expr; | ||
|  |         typedef Expr &expr_param; | ||
|  |         typedef State state; | ||
|  |         typedef State &state_param; | ||
|  |         typedef Data data; | ||
|  |         typedef Data &data_param; | ||
|  |     }; | ||
|  | 
 | ||
|  | }} // namespace boost::proto | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) | ||
|  | # pragma warning(pop) | ||
|  | #endif | ||
|  | 
 | ||
|  | #endif |