File indexing completed on 2025-01-19 09:47:34
0001
0002
0003
0004
0005
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
0037
0038 template <typename Eval>
0039 struct use_terminal<karma::domain, phoenix::actor<Eval> >
0040 : mpl::true_ {};
0041
0042
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& , mpl::true_)
0069 {
0070
0071
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
0081
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
0106
0107
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
0180
0181
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
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