Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:34

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //  Copyright (c) 2001-2011 Joel de Guzman
0003 // 
0004 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
0005 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #if !defined(BOOST_SPIRIT_KARMA_LAZY_MARCH_27_2007_1231PM)
0008 #define BOOST_SPIRIT_KARMA_LAZY_MARCH_27_2007_1231PM
0009 
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013 
0014 #include <boost/spirit/home/karma/domain.hpp>
0015 #include <boost/spirit/home/karma/delimit_out.hpp>
0016 #include <boost/spirit/home/karma/meta_compiler.hpp>
0017 #include <boost/spirit/home/karma/detail/attributes.hpp>
0018 #include <boost/spirit/home/support/unused.hpp>
0019 #include <boost/spirit/home/support/info.hpp>
0020 #include <boost/spirit/home/support/lazy.hpp>
0021 #include <boost/fusion/include/at.hpp>
0022 #include <boost/utility/result_of.hpp>
0023 #include <boost/proto/make_expr.hpp>
0024 #include <boost/type_traits/remove_reference.hpp>
0025 #include <boost/mpl/not.hpp>
0026 
0027 namespace boost { namespace phoenix
0028 {
0029     template <typename Expr>
0030     struct actor;
0031 }}
0032 
0033 namespace boost { namespace spirit
0034 {
0035     ///////////////////////////////////////////////////////////////////////////
0036     // Enablers
0037     ///////////////////////////////////////////////////////////////////////////
0038     template <typename Eval>
0039     struct use_terminal<karma::domain, phoenix::actor<Eval> >  // enables phoenix actors
0040         : mpl::true_ {};
0041 
0042     // forward declaration
0043     template <typename Terminal, typename Actor, int Arity>
0044     struct lazy_terminal;
0045 
0046 }}
0047 
0048 namespace boost { namespace spirit { namespace karma
0049 {
0050     using spirit::lazy;
0051     typedef modify<karma::domain> karma_modify;
0052 
0053     namespace detail
0054     {
0055         template <typename Generator, typename OutputIterator, typename Context
0056           , typename Delimiter, typename Attribute>
0057         bool lazy_generate_impl(Generator const& g, OutputIterator& sink
0058           , Context& context, Delimiter const& delim
0059           , Attribute const& attr, mpl::false_)
0060         {
0061             return g.generate(sink, context, delim, attr);
0062         }
0063 
0064         template <typename Generator, typename OutputIterator, typename Context
0065           , typename Delimiter, typename Attribute>
0066         bool lazy_generate_impl(Generator const& g, OutputIterator& sink
0067           , Context& context, Delimiter const& delim
0068           , Attribute const& /* attr */, mpl::true_)
0069         {
0070             // If DeducedAuto is false (semantic actions is present), the
0071             // component's attribute is unused.
0072             return g.generate(sink, context, delim, unused);
0073         }
0074 
0075         template <typename Generator, typename OutputIterator, typename Context
0076           , typename Delimiter, typename Attribute>
0077         bool lazy_generate_impl_main(Generator const& g, OutputIterator& sink
0078           , Context& context, Delimiter const& delim, Attribute const& attr)
0079         {
0080             // If DeducedAuto is true (no semantic action), we pass the parser's
0081             // attribute on to the component.
0082             typedef typename traits::has_semantic_action<Generator>::type auto_rule;
0083             return lazy_generate_impl(g, sink, context, delim, attr, auto_rule());
0084         }
0085     }
0086 
0087     template <typename Function, typename Modifiers>
0088     struct lazy_generator : generator<lazy_generator<Function, Modifiers> >
0089     {
0090         typedef mpl::int_<generator_properties::all_properties> properties;
0091 
0092         template <typename Context, typename Iterator>
0093         struct attribute
0094         {
0095             typedef typename
0096                 boost::result_of<karma_modify(tag::lazy_eval, Modifiers)>::type
0097             modifier;
0098 
0099             typedef typename
0100                 remove_reference<
0101                     typename boost::result_of<Function(unused_type, Context)>::type
0102                 >::type
0103             expr_type;
0104 
0105             // If you got an error_invalid_expression error message here,
0106             // then the expression (expr_type) is not a valid spirit karma
0107             // expression.
0108             BOOST_SPIRIT_ASSERT_MATCH(karma::domain, expr_type);
0109 
0110             typedef typename
0111                 result_of::compile<karma::domain, expr_type, modifier>::type
0112             generator_type;
0113 
0114             typedef typename
0115                 traits::attribute_of<generator_type, Context, Iterator>::type
0116             type;
0117         };
0118 
0119         lazy_generator(Function const& func, Modifiers const& modifiers)
0120           : func(func), modifiers(modifiers) {}
0121 
0122         template <
0123             typename OutputIterator, typename Context, 
0124             typename Delimiter, typename Attribute
0125         >
0126         bool generate(OutputIterator& sink, Context& context, 
0127             Delimiter const& d, Attribute const& attr) const
0128         {
0129             return detail::lazy_generate_impl_main(
0130                 compile<karma::domain>(func(unused, context)
0131               , karma_modify()(tag::lazy_eval(), modifiers))
0132               , sink, context, d, attr);
0133         }
0134 
0135         template <typename Context>
0136         info what(Context& context) const
0137         {
0138             return info("lazy"
0139               , compile<karma::domain>(func(unused, context)
0140                 , karma_modify()(tag::lazy_eval(), modifiers))
0141                     .what(context)
0142             );
0143         }
0144 
0145         Function func;
0146         Modifiers modifiers;
0147     };
0148 
0149     ///////////////////////////////////////////////////////////////////////////
0150     template <typename Function, typename Subject, typename Modifiers>
0151     struct lazy_directive 
0152       : unary_generator<lazy_directive<Function, Subject, Modifiers> >
0153     {
0154         typedef mpl::int_<generator_properties::all_properties> properties;
0155 
0156         typedef Subject subject_type;
0157 
0158         template <typename Context, typename Iterator>
0159         struct attribute
0160         {
0161             typedef typename
0162                 boost::result_of<karma_modify(tag::lazy_eval, Modifiers)>::type
0163             modifier;
0164 
0165             typedef typename
0166                 remove_reference<
0167                     typename boost::result_of<Function(unused_type, Context)>::type
0168                 >::type
0169             directive_expr_type;
0170 
0171             typedef typename
0172                 proto::result_of::make_expr<
0173                     proto::tag::subscript
0174                   , directive_expr_type
0175                   , Subject
0176                 >::type
0177             expr_type;
0178 
0179             // If you got an error_invalid_expression error message here,
0180             // then the expression (expr_type) is not a valid spirit karma
0181             // expression.
0182             BOOST_SPIRIT_ASSERT_MATCH(karma::domain, expr_type);
0183 
0184             typedef typename
0185                 result_of::compile<karma::domain, expr_type, modifier>::type
0186             generator_type;
0187 
0188             typedef typename
0189                 traits::attribute_of<generator_type, Context, Iterator>::type
0190             type;
0191         };
0192 
0193         lazy_directive(Function const& function, Subject const& subject
0194               , Modifiers const& modifiers)
0195           : function(function), subject(subject), modifiers(modifiers) {}
0196 
0197         template <typename OutputIterator, typename Context, typename Delimiter
0198           , typename Attribute>
0199         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0200           , Attribute const& attr) const
0201         {
0202             return detail::lazy_generate_impl_main(compile<karma::domain>(
0203                 proto::make_expr<proto::tag::subscript>(
0204                     function(unused, ctx), subject)
0205                   , karma_modify()(tag::lazy_eval(), modifiers))
0206                   , sink, ctx, d, attr);
0207         }
0208 
0209         template <typename Context>
0210         info what(Context& ctx) const
0211         {
0212             return info("lazy-directive"
0213               , compile<karma::domain>(
0214                     proto::make_expr<proto::tag::subscript>(
0215                         function(unused, ctx), subject)
0216                       , karma_modify()(tag::lazy_eval(), modifiers))
0217                     .what(ctx)
0218             );
0219         }
0220 
0221         Function function;
0222         Subject subject;
0223         Modifiers modifiers;
0224     };
0225 
0226     ///////////////////////////////////////////////////////////////////////////
0227     // Generator generators: make_xxx function (objects)
0228     ///////////////////////////////////////////////////////////////////////////
0229     template <typename Eval, typename Modifiers>
0230     struct make_primitive<phoenix::actor<Eval>, Modifiers>
0231     {
0232         typedef lazy_generator<phoenix::actor<Eval>, Modifiers> result_type;
0233         result_type operator()(phoenix::actor<Eval> const& f
0234           , Modifiers const& modifiers) const
0235         {
0236             return result_type(f, modifiers);
0237         }
0238     };
0239 
0240     template <typename Terminal, typename Actor, int Arity, typename Modifiers>
0241     struct make_primitive<lazy_terminal<Terminal, Actor, Arity>, Modifiers>
0242     {
0243         typedef lazy_generator<Actor, Modifiers> result_type;
0244         result_type operator()(
0245             lazy_terminal<Terminal, Actor, Arity> const& lt
0246           , Modifiers const& modifiers) const
0247         {
0248             return result_type(lt.actor, modifiers);
0249         }
0250     };
0251 
0252     template <
0253         typename Terminal, typename Actor, int Arity, typename Subject
0254       , typename Modifiers>
0255     struct make_directive<lazy_terminal<Terminal, Actor, Arity>
0256       , Subject, Modifiers>
0257     {
0258         typedef lazy_directive<Actor, Subject, Modifiers> result_type;
0259         result_type operator()(
0260             lazy_terminal<Terminal, Actor, Arity> const& lt
0261           , Subject const& subject, Modifiers const& modifiers) const
0262         {
0263             return result_type(lt.actor, subject, modifiers);
0264         }
0265     };
0266 
0267 }}}
0268 
0269 #endif