145 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			145 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================== | ||
|  |     Copyright (c) 2005-2010 Joel de Guzman | ||
|  |     Copyright (c) 2010 Thomas Heller | ||
|  | 
 | ||
|  |     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_PHOENIX_CORE_TERMINAL_HPP | ||
|  | #define BOOST_PHOENIX_CORE_TERMINAL_HPP | ||
|  | 
 | ||
|  | #include <boost/phoenix/core/limits.hpp> | ||
|  | #include <boost/call_traits.hpp> | ||
|  | #include <boost/is_placeholder.hpp> | ||
|  | #include <boost/phoenix/core/actor.hpp> | ||
|  | #include <boost/phoenix/core/meta_grammar.hpp> | ||
|  | #include <boost/phoenix/core/terminal_fwd.hpp> | ||
|  | #include <boost/proto/matches.hpp> | ||
|  | #include <boost/proto/transform/lazy.hpp> | ||
|  | #include <boost/proto/functional/fusion/at.hpp> | ||
|  | #include <boost/type_traits/remove_pointer.hpp> | ||
|  | 
 | ||
|  | #define BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(Template, Terminal, IsNullary, EvalFun)\ | ||
|  |     namespace boost { namespace phoenix                                         \ | ||
|  |     {                                                                           \ | ||
|  |         namespace result_of                                                     \ | ||
|  |         {                                                                       \ | ||
|  |             Template                                                            \ | ||
|  |             struct is_nullary<                                                  \ | ||
|  |                 custom_terminal<                                                \ | ||
|  |                     Terminal                                                    \ | ||
|  |                 >                                                               \ | ||
|  |             >                                                                   \ | ||
|  |                 : IsNullary                                                     \ | ||
|  |             {};                                                                 \ | ||
|  |         }                                                                       \ | ||
|  |         Template                                                                \ | ||
|  |         struct is_custom_terminal<Terminal >: mpl::true_ {};                    \ | ||
|  |                                                                                 \ | ||
|  |         Template                                                                \ | ||
|  |         struct custom_terminal<Terminal > : proto::call<EvalFun > {};           \ | ||
|  |     }}                                                                          \ | ||
|  | /**/ | ||
|  | 
 | ||
|  | namespace boost { namespace phoenix | ||
|  | { | ||
|  |     template <typename T, typename Dummy> | ||
|  |     struct is_custom_terminal | ||
|  |         : mpl::false_ {}; | ||
|  | 
 | ||
|  |     template <typename T, typename Dummy> | ||
|  |     struct custom_terminal; | ||
|  | 
 | ||
|  |     namespace tag { | ||
|  |       struct terminal /*: public proto::tag::terminal */ {}; | ||
|  |     } | ||
|  |   | ||
|  |     namespace expression | ||
|  |     { | ||
|  |         template <typename T, template <typename> class Actor = actor> | ||
|  |         struct terminal | ||
|  |             : proto::terminal< | ||
|  |                 T//typename call_traits<T>::value_type | ||
|  |             > | ||
|  |         { | ||
|  |             typedef | ||
|  |                 proto::basic_expr< | ||
|  |                 proto::tag::terminal | ||
|  |             // tag::terminal //cannot change to use phoenix tag - breaks code. | ||
|  |                   , proto::term<T> | ||
|  |                   , 0 | ||
|  |                 > | ||
|  |                 base_type; | ||
|  |             typedef Actor<base_type> type; | ||
|  |              | ||
|  |             static const type make(typename call_traits<T>::param_type t) | ||
|  |             { | ||
|  |             // ?? Should the next line be Actor not actor which is the default? | ||
|  |                 actor<base_type> const e = {base_type::make(t)}; | ||
|  |                 //Actor<base_type> const e = {base_type::make(t)}; | ||
|  |                 return e; | ||
|  |             } | ||
|  |         }; | ||
|  |     } | ||
|  | 
 | ||
|  |     namespace rule | ||
|  |     { | ||
|  |         struct argument | ||
|  |             : proto::if_<boost::is_placeholder<proto::_value>()> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         struct custom_terminal | ||
|  |             : proto::if_<boost::phoenix::is_custom_terminal<proto::_value>()> | ||
|  |         {}; | ||
|  |          | ||
|  |         struct terminal | ||
|  |             : proto::terminal<proto::_> | ||
|  |         {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Dummy> | ||
|  |     struct meta_grammar::case_<proto::tag::terminal, Dummy> | ||
|  |         : proto::or_< | ||
|  |             enable_rule<rule::argument       , Dummy> | ||
|  |           , enable_rule<rule::custom_terminal, Dummy> | ||
|  |           , enable_rule<rule::terminal       , Dummy> | ||
|  |         > | ||
|  |     {}; | ||
|  | 
 | ||
|  |     template <typename Dummy> | ||
|  |     struct default_actions::when<rule::custom_terminal, Dummy> | ||
|  |         : proto::lazy< | ||
|  |             custom_terminal<proto::_value>( | ||
|  |                 proto::_value | ||
|  |               , _context | ||
|  |             ) | ||
|  |         > | ||
|  |     {}; | ||
|  | 
 | ||
|  |     namespace detail | ||
|  |     { | ||
|  |         template <typename N> | ||
|  |         struct placeholder_idx | ||
|  |             : mpl::int_<N::value> | ||
|  |         {}; | ||
|  |     } | ||
|  |      | ||
|  |     template <typename Grammar> | ||
|  |     struct default_actions::when<rule::argument, Grammar> | ||
|  |         : proto::call< | ||
|  |             proto::functional::at( | ||
|  |                 _env | ||
|  |               , proto::make< | ||
|  |                     detail::placeholder_idx< | ||
|  |                         proto::make< | ||
|  |                             boost::is_placeholder<proto::_value>() | ||
|  |                         > | ||
|  |                     >() | ||
|  |                 > | ||
|  |             ) | ||
|  |         > | ||
|  |     {}; | ||
|  | }} | ||
|  | 
 | ||
|  | #endif |