123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /*==============================================================================
- 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/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>
- {
- 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(T const& 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
|