// Copyright (c) 2001-2010 Hartmut Kaiser // Copyright (c) 2001-2010 Joel de Guzman // // 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_KARMA_LAZY_MARCH_27_2007_1231PM) #define BOOST_SPIRIT_KARMA_LAZY_MARCH_27_2007_1231PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { /////////////////////////////////////////////////////////////////////////// // Enablers /////////////////////////////////////////////////////////////////////////// template struct use_terminal > // enables phoenix actors : mpl::true_ {}; // forward declaration template struct lazy_terminal; }} namespace boost { namespace spirit { namespace karma { using spirit::lazy; typedef modify karma_modify; template struct lazy_generator : generator > { typedef mpl::int_ properties; template struct attribute { typedef typename boost::result_of::type modifier; typedef typename remove_reference< typename boost::result_of::type >::type expr_type; // If you got an error_invalid_expression error message here, // then the expression (expr_type) is not a valid spirit karma // expression. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, expr_type); typedef typename result_of::compile::type generator_type; typedef typename traits::attribute_of::type type; }; lazy_generator(Function const& func, Modifiers const& modifiers) : func(func), modifiers(modifiers) {} template < typename OutputIterator, typename Context, typename Delimiter, typename Attribute > bool generate(OutputIterator& sink, Context& context, Delimiter const& d, Attribute const& attr) const { return compile(func(unused, context) , karma_modify()(tag::lazy_eval(), modifiers)) .generate(sink, context, d, attr); } template info what(Context& context) const { return info("lazy" , compile(func(unused, context) , karma_modify()(tag::lazy_eval(), modifiers)) .what(context) ); } Function func; Modifiers modifiers; private: // silence MSVC warning C4512: assignment operator could not be generated lazy_generator& operator= (lazy_generator const&); }; /////////////////////////////////////////////////////////////////////////// template struct lazy_directive : unary_generator > { typedef mpl::int_ properties; typedef Subject subject_type; template struct attribute { typedef typename boost::result_of::type modifier; typedef typename remove_reference< typename boost::result_of::type >::type directive_expr_type; typedef typename proto::result_of::make_expr< proto::tag::subscript , directive_expr_type , Subject >::type expr_type; // If you got an error_invalid_expression error message here, // then the expression (expr_type) is not a valid spirit karma // expression. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, expr_type); typedef typename result_of::compile::type generator_type; typedef typename traits::attribute_of::type type; }; lazy_directive(Function const& function, Subject const& subject , Modifiers const& modifiers) : function(function), subject(subject), modifiers(modifiers) {} template bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d , Attribute const& attr) const { return compile( proto::make_expr( function(unused, ctx), subject) , karma_modify()(tag::lazy_eval(), modifiers)) .generate(sink, ctx, d, attr); } template info what(Context& ctx) const { return info("lazy-directive" , compile( proto::make_expr( function(unused, ctx), subject) , karma_modify()(tag::lazy_eval(), modifiers)) .what(ctx) ); } Function function; Subject subject; Modifiers modifiers; }; /////////////////////////////////////////////////////////////////////////// // Generator generators: make_xxx function (objects) /////////////////////////////////////////////////////////////////////////// template struct make_primitive, Modifiers> { typedef lazy_generator, Modifiers> result_type; result_type operator()(phoenix::actor const& f , Modifiers const& modifiers) const { return result_type(f, modifiers); } }; template struct make_primitive, Modifiers> { typedef lazy_generator result_type; result_type operator()( lazy_terminal const& lt , Modifiers const& modifiers) const { return result_type(lt.actor, modifiers); } }; template < typename Terminal, typename Actor, int Arity, typename Subject , typename Modifiers> struct make_directive , Subject, Modifiers> { typedef lazy_directive result_type; result_type operator()( lazy_terminal const& lt , Subject const& subject, Modifiers const& modifiers) const { return result_type(lt.actor, subject, modifiers); } }; }}} #endif