diff --git a/include/boost/spirit/home/lex/argument.hpp b/include/boost/spirit/home/lex/argument.hpp index 0ba4cd28a..edfee0be3 100644 --- a/include/boost/spirit/home/lex/argument.hpp +++ b/include/boost/spirit/home/lex/argument.hpp @@ -1,6 +1,7 @@ // Copyright (c) 2001-2011 Hartmut Kaiser // Copyright (c) 2001-2011 Joel de Guzman // Copyright (c) 2010 Bryce Lelbach +// Copyright (c) 2011 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) @@ -12,18 +13,16 @@ #pragma once #endif -#include -#include -#include -#include -#include -#include +#include +#include #include +#include #include #include #include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace lex @@ -48,9 +47,11 @@ namespace boost { namespace spirit { namespace lex template struct result { - typedef typename - remove_const< - typename mpl::at_c::type + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c::type + >::type >::type context_type; @@ -92,9 +93,11 @@ namespace boost { namespace spirit { namespace lex template void eval(Env const& env) const { - typedef typename - remove_const< - typename mpl::at_c::type + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c::type + >::type >::type context_type; @@ -108,38 +111,14 @@ namespace boost { namespace spirit { namespace lex : actor_(actor) {} // see explanation for this constructor at the end of this file +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 state_setter(phoenix::actor, Actor const& actor) : actor_(actor) {} +#endif Actor actor_; }; - /////////////////////////////////////////////////////////////////////////// - // The state_context is used as a noop Phoenix actor to create the - // placeholder '_state' (see below). It is a noop actor because it is used - // as a placeholder only, while it is being converted either to a - // state_getter (if used as a rvalue) or to a state_setter (if used as a - // lvalue). The conversion is achieved by specializing and overloading a - // couple of the Phoenix templates from the Phoenix expression composition - // engine (see the end of this file). - struct state_context - { - typedef mpl::true_ no_nullary; - - template - struct result - { - typedef unused_type type; - }; - - template - unused_type - eval(Env const& env) const - { - return unused; - } - }; - /////////////////////////////////////////////////////////////////////////// // The value_getter is used to create the _val placeholder, which is a // Phoenix actor used to access the value of the current token. @@ -159,9 +138,11 @@ namespace boost { namespace spirit { namespace lex template struct result { - typedef typename - remove_const< - typename mpl::at_c::type + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c::type + >::type >::type context_type; @@ -209,39 +190,15 @@ namespace boost { namespace spirit { namespace lex value_setter(Actor const& actor) : actor_(actor) {} +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 // see explanation for this constructor at the end of this file value_setter(phoenix::actor, Actor const& actor) : actor_(actor) {} +#endif Actor actor_; }; - /////////////////////////////////////////////////////////////////////////// - // The value_context is used as a noop Phoenix actor to create the - // placeholder '_val' (see below). It is a noop actor because it is used - // as a placeholder only, while it is being converted either to a - // value_getter (if used as a rvalue) or to a value_setter (if used as a - // lvalue). The conversion is achieved by specializing and overloading a - // couple of the Phoenix templates from the Phoenix expression composition - // engine (see the end of this file). - struct value_context - { - typedef mpl::true_ no_nullary; - - template - struct result - { - typedef unused_type type; - }; - - template - unused_type - eval(Env const& env) const - { - return unused; - } - }; - /////////////////////////////////////////////////////////////////////////// // The eoi_getter is used to create the _eoi placeholder, which is a // Phoenix actor used to access the end of input iterator pointing to the @@ -263,9 +220,11 @@ namespace boost { namespace spirit { namespace lex template struct result { - typedef typename - remove_const< - typename mpl::at_c::type + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c::type + >::type >::type context_type; @@ -283,33 +242,47 @@ namespace boost { namespace spirit { namespace lex /////////////////////////////////////////////////////////////////////////// // '_start' and '_end' may be used to access the start and the end of // the matched sequence of the current token - phoenix::actor > const _start = phoenix::argument<0>(); - phoenix::actor > const _end = phoenix::argument<1>(); + typedef phoenix::arg_names::_1_type _start_type; + typedef phoenix::arg_names::_2_type _end_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + _start_type const _start = _start_type(); + _end_type const _end = _end_type(); +#endif // We are reusing the placeholder '_pass' to access and change the pass // status of the current match (see support/argument.hpp for its // definition). + // typedef phoenix::arg_names::_3_type _pass_type; + using boost::spirit::_pass_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS using boost::spirit::_pass; +#endif // '_tokenid' may be used to access and change the tokenid of the current // token - phoenix::actor > const _tokenid = phoenix::argument<3>(); + typedef phoenix::arg_names::_4_type _tokenid_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + _tokenid_type const _tokenid = _tokenid_type(); +#endif + typedef phoenix::actor _val_type; + typedef phoenix::actor _state_type; + typedef phoenix::actor _eoi_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS // '_val' may be used to access and change the token value of the current // token - phoenix::actor const _val = value_context(); - + _val_type const _val = _val_type(); // _state may be used to access and change the name of the current lexer // state - phoenix::actor const _state = state_context(); - + _state_type const _state = _state_type(); // '_eoi' may be used to access the end of input iterator of the input // stream used by the lexer to match tokens from - phoenix::actor const _eoi = eoi_getter(); - + _eoi_type const _eoi = _eoi_type(); +#endif }}} /////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 namespace boost { namespace phoenix { /////////////////////////////////////////////////////////////////////////// @@ -382,6 +355,7 @@ namespace boost { namespace phoenix typedef spirit::lex::value_setter::type> type; }; }} +#endif #undef SPIRIT_DECLARE_ARG #endif diff --git a/include/boost/spirit/home/lex/argument_phoenix.hpp b/include/boost/spirit/home/lex/argument_phoenix.hpp new file mode 100644 index 000000000..9d0183bbf --- /dev/null +++ b/include/boost/spirit/home/lex/argument_phoenix.hpp @@ -0,0 +1,220 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 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) + +#if !defined(BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM) +#define BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // The value_context is used as a noop Phoenix actor to create the + // placeholder '_val' (see below). It is a noop actor because it is used + // as a placeholder only, while it is being converted either to a + // value_getter (if used as a rvalue) or to a value_setter (if used as a + // lvalue). The conversion is achieved by specializing and overloading a + // couple of the Phoenix templates from the Phoenix expression composition + // engine (see the end of this file). + struct value_context + { + typedef mpl::true_ no_nullary; + + template + struct result + { + typedef unused_type type; + }; + + template + unused_type + eval(Env const& env) const + { + return unused; + } + }; + + // forward declarations + struct value_getter; + template struct value_setter; + + /////////////////////////////////////////////////////////////////////////// + // The state_context is used as a noop Phoenix actor to create the + // placeholder '_state' (see below). It is a noop actor because it is used + // as a placeholder only, while it is being converted either to a + // state_getter (if used as a rvalue) or to a state_setter (if used as a + // lvalue). The conversion is achieved by specializing and overloading a + // couple of the Phoenix templates from the Phoenix expression composition + // engine (see the end of this file). + struct state_context + { + typedef mpl::true_ no_nullary; + + template + struct result + { + typedef unused_type type; + }; + + template + unused_type + eval(Env const& env) const + { + return unused; + } + }; + + // forward declarations + struct state_getter; + template struct state_setter; + struct eoi_getter; +}}} + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template<> + , boost::spirit::lex::value_context + , mpl::false_ + , v2_eval( + proto::make + , proto::call< + functional::env(proto::_state) + > + ) +) + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template<> + , boost::spirit::lex::state_context + , mpl::false_ + , v2_eval( + proto::make + , proto::call< + functional::env(proto::_state) + > + ) +) + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template<> + , boost::spirit::lex::eoi_getter + , mpl::false_ + , v2_eval( + proto::make + , proto::call< + functional::env(proto::_state) + > + ) +) + +/////////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_SPIRIT_USE_PHOENIX_V3 + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(value_setter) + , (boost::phoenix::meta_grammar) +) + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(state_setter) + , (boost::phoenix::meta_grammar) +) + +namespace boost { namespace phoenix +{ + template + struct is_nullary::when + : proto::make + {}; + + template + struct default_actions::when + : proto::call< + v2_eval( + proto::make< + spirit::lex::value_setter( + proto::_child0 + ) + > + , _env + ) + > + {}; + + template <> + struct actor + : boost::phoenix::actor::type> + { + typedef boost::phoenix::actor< + typename proto::terminal::type + > base_type; + + actor(base_type const & base = base_type()) + : base_type(base) + {} + + template + typename spirit::lex::expression::value_setter< + typename phoenix::as_actor::type>::type const + operator=(Expr const & expr) const + { + return + spirit::lex::expression::value_setter< + typename phoenix::as_actor::type + >::make(phoenix::as_actor::convert(expr)); + } + }; + + template + struct is_nullary::when + : proto::make + {}; + + template + struct default_actions::when + : proto::call< + v2_eval( + proto::make< + spirit::lex::state_setter( + proto::_child0 + ) + > + , _env + ) + > + {}; + + template <> + struct actor + : boost::phoenix::actor::type> + { + typedef boost::phoenix::actor< + typename proto::terminal::type + > base_type; + + actor(base_type const & base = base_type()) + : base_type(base) + {} + + template + typename spirit::lex::expression::state_setter< + typename phoenix::as_actor::type>::type const + operator=(Expr const & expr) const + { + return + spirit::lex::expression::state_setter< + typename phoenix::as_actor::type + >::make(phoenix::as_actor::convert(expr)); + } + }; +}} + +#endif // BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/include/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp b/include/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp index 1ef3914ad..50adff66a 100644 --- a/include/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp +++ b/include/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp @@ -13,10 +13,10 @@ #pragma once #endif -#include -#include -#include -#include +#include +#include +#include + #include #include @@ -40,9 +40,11 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl // wrap phoenix actor struct phoenix_action { + typedef void result_type; + template - struct result { typedef void type; }; + struct result { typedef result_type type; }; template void operator()(phoenix::actor const& f, Iterator& start diff --git a/include/boost/spirit/home/lex/lexer/support_functions.hpp b/include/boost/spirit/home/lex/lexer/support_functions.hpp index eeae6c1fe..d995d5a7a 100644 --- a/include/boost/spirit/home/lex/lexer/support_functions.hpp +++ b/include/boost/spirit/home/lex/lexer/support_functions.hpp @@ -10,14 +10,12 @@ #pragma once #endif -#include -#include -#include -#include -#include +#include #include #include +#include + /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace lex { @@ -72,13 +70,14 @@ namespace boost { namespace spirit { namespace lex }; // The function lex::less() is used to create a Phoenix actor allowing to - // implement functionality similar to flex' function yyless(). + // implement functionality similar to flex' function yyless(). template - inline phoenix::actor::type> > + inline typename expression::less< + typename phoenix::as_actor::type + >::type const less(T const& v) { - typedef typename phoenix::as_actor::type actor_type; - return less_type(phoenix::as_actor::convert(v)); + return expression::less::make(phoenix::as_actor::convert(v)); } /////////////////////////////////////////////////////////////////////////// @@ -115,10 +114,10 @@ namespace boost { namespace spirit { namespace lex // The function lex::more() is used to create a Phoenix actor allowing to // implement functionality similar to flex' function yymore(). - inline phoenix::actor - more() + //inline expression::more::type const + inline phoenix::actor more() { - return more_type(); + return phoenix::actor(); } /////////////////////////////////////////////////////////////////////////// @@ -156,27 +155,27 @@ namespace boost { namespace spirit { namespace lex // The function lex::lookahead() is used to create a Phoenix actor // allowing to implement functionality similar to flex' lookahead operator - // a/b. + // a/b. template - inline phoenix::actor< - lookahead_type< - typename phoenix::as_actor::type - , typename phoenix::as_actor::type> > + inline typename expression::lookahead< + typename phoenix::as_actor::type + , typename phoenix::as_actor::type + >::type const lookahead(T const& id) { typedef typename phoenix::as_actor::type id_actor_type; typedef typename phoenix::as_actor::type state_actor_type; - return lookahead_type( + return expression::lookahead::make( phoenix::as_actor::convert(id), phoenix::as_actor::convert(std::size_t(~0))); } template - inline phoenix::actor< - lookahead_type< - typename phoenix::as_actor::type - , typename phoenix::as_actor::type> > + inline typename expression::lookahead< + typename phoenix::as_actor::type + , typename phoenix::as_actor::type + >::type const lookahead(token_def const& tok) { typedef typename phoenix::as_actor::type id_actor_type; @@ -189,8 +188,8 @@ namespace boost { namespace spirit { namespace lex // lexer. BOOST_ASSERT(std::size_t(~0) != state && "token_def instance not associated with lexer yet"); - - return lookahead_type( + + return expression::lookahead::make( phoenix::as_actor::convert(tok.id()), phoenix::as_actor::convert(state)); } diff --git a/include/boost/spirit/home/lex/lexer/support_functions_expression.hpp b/include/boost/spirit/home/lex/lexer/support_functions_expression.hpp new file mode 100644 index 000000000..7608b13fd --- /dev/null +++ b/include/boost/spirit/home/lex/lexer/support_functions_expression.hpp @@ -0,0 +1,118 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 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) + +#if !defined(SPIRIT_LEX_SUPPORT_FUNCTIONS_EXPRESSION_MAR_22_2011_0711PM) +#define SPIRIT_LEX_SUPPORT_FUNCTIONS_EXPRESSION_MAR_22_2011_0711PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost { namespace spirit { namespace lex +{ + template struct less_type; + struct more_type; + template struct lookahead_type; +}}} + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template <> + , boost::spirit::lex::more_type + , mpl::false_ + , v2_eval( + proto::make + , proto::call + ) +) + +/////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + +namespace boost { namespace spirit { namespace lex +{ + namespace expression + { + template + struct less + { + typedef phoenix::actor > type; + + static type make(Eval const & eval) + { + return lex::less_type(eval); + } + }; + + template + struct lookahead + { + typedef phoenix::actor > type; + + static type make(IdType const & id_type, State const & state) + { + return lex::lookahead_type(id_type, state); + } + }; + } +}}} + +#else // BOOST_SPIRIT_USE_PHOENIX_V3 + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(less) + , (boost::phoenix::meta_grammar) +) + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(lookahead) + , (boost::phoenix::meta_grammar) + (boost::phoenix::meta_grammar) +) + +namespace boost { namespace phoenix +{ + template + struct is_nullary::when + : proto::make + {}; + + template + struct default_actions::when + : proto::call< + v2_eval( + spirit::lex::less_type(proto::_child0) + , _env + ) + > + {}; + + template + struct is_nullary::when + : proto::make + {}; + + template + struct default_actions::when + : proto::call< + v2_eval( + spirit::lex::lookahead_type< + proto::_child0 + , proto::_child1 + >( + proto::_child0 + , proto::_child1 + ) + , _env + ) + > + {}; +}} + +#endif // BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/include/boost/spirit/home/phoenix/core/argument.hpp b/include/boost/spirit/home/phoenix/core/argument.hpp index 3e71f7f16..1679cb2b3 100644 --- a/include/boost/spirit/home/phoenix/core/argument.hpp +++ b/include/boost/spirit/home/phoenix/core/argument.hpp @@ -21,10 +21,14 @@ #include #include -#define PHOENIX_DECLARE_ARG(z, n, data) \ - actor > const \ - BOOST_PP_CAT(arg, BOOST_PP_INC(n)) = argument(); \ - actor > const \ +#define PHOENIX_DECLARE_ARG(z, n, data) \ + typedef actor > \ + BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type); \ + actor > const \ + BOOST_PP_CAT(arg, BOOST_PP_INC(n)) = argument(); \ + typedef actor > \ + BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ + actor > const \ BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument(); namespace boost { namespace phoenix @@ -69,13 +73,19 @@ namespace boost { namespace phoenix namespace arg_names { // Phoenix style names + typedef actor > arg1_type; actor > const arg1 = argument<0>(); + typedef actor > arg2_type; actor > const arg2 = argument<1>(); + typedef actor > arg3_type; actor > const arg3 = argument<2>(); // BLL style names + typedef actor > _1_type; actor > const _1 = argument<0>(); + typedef actor > _2_type; actor > const _2 = argument<1>(); + typedef actor > _3_type; actor > const _3 = argument<2>(); // Bring in the rest or the Phoenix style arguments (arg4 .. argN+1) diff --git a/include/boost/spirit/home/support/action_dispatch.hpp b/include/boost/spirit/home/support/action_dispatch.hpp index 0a2a56513..7b9bccf09 100644 --- a/include/boost/spirit/home/support/action_dispatch.hpp +++ b/include/boost/spirit/home/support/action_dispatch.hpp @@ -13,7 +13,16 @@ #pragma once #endif -#include +#include + +#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_LAMBDAS) && \ + !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_DECLTYPE) +#include +#include +#endif + + +#include #include namespace boost { namespace spirit { namespace traits @@ -21,6 +30,130 @@ namespace boost { namespace spirit { namespace traits template struct action_dispatch { +#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_LAMBDAS) && \ + !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_DECLTYPE) + // omit function parameters without specializing for each possible + // type of callable entity + // many thanks to Eelis/##iso-c++ for this contribution + + private: + // this will be used to pass around POD types which are safe + // to go through the ellipsis operator (if ever used) + template + struct fwd_tag {}; + + // the first parameter is a placeholder to obtain SFINAE when + // doing overload resolution, the second one is the actual + // forwarder, where we can apply our implementation + template + struct fwd_storage { typedef T type; }; + + // gcc should accept fake() but it prints a sorry, needs + // a check once the bug is sorted out, use a FAKE_CALL macro for now + template + T fake_call(); + +#define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0) + + // the forwarders, here we could tweak the implementation of + // how parameters are passed to the functions, if needed + struct fwd_none + { + template + auto operator()(F && f, Rest&&...) -> decltype(f()) + { + return f(); + } + }; + + struct fwd_attrib + { + template + auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a)) + { + return f(a); + } + }; + + struct fwd_attrib_context + { + template + auto operator()(F && f, A && a, B && b, Rest&&...) + -> decltype(f(a, b)) + { + return f(a, b); + } + }; + + struct fwd_attrib_context_pass + { + template + auto operator()(F && f, A && a, B && b, C && c, Rest&&...) + -> decltype(f(a, b, c)) + { + return f(a, b, c); + } + }; + + // SFINAE for our calling syntax, the forwarders are stored based + // on what function call gives a proper result + // this code can probably be more generic once implementations are + // steady + template + static auto do_call(F && f, ...) + -> typename fwd_storage::type + { + return {}; + } + + template + static auto do_call(F && f, fwd_tag, ...) + -> typename fwd_storage::type + { + return {}; + } + + template + static auto do_call(F && f, fwd_tag, fwd_tag, ...) + -> typename fwd_storage< + decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B))) + , fwd_attrib_context>::type + { + return {}; + } + + template + static auto do_call(F && f, fwd_tag, fwd_tag, fwd_tag, ...) + -> typename fwd_storage< + decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B) + , BOOST_SPIRIT_FAKE_CALL(C))) + , fwd_attrib_context_pass>::type + { + return {}; + } + + // this function calls the forwarder and is responsible for + // stripping the tail of the parameters + template + static void caller(F && f, A && ... a) + { + do_call(f, fwd_tag::type>()...) + (std::forward(f), std::forward(a)...); + } + +#undef BOOST_SPIRIT_FAKE_CALL + + public: + template + bool operator()(F const& f, Attribute& attr, Context& context) + { + bool pass = true; + caller(f, attr, context, pass); + return pass; + } +#else // general handler for everything not explicitly specialized below template bool operator()(F const& f, Attribute& attr, Context& context) @@ -29,6 +162,7 @@ namespace boost { namespace spirit { namespace traits f(attr, context, pass); return pass; } +#endif // handler for phoenix actors diff --git a/include/boost/spirit/home/support/argument.hpp b/include/boost/spirit/home/support/argument.hpp index 7dfaded17..3a84574ad 100644 --- a/include/boost/spirit/home/support/argument.hpp +++ b/include/boost/spirit/home/support/argument.hpp @@ -1,5 +1,7 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 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) @@ -13,45 +15,79 @@ #include #include -#include -#include +#include #include +#include #include #include #include #include -#if !defined(SPIRIT_ARGUMENTS_LIMIT) -# define SPIRIT_ARGUMENTS_LIMIT PHOENIX_LIMIT -#endif - #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS -#define SPIRIT_DECLARE_ARG(z, n, data) \ - typedef phoenix::actor > const \ - BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ - phoenix::actor > const \ - BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument(); +#define SPIRIT_DECLARE_ARG(z, n, data) \ + typedef phoenix::actor > const \ + BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ + phoenix::actor > const \ + BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \ + BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \ /***/ -#define SPIRIT_USING_ARGUMENT(z, n, data) \ - using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ - using spirit::BOOST_PP_CAT(_, n); +#define SPIRIT_USING_ARGUMENT(z, n, data) \ + using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ + using spirit::BOOST_PP_CAT(_, n); \ /***/ #else -#define SPIRIT_DECLARE_ARG(z, n, data) \ - typedef phoenix::actor > const \ - BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); +#define SPIRIT_DECLARE_ARG(z, n, data) \ + typedef phoenix::actor > const \ + BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ /***/ -#define SPIRIT_USING_ARGUMENT(z, n, data) \ - using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ +#define SPIRIT_USING_ARGUMENT(z, n, data) \ + using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ /***/ #endif +namespace boost { namespace spirit +{ + template + struct argument; + + template + struct attribute_context; +}} + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template + , boost::spirit::argument + , mpl::false_ // is not nullary + , v2_eval( + proto::make< + boost::spirit::argument() + > + , proto::call< + functional::env(proto::_state) + > + ) +) + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template + , boost::spirit::attribute_context + , mpl::false_ // is not nullary + , v2_eval( + proto::make< + boost::spirit::attribute_context() + > + , proto::call< + functional::env(proto::_state) + > + ) +) + namespace boost { namespace spirit { namespace result_of @@ -91,6 +127,7 @@ namespace boost { namespace spirit return result_of::get_arg::call(val); } + template struct attribute_context { typedef mpl::true_ no_nullary; @@ -138,9 +175,9 @@ namespace boost { namespace spirit }; // _0 refers to the whole attribute as generated by the lhs parser - typedef phoenix::actor const _0_type; + typedef phoenix::actor > const _0_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS - _0_type _0 = attribute_context(); + _0_type _0 = _0_type(); #endif // _1, _2, ... refer to the attributes of the single components the lhs @@ -150,15 +187,15 @@ namespace boost { namespace spirit typedef phoenix::actor > const _3_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS - _1_type _1 = argument<0>(); - _2_type _2 = argument<1>(); - _3_type _3 = argument<2>(); + _1_type _1 = _1_type(); + _2_type _2 = _2_type(); + _3_type _3 = _3_type(); #endif // '_pass' may be used to make a match fail in retrospective - typedef phoenix::actor > const _pass_type; + typedef phoenix::arg_names::_3_type const _pass_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS - _pass_type _pass = phoenix::argument<2>(); + _pass_type _pass = _pass_type(); #endif // Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP diff --git a/include/boost/spirit/home/support/argument_expression.hpp b/include/boost/spirit/home/support/argument_expression.hpp new file mode 100644 index 000000000..659470468 --- /dev/null +++ b/include/boost/spirit/home/support/argument_expression.hpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2011 Thomas Heller + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 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) +==============================================================================*/ +#if !defined(BOOST_SPIRIT_ARGUMENT_MARCH_22_2011_0939PM) +#define BOOST_SPIRIT_ARGUMENT_MARCH_22_2011_0939PM + +#include + +namespace boost { namespace spirit +{ + template + struct argument; + + template + struct attribute_context; + + namespace expression + { +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + template + struct argument + { + typedef phoenix::actor > type; + + static type make() + { + return spirit::argument(); + } + }; + + template + struct attribute_context + { + typedef phoenix::actor > type; + + static type make() + { + return spirit::attribute_context(); + } + }; +#else + template + struct argument + : phoenix::expression::terminal > + { + typedef typename phoenix::expression::terminal< + spirit::argument + >::type type; + + static type make() + { + type const e = {{{}}}; + return e; + } + }; + + template + struct attribute_context + : phoenix::expression::terminal > + { + typedef typename phoenix::expression::terminal< + spirit::attribute_context + >::type type; + + static type make() + { + type const e = {{{}}}; + return e; + } + }; +#endif + } +}} + +#ifdef BOOST_SPIRIT_USE_PHOENIX_V3 +namespace boost { namespace phoenix +{ + namespace result_of + { + template + struct is_nullary > > + : mpl::false_ + {}; + + template + struct is_nullary > > + : mpl::false_ + {}; + } + + template + struct is_custom_terminal > + : mpl::true_ + {}; + + template + struct is_custom_terminal > + : mpl::true_ + {}; + + template + struct custom_terminal > + : proto::call< + v2_eval(spirit::attribute_context(), _env) + > + {}; + + template + struct custom_terminal > + : proto::call< + v2_eval(spirit::argument(), _env(proto::_, proto::_state, int())) + > + {}; +}} +#endif // BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/include/boost/spirit/home/support/char_class.hpp b/include/boost/spirit/home/support/char_class.hpp index ff7033a2f..b4d036168 100644 --- a/include/boost/spirit/home/support/char_class.hpp +++ b/include/boost/spirit/home/support/char_class.hpp @@ -269,6 +269,7 @@ namespace boost { namespace spirit { namespace tag struct char_code : char_code_base, char_encoding_base { + typedef void is_spirit_tag; typedef CharEncoding char_encoding; // e.g. ascii typedef CharClass char_class; // e.g. tag::alnum }; diff --git a/include/boost/spirit/home/support/context.hpp b/include/boost/spirit/home/support/context.hpp index 543b01aff..b20c5750e 100644 --- a/include/boost/spirit/home/support/context.hpp +++ b/include/boost/spirit/home/support/context.hpp @@ -1,5 +1,7 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 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) @@ -12,11 +14,11 @@ #endif #include +#include #include #include #include -#include -#include +#include #include #include #include @@ -24,35 +26,69 @@ #include #include -#if !defined(SPIRIT_ATTRIBUTES_LIMIT) -# define SPIRIT_ATTRIBUTES_LIMIT PHOENIX_LIMIT -#endif - +/////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS -#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ - typedef phoenix::actor > const \ - BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ - phoenix::actor > const \ - BOOST_PP_CAT(_r, n) = attribute(); - -#define SPIRIT_USING_ATTRIBUTE(z, n, data) \ - using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ - using spirit::BOOST_PP_CAT(_r, n); \ +#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ + typedef phoenix::actor > \ + BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ + phoenix::actor > const \ + BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)(); + /***/ +#define SPIRIT_USING_ATTRIBUTE(z, n, data) \ + using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ + using spirit::BOOST_PP_CAT(_r, n); \ /***/ #else -#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ - typedef phoenix::actor > const \ - BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ - -#define SPIRIT_USING_ATTRIBUTE(z, n, data) \ - using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ +#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ + typedef phoenix::actor > \ + BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ + /***/ +#define SPIRIT_USING_ATTRIBUTE(z, n, data) \ + using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ /***/ #endif +namespace boost { namespace spirit +{ + template + struct attribute; + + template + struct local_variable; +}} + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template + , boost::spirit::attribute + , mpl::false_ // is not nullary + , v2_eval( + proto::make< + boost::spirit::attribute() + > + , proto::call< + functional::env(proto::_state) + > + ) +) + +BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( + template + , boost::spirit::local_variable + , mpl::false_ // is not nullary + , v2_eval( + proto::make< + boost::spirit::local_variable() + > + , proto::call< + functional::env(proto::_state) + > + ) +) + namespace boost { namespace spirit { template @@ -99,6 +135,11 @@ namespace boost { namespace spirit typedef typename Context::attributes_type const type; }; + template + struct attributes_of + : attributes_of + {}; + template struct locals_of { @@ -111,6 +152,12 @@ namespace boost { namespace spirit typedef typename Context::locals_type const type; }; + template + struct locals_of + { + typedef typename Context::locals_type type; + }; + template struct attribute { @@ -182,21 +229,19 @@ namespace boost { namespace spirit return get_arg((fusion::at_c<1>(env.args())).locals); } }; - + typedef phoenix::actor > const _val_type; typedef phoenix::actor > const _r0_type; typedef phoenix::actor > const _r1_type; typedef phoenix::actor > const _r2_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS - // _val refers to the 'return' value of a rule (same as _r0) // _r1, _r2, ... refer to the rule arguments - _val_type _val = attribute<0>(); - _r0_type _r0 = attribute<0>(); - _r1_type _r1 = attribute<1>(); - _r2_type _r2 = attribute<2>(); - + _val_type _val = _val_type(); + _r0_type _r0 = _r0_type(); + _r1_type _r1 = _r1_type(); + _r2_type _r2 = _r2_type(); #endif // Bring in the rest of the attributes (_r4 .. _rN+1), using PP @@ -215,20 +260,19 @@ namespace boost { namespace spirit typedef phoenix::actor > const _j_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS - // _a, _b, ... refer to the local variables of a rule - _a_type _a = local_variable<0>(); - _b_type _b = local_variable<1>(); - _c_type _c = local_variable<2>(); - _d_type _d = local_variable<3>(); - _e_type _e = local_variable<4>(); - _f_type _f = local_variable<5>(); - _g_type _g = local_variable<6>(); - _h_type _h = local_variable<7>(); - _i_type _i = local_variable<8>(); - _j_type _j = local_variable<9>(); - + _a_type _a = _a_type(); + _b_type _b = _b_type(); + _c_type _c = _c_type(); + _d_type _d = _d_type(); + _e_type _e = _e_type(); + _f_type _f = _f_type(); + _g_type _g = _g_type(); + _h_type _h = _h_type(); + _i_type _i = _i_type(); + _j_type _j = _j_type(); #endif + // You can bring these in with the using directive // without worrying about bringing in too much. namespace labels diff --git a/include/boost/spirit/home/support/limits.hpp b/include/boost/spirit/home/support/limits.hpp new file mode 100644 index 000000000..ff53967f1 --- /dev/null +++ b/include/boost/spirit/home/support/limits.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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) + +#if !defined(BOOST_SPIRIT_SUPPORT_LIMITS_MAR_26_2011_0833PM) +#define BOOST_SPIRIT_SUPPORT_LIMITS_MAR_26_2011_0833PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + +#if !defined(SPIRIT_ARGUMENTS_LIMIT) +# define SPIRIT_ARGUMENTS_LIMIT PHOENIX_LIMIT +#endif +#if !defined(SPIRIT_ATTRIBUTES_LIMIT) +# define SPIRIT_ATTRIBUTES_LIMIT PHOENIX_LIMIT +#endif + +#else + +#if !defined(SPIRIT_ARGUMENTS_LIMIT) +# define SPIRIT_ARGUMENTS_LIMIT BOOST_PHOENIX_LIMIT +#endif +#if !defined(SPIRIT_ATTRIBUTES_LIMIT) +# define SPIRIT_ATTRIBUTES_LIMIT BOOST_PHOENIX_LIMIT +#endif + +#endif + +#endif diff --git a/include/boost/spirit/home/support/make_component.hpp b/include/boost/spirit/home/support/make_component.hpp index 8ece2cf13..4c88bb95d 100644 --- a/include/boost/spirit/home/support/make_component.hpp +++ b/include/boost/spirit/home/support/make_component.hpp @@ -12,6 +12,7 @@ #pragma once #endif +#include #include #include #include @@ -321,11 +322,25 @@ namespace boost { namespace spirit { namespace detail )>::type lhs_component; +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 typedef typename proto::result_of::value< typename proto::result_of::child_c::type >::type rhs_component; +#else + typedef + typename mpl::eval_if_c< + phoenix::is_actor< + typename proto::result_of::child_c::type + >::type::value + , proto::result_of::child_c + , proto::result_of::value< + typename proto::result_of::child_c::type + > + >::type + rhs_component; +#endif typedef typename result_of::make_cons< @@ -341,6 +356,7 @@ namespace boost { namespace spirit { namespace detail result::type result_type; +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 result_type operator()( typename impl::expr_param expr , typename impl::state_param state @@ -357,6 +373,60 @@ namespace boost { namespace spirit { namespace detail return make_component_()(elements, data); } +#else + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + ) const + { + return + (*this)( + expr + , state + , data + , typename phoenix::is_actor< + typename proto::result_of::child_c::type + >::type() + ); + } + + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + , mpl::false_ + ) const + { + elements_type elements = + detail::make_cons( + Grammar()( + proto::child_c<0>(expr), state, data) // LHS + , detail::make_cons( + proto::value(proto::child_c<1>(expr))) // RHS + ); + + return make_component_()(elements, data); + } + + result_type operator()( + typename impl::expr_param expr + , typename impl::state_param state + , typename impl::data_param data + , mpl::true_ + ) const + { + elements_type elements = + detail::make_cons( + Grammar()( + proto::child_c<0>(expr), state, data) // LHS + , detail::make_cons( + proto::child_c<1>(expr)) // RHS + ); + + return make_component_()(elements, data); + } +#endif }; }; }}} diff --git a/include/boost/spirit/home/support/terminal.hpp b/include/boost/spirit/home/support/terminal.hpp index 2ad4c533a..0c05c80e7 100644 --- a/include/boost/spirit/home/support/terminal.hpp +++ b/include/boost/spirit/home/support/terminal.hpp @@ -1,5 +1,7 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 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) @@ -11,15 +13,17 @@ #pragma once #endif -#include -#include #include #include +#include +#include #include #include #include #include +#include + namespace boost { namespace spirit { template @@ -84,11 +88,7 @@ namespace boost { namespace spirit proto::terminal< lazy_terminal< typename F::terminal_type - , phoenix::actor< - typename phoenix::as_composite< - phoenix::detail::function_eval<1>, F, A0 - >::type - > + , typename phoenix::expression::function::type , 1 // arity > >::type @@ -100,7 +100,7 @@ namespace boost { namespace spirit { typedef typename result_type::proto_child0 child_type; return result_type::make(child_type( - phoenix::compose >(f, _0) + phoenix::expression::function::make(f, _0) , f.proto_base().child0 )); } @@ -113,11 +113,7 @@ namespace boost { namespace spirit proto::terminal< lazy_terminal< typename F::terminal_type - , phoenix::actor< - typename phoenix::as_composite< - phoenix::detail::function_eval<2>, F, A0, A1 - >::type - > + , typename phoenix::expression::function::type , 2 // arity > >::type @@ -129,7 +125,7 @@ namespace boost { namespace spirit { typedef typename result_type::proto_child0 child_type; return result_type::make(child_type( - phoenix::compose >(f, _0, _1) + phoenix::expression::function::make(f, _0, _1) , f.proto_base().child0 )); } @@ -142,11 +138,7 @@ namespace boost { namespace spirit proto::terminal< lazy_terminal< typename F::terminal_type - , phoenix::actor< - typename phoenix::as_composite< - phoenix::detail::function_eval<3>, F, A0, A1, A2 - >::type - > + , typename phoenix::expression::function::type , 3 // arity > >::type @@ -158,7 +150,7 @@ namespace boost { namespace spirit { typedef typename result_type::proto_child0 child_type; return result_type::make(child_type( - phoenix::compose >(f, _0, _1, _2) + phoenix::expression::function::make(f, _0, _1, _2) , f.proto_base().child0 )); } @@ -167,14 +159,19 @@ namespace boost { namespace spirit namespace detail { // Helper struct for SFINAE purposes - template - struct bool_; + template struct bool_; + template <> struct bool_ : mpl::bool_ - { typedef bool_* is_true; }; + { + typedef bool_* is_true; + }; + template <> struct bool_ : mpl::bool_ - { typedef bool_* is_false; }; + { + typedef bool_* is_false; + }; // Metafunction to detect if at least one arg is a Phoenix actor template < @@ -184,10 +181,10 @@ namespace boost { namespace spirit > struct contains_actor : bool_< - phoenix::is_actor::value - || phoenix::is_actor::value - || phoenix::is_actor::value - > + phoenix::is_actor::value + || phoenix::is_actor::value + || phoenix::is_actor::value + > {}; // to_lazy_arg: convert a terminal arg type to the type make_lazy needs @@ -200,6 +197,11 @@ namespace boost { namespace spirit struct to_lazy_arg : to_lazy_arg {}; + + template + struct to_lazy_arg + : to_lazy_arg + {}; template <> struct to_lazy_arg @@ -221,6 +223,11 @@ namespace boost { namespace spirit : to_nonlazy_arg {}; + template + struct to_nonlazy_arg + : to_nonlazy_arg + {}; + template <> struct to_nonlazy_arg { @@ -247,7 +254,8 @@ namespace boost { namespace spirit terminal() {} terminal(Terminal const& t) - : base_type(proto::terminal::type::make(t)) {} + : base_type(proto::terminal::type::make(t)) + {} template < bool Lazy @@ -307,6 +315,40 @@ namespace boost { namespace spirit type; }; + template + struct result + { + typedef typename + result_helper< + detail::contains_actor::value + , A0, unused_type, unused_type + >::type + type; + }; + + template + struct result + { + typedef typename + result_helper< + detail::contains_actor::value + , A0, A1, unused_type + >::type + type; + }; + + + template + struct result + { + typedef typename + result_helper< + detail::contains_actor::value + , A0, A1, A2 + >::type + type; + }; + // Note: in the following overloads, SFINAE cannot // be done on return type because of gcc bug #24915: // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24915 @@ -360,7 +402,6 @@ namespace boost { namespace spirit // Lazy overloads. Enabled when at // least one arg is a Phoenix actor. - template typename result::type operator()(A0 const& _0 @@ -441,10 +482,13 @@ namespace boost { namespace spirit // support for stateful tag types namespace tag { - template struct stateful_tag { + typedef void is_spirit_tag; + typedef Data data_type; stateful_tag() {} @@ -458,7 +502,8 @@ namespace boost { namespace spirit }; } - template struct stateful_tag_type : spirit::terminal > @@ -467,7 +512,8 @@ namespace boost { namespace spirit stateful_tag_type() {} stateful_tag_type(Data const& data) - : spirit::terminal(data) {} + : spirit::terminal(data) + {} private: // silence MSVC warning C4512: assignment operator could not be generated @@ -493,6 +539,28 @@ namespace boost { namespace spirit }} +#ifdef BOOST_SPIRIT_USE_PHOENIX_V3 +namespace boost { namespace phoenix +{ + template + struct is_custom_terminal + : mpl::true_ + {}; + + template + struct custom_terminal + { + typedef spirit::terminal result_type; + + template + result_type operator()(Tag const & t, Context const &) + { + return spirit::terminal(t); + } + }; +}} +#endif + // Define a spirit terminal. This macro may be placed in any namespace. // Common placeholders are placed in the main boost::spirit namespace // (see common_terminals.hpp) @@ -505,7 +573,7 @@ namespace boost { namespace spirit #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS #define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \ - namespace tag { struct name {}; } \ + namespace tag { struct name { typedef void is_spirit_tag; }; } \ typedef boost::proto::terminal::type type_name; \ type_name const name = {{}}; \ inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \ @@ -514,7 +582,7 @@ namespace boost { namespace spirit #else #define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \ - namespace tag { struct name {}; } \ + namespace tag { struct name { typedef void is_spirit_tag; }; } \ typedef boost::proto::terminal::type type_name; \ /***/ @@ -543,7 +611,7 @@ namespace boost { namespace spirit #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS #define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \ - namespace tag { struct name {}; } \ + namespace tag { struct name { typedef void is_spirit_tag; }; } \ typedef boost::spirit::terminal type_name; \ type_name const name = type_name(); \ inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \ @@ -552,7 +620,7 @@ namespace boost { namespace spirit #else #define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \ - namespace tag { struct name {}; } \ + namespace tag { struct name { typedef void is_spirit_tag; }; } \ typedef boost::spirit::terminal type_name; \ /***/ diff --git a/include/boost/spirit/home/support/terminal_expression.hpp b/include/boost/spirit/home/support/terminal_expression.hpp new file mode 100644 index 000000000..2fea1b211 --- /dev/null +++ b/include/boost/spirit/home/support/terminal_expression.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 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) +==============================================================================*/ +#if !defined(BOOST_SPIRIT_TERMINAL_EXPRESSION_MARCH_24_2011_1210AM) +#define BOOST_SPIRIT_TERMINAL_EXPRESSION_MARCH_24_2011_1210AM + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + +namespace boost { namespace phoenix +{ + namespace expression + { + template < + typename F, typename A0 = void, typename A1 = void + , typename A2 = void, typename Dummy = void> + struct function; + + template + struct function + { + typedef phoenix::actor< + typename phoenix::as_composite< + phoenix::detail::function_eval<1>, F, A0 + >::type + > type; + + static type make(F f, A0 const & _0) + { + return phoenix::compose< + phoenix::detail::function_eval<1> >(f, _0); + } + }; + + template + struct function + { + typedef phoenix::actor< + typename phoenix::as_composite< + phoenix::detail::function_eval<2>, F, A0, A1 + >::type + > type; + + static type make(F f, A0 const & _0, A1 const & _1) + { + return phoenix::compose< + phoenix::detail::function_eval<2> >(f, _0, _1); + } + }; + + template + struct function + { + typedef phoenix::actor< + typename phoenix::as_composite< + phoenix::detail::function_eval<3>, F, A0, A1, A2 + >::type + > type; + + static type make(F f, A0 const & _0, A1 const & _1, A2 const & _2) + { + return phoenix::compose< + phoenix::detail::function_eval<3> >(f, _0, _1, _2); + } + }; + } +}} + +#endif // !BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/include/boost/spirit/include/phoenix.hpp b/include/boost/spirit/include/phoenix.hpp index 3c61098be..f60958739 100644 --- a/include/boost/spirit/include/phoenix.hpp +++ b/include/boost/spirit/include/phoenix.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX #define BOOST_SPIRIT_INCLUDE_PHOENIX + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_algorithm.hpp b/include/boost/spirit/include/phoenix_algorithm.hpp index 980ac83f0..b0e4846d4 100644 --- a/include/boost/spirit/include/phoenix_algorithm.hpp +++ b/include/boost/spirit/include/phoenix_algorithm.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_ALGORITHM #define BOOST_SPIRIT_INCLUDE_PHOENIX_ALGORITHM + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_bind.hpp b/include/boost/spirit/include/phoenix_bind.hpp index 0f4d0ee2e..f289ac02c 100644 --- a/include/boost/spirit/include/phoenix_bind.hpp +++ b/include/boost/spirit/include/phoenix_bind.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_BIND #define BOOST_SPIRIT_INCLUDE_PHOENIX_BIND + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_container.hpp b/include/boost/spirit/include/phoenix_container.hpp index a06405ef0..f63dc8831 100644 --- a/include/boost/spirit/include/phoenix_container.hpp +++ b/include/boost/spirit/include/phoenix_container.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_CONTAINER #define BOOST_SPIRIT_INCLUDE_PHOENIX_CONTAINER + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_core.hpp b/include/boost/spirit/include/phoenix_core.hpp index b807833ec..55b5010ec 100644 --- a/include/boost/spirit/include/phoenix_core.hpp +++ b/include/boost/spirit/include/phoenix_core.hpp @@ -8,5 +8,12 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_CORE #define BOOST_SPIRIT_INCLUDE_PHOENIX_CORE + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 +#define BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(A,B,C,D) #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_function.hpp b/include/boost/spirit/include/phoenix_function.hpp index a7a29e954..76c244d97 100644 --- a/include/boost/spirit/include/phoenix_function.hpp +++ b/include/boost/spirit/include/phoenix_function.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_FUNCTION #define BOOST_SPIRIT_INCLUDE_PHOENIX_FUNCTION + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_fusion.hpp b/include/boost/spirit/include/phoenix_fusion.hpp index 2b825c6b6..8ab422a5b 100644 --- a/include/boost/spirit/include/phoenix_fusion.hpp +++ b/include/boost/spirit/include/phoenix_fusion.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_FUSION #define BOOST_SPIRIT_INCLUDE_PHOENIX_FUSION + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_object.hpp b/include/boost/spirit/include/phoenix_object.hpp index ae95f541e..5bb6dd469 100644 --- a/include/boost/spirit/include/phoenix_object.hpp +++ b/include/boost/spirit/include/phoenix_object.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_OBJECT #define BOOST_SPIRIT_INCLUDE_PHOENIX_OBJECT + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_operator.hpp b/include/boost/spirit/include/phoenix_operator.hpp index 289538770..03c66c9d1 100644 --- a/include/boost/spirit/include/phoenix_operator.hpp +++ b/include/boost/spirit/include/phoenix_operator.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_OPERATOR #define BOOST_SPIRIT_INCLUDE_PHOENIX_OPERATOR + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_scope.hpp b/include/boost/spirit/include/phoenix_scope.hpp index b4ed4bd92..c71533e90 100644 --- a/include/boost/spirit/include/phoenix_scope.hpp +++ b/include/boost/spirit/include/phoenix_scope.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_SCOPE #define BOOST_SPIRIT_INCLUDE_PHOENIX_SCOPE + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_statement.hpp b/include/boost/spirit/include/phoenix_statement.hpp index 701458976..e6729b2ec 100644 --- a/include/boost/spirit/include/phoenix_statement.hpp +++ b/include/boost/spirit/include/phoenix_statement.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_STATEMENT #define BOOST_SPIRIT_INCLUDE_PHOENIX_STATEMENT + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/include/boost/spirit/include/phoenix_stl.hpp b/include/boost/spirit/include/phoenix_stl.hpp index c98700177..63656357c 100644 --- a/include/boost/spirit/include/phoenix_stl.hpp +++ b/include/boost/spirit/include/phoenix_stl.hpp @@ -8,5 +8,11 @@ =============================================================================*/ #ifndef BOOST_SPIRIT_INCLUDE_PHOENIX_STL #define BOOST_SPIRIT_INCLUDE_PHOENIX_STL + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 #include +#else +#include +#endif + #endif diff --git a/test/Jamfile b/test/Jamfile index 03feec482..b03dbbc9e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -7,6 +7,26 @@ # License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) #============================================================================== + +# bring in rules for testing +import testing ; +import modules ; +import feature ; + +############################################################################### +# new feature definition allowing to switch between Phoenix V2 and V3 tests +feature.feature phoenix_v3 + : on + : optional composite propagated + ; + +feature.compose on + : BOOST_SPIRIT_USE_PHOENIX_V3=1 + BOOST_PROTO_MAX_ARITY=11 + BOOST_PROTO_MAX_LOGICAL_ARITY=11 + ; + +############################################################################### project spirit_v2x/test : requirements . @@ -16,10 +36,35 @@ project spirit_v2x/test : ; -path-constant LEX_DIR : $(BOOST_ROOT)/libs/spirit/test/lex ; +# use this alias to buil Spirit against Phoenix V2 +alias test_using_phoenix_v2 + : spirit_v2/qi + spirit_v2/qi_regressions + spirit_v2/karma + spirit_v2/karma_regressions + spirit_v2/lex + spirit_v2/lex_regressions + spirit_v2/support + spirit_v2/support_regressions + ; -# bring in rules for testing -import testing ; +# use this alias to buil Spirit against Phoenix V3 +alias test_using_phoenix_v3 + : spirit_v2/qi + spirit_v2/qi_regressions + spirit_v2/karma + spirit_v2/karma_regressions + spirit_v2/lex + spirit_v2/lex_regressions + spirit_v2/support + spirit_v2/support_regressions + : on + ; + +explicit test_using_phoenix_v2 test_using_phoenix_v3 ; + +############################################################################### +path-constant LEX_DIR : $(BOOST_ROOT)/libs/spirit/test/lex ; { ########################################################################### diff --git a/test/karma/sequence2.cpp b/test/karma/sequence2.cpp index 73d3913c6..2f0ea39c6 100644 --- a/test/karma/sequence2.cpp +++ b/test/karma/sequence2.cpp @@ -34,10 +34,15 @@ using namespace spirit_test; struct seqsize_impl { template - struct result + struct result : boost::fusion::result_of::size {}; + template + struct result + : result::type> + {}; + template typename result::type operator()(Sequence const& seq) const diff --git a/test/karma/utree1.cpp b/test/karma/utree1.cpp index d65488e4c..5728b1034 100644 --- a/test/karma/utree1.cpp +++ b/test/karma/utree1.cpp @@ -10,8 +10,8 @@ #include -#include #include +#include #include diff --git a/test/karma/utree2.cpp b/test/karma/utree2.cpp index da8473d7d..429ddda18 100644 --- a/test/karma/utree2.cpp +++ b/test/karma/utree2.cpp @@ -10,8 +10,8 @@ #include -#include #include +#include #include diff --git a/test/karma/utree3.cpp b/test/karma/utree3.cpp index 86e396ce3..96f84e316 100644 --- a/test/karma/utree3.cpp +++ b/test/karma/utree3.cpp @@ -10,8 +10,8 @@ #include -#include #include +#include #include diff --git a/test/lex/auto_switch_lexerstate.cpp b/test/lex/auto_switch_lexerstate.cpp index 857d63460..da5e6c673 100644 --- a/test/lex/auto_switch_lexerstate.cpp +++ b/test/lex/auto_switch_lexerstate.cpp @@ -15,16 +15,12 @@ #include #include +#include + #include #include #include -#include -#include -#include -#include -#include - namespace spirit = boost::spirit; namespace lex = spirit::lex; namespace phoenix = boost::phoenix; diff --git a/test/lex/id_type_enum.cpp b/test/lex/id_type_enum.cpp index 8c582b54b..ca594de78 100644 --- a/test/lex/id_type_enum.cpp +++ b/test/lex/id_type_enum.cpp @@ -11,10 +11,7 @@ #include #include -#include -#include -#include -#include +#include namespace spirit = boost::spirit; namespace lex = spirit::lex; diff --git a/test/lex/lexer_state_switcher.cpp b/test/lex/lexer_state_switcher.cpp index 9e33afe5f..3fad9d349 100644 --- a/test/lex/lexer_state_switcher.cpp +++ b/test/lex/lexer_state_switcher.cpp @@ -26,7 +26,7 @@ struct switch_state_tokens : boost::spirit::lex::lexer this->self = identifier [ phoenix::ref(state_) = _state ]; integer = "[0-9]+"; - this->self("INT") = integer [ _state = phoenix::val("INITIAL") ]; + this->self("INT") = integer [ _state = "INITIAL" ]; } std::string state_; diff --git a/test/lex/regression_file_iterator1.cpp b/test/lex/regression_file_iterator1.cpp index 2478ddcb1..583613b83 100644 --- a/test/lex/regression_file_iterator1.cpp +++ b/test/lex/regression_file_iterator1.cpp @@ -13,11 +13,7 @@ #include #include -#include -#include -#include -#include -#include +#include namespace spirit = boost::spirit; namespace lex = spirit::lex; @@ -41,14 +37,14 @@ make_file_iterator(std::istream& input, const std::string& filename) struct identifier { - identifier(file_iterator begin, file_iterator end) + identifier(file_iterator, file_iterator) { } }; struct string_literal { - string_literal(file_iterator begin, file_iterator end) + string_literal(file_iterator, file_iterator) { } }; diff --git a/test/lex/regression_file_iterator2.cpp b/test/lex/regression_file_iterator2.cpp index adab4e3bf..486ddf6ec 100644 --- a/test/lex/regression_file_iterator2.cpp +++ b/test/lex/regression_file_iterator2.cpp @@ -13,11 +13,7 @@ #include #include -#include -#include -#include -#include -#include +#include namespace spirit = boost::spirit; namespace lex = spirit::lex; @@ -39,14 +35,14 @@ make_file_iterator(std::istream& input, const std::string& filename) struct identifier { - identifier(file_iterator begin, file_iterator end) + identifier(file_iterator, file_iterator) { } }; struct string_literal { - string_literal(file_iterator begin, file_iterator end) + string_literal(file_iterator, file_iterator) { } }; diff --git a/test/lex/regression_file_iterator3.cpp b/test/lex/regression_file_iterator3.cpp index 60feff8ef..3d7b5b078 100644 --- a/test/lex/regression_file_iterator3.cpp +++ b/test/lex/regression_file_iterator3.cpp @@ -14,10 +14,11 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include @@ -43,7 +44,7 @@ make_file_iterator(std::istream& input, const std::string& filename) struct string_literal { - string_literal(file_iterator begin, file_iterator end) + string_literal(file_iterator, file_iterator) { } }; diff --git a/test/lex/regression_file_iterator4.cpp b/test/lex/regression_file_iterator4.cpp index 2f0f90c45..97206b479 100644 --- a/test/lex/regression_file_iterator4.cpp +++ b/test/lex/regression_file_iterator4.cpp @@ -17,10 +17,7 @@ #include #include -#include -#include -#include -#include +#include namespace spirit = boost::spirit; namespace lex = spirit::lex; diff --git a/test/lex/regression_wide.cpp b/test/lex/regression_wide.cpp index 2d5ead42e..9006b3211 100644 --- a/test/lex/regression_wide.cpp +++ b/test/lex/regression_wide.cpp @@ -59,6 +59,7 @@ test_data data[] = /////////////////////////////////////////////////////////////////////////////// struct test_impl { + typedef void result_type; template struct result { typedef void type; }; diff --git a/test/lex/regression_word_count.cpp b/test/lex/regression_word_count.cpp index 1e52eab58..c55fa77ba 100644 --- a/test/lex/regression_word_count.cpp +++ b/test/lex/regression_word_count.cpp @@ -12,9 +12,8 @@ #include #include + #include -#include -#include #include #include diff --git a/test/support/utree.cpp b/test/support/utree.cpp index 85cfc0dfe..f638f82ad 100644 --- a/test/support/utree.cpp +++ b/test/support/utree.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include