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 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_KARMA_AUTO_NOV_29_2009_0339PM)
0007 #define BOOST_SPIRIT_KARMA_AUTO_NOV_29_2009_0339PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/support/common_terminals.hpp>
0014 #include <boost/spirit/home/support/info.hpp>
0015 #include <boost/spirit/home/support/container.hpp>
0016 #include <boost/spirit/home/support/assert_msg.hpp>
0017 #include <boost/spirit/home/support/detail/hold_any.hpp>
0018 #include <boost/spirit/home/karma/domain.hpp>
0019 #include <boost/spirit/home/karma/meta_compiler.hpp>
0020 #include <boost/spirit/home/karma/delimit_out.hpp>
0021 #include <boost/spirit/home/karma/generator.hpp>
0022 #include <boost/spirit/home/karma/auto/create_generator.hpp>
0023 #include <boost/mpl/bool.hpp>
0024 
0025 ///////////////////////////////////////////////////////////////////////////////
0026 namespace boost { namespace spirit
0027 {
0028     ///////////////////////////////////////////////////////////////////////////
0029     // Enablers
0030     ///////////////////////////////////////////////////////////////////////////
0031     template <>
0032     struct use_terminal<karma::domain, tag::auto_>     // enables auto_
0033       : mpl::true_ {};
0034 
0035     template <typename A0>
0036     struct use_terminal<karma::domain                   // enables auto_(...)
0037       , terminal_ex<tag::auto_, fusion::vector1<A0> >
0038     > : mpl::true_ {};
0039 
0040     template <>                                         // enables auto_(f)
0041     struct use_lazy_terminal<
0042         karma::domain, tag::auto_, 1   /*arity*/
0043     > : mpl::true_ {};
0044 
0045 }}
0046 
0047 ///////////////////////////////////////////////////////////////////////////////
0048 namespace boost { namespace spirit { namespace karma
0049 {
0050 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0051     using spirit::auto_;
0052 #endif
0053     using spirit::auto_type;
0054 
0055     ///////////////////////////////////////////////////////////////////////////
0056     template <typename Modifiers>
0057     struct auto_generator
0058       : generator<auto_generator<Modifiers> >
0059     {
0060         typedef mpl::int_<generator_properties::all_properties> properties;
0061 
0062         template <typename Context, typename Unused>
0063         struct attribute
0064         {
0065             typedef spirit::basic_hold_any<char> type;
0066         };
0067 
0068         auto_generator(Modifiers const& modifiers)
0069           : modifiers_(modifiers) {}
0070 
0071         // auto_generator has an attached attribute
0072         template <
0073             typename OutputIterator, typename Context, typename Delimiter
0074           , typename Attribute>
0075         bool generate(OutputIterator& sink, Context& context
0076           , Delimiter const& d, Attribute const& attr) const
0077         {
0078             return compile<karma::domain>(create_generator<Attribute>(), modifiers_)
0079                       .generate(sink, context, d, attr);
0080         }
0081 
0082         // this auto_generator has no attribute attached, it needs to have been
0083         // initialized from a value/variable
0084         template <typename OutputIterator, typename Context
0085           , typename Delimiter>
0086         static bool
0087         generate(OutputIterator&, Context&, Delimiter const&, unused_type)
0088         {
0089             // It is not possible (doesn't make sense) to use auto_ generators
0090             // without providing any attribute, as the generator doesn't 'know'
0091             // what to output. The following assertion fires if this situation
0092             // is detected in your code.
0093             BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, auto_not_usable_without_attribute, ());
0094             return false;
0095         }
0096 
0097         template <typename Context>
0098         info what(Context& /*context*/) const
0099         {
0100             return info("auto_");
0101         }
0102 
0103         Modifiers modifiers_;
0104     };
0105 
0106     ///////////////////////////////////////////////////////////////////////////
0107     template <typename T, typename Modifiers>
0108     struct lit_auto_generator
0109       : generator<lit_auto_generator<T, Modifiers> >
0110     {
0111         typedef mpl::int_<generator_properties::all_properties> properties;
0112 
0113         template <typename Context, typename Unused>
0114         struct attribute
0115         {
0116             typedef unused_type type;
0117         };
0118 
0119         lit_auto_generator(typename add_reference<T>::type t, Modifiers const& modifiers)
0120           : t_(t)
0121           , generator_(compile<karma::domain>(create_generator<T>(), modifiers))
0122         {}
0123 
0124         // auto_generator has an attached attribute
0125         template <
0126             typename OutputIterator, typename Context, typename Delimiter
0127           , typename Attribute>
0128         bool generate(OutputIterator& sink, Context& context
0129           , Delimiter const& d, Attribute const&) const
0130         {
0131             return generator_.generate(sink, context, d, t_);
0132         }
0133 
0134         template <typename Context>
0135         info what(Context& /*context*/) const
0136         {
0137             return info("auto_");
0138         }
0139 
0140         typedef typename spirit::result_of::create_generator<T>::type
0141             generator_type;
0142 
0143         typedef typename spirit::result_of::compile<
0144             karma::domain, generator_type, Modifiers>::type generator_impl_type;
0145 
0146         T t_;
0147         generator_impl_type generator_;
0148     };
0149 
0150     ///////////////////////////////////////////////////////////////////////////
0151     // Generator generators: make_xxx function (objects)
0152     ///////////////////////////////////////////////////////////////////////////
0153 
0154     // auto_
0155     template <typename Modifiers>
0156     struct make_primitive<tag::auto_, Modifiers>
0157     {
0158         typedef auto_generator<Modifiers> result_type;
0159 
0160         result_type operator()(unused_type, Modifiers const& modifiers) const
0161         {
0162             return result_type(modifiers);
0163         }
0164     };
0165 
0166     // auto_(...)
0167     template <typename Modifiers, typename A0>
0168     struct make_primitive<
0169             terminal_ex<tag::auto_, fusion::vector1<A0> >, Modifiers>
0170     {
0171         typedef typename add_const<A0>::type const_attribute;
0172 
0173         typedef lit_auto_generator<const_attribute, Modifiers> result_type;
0174 
0175         template <typename Terminal>
0176         result_type operator()(Terminal const& term, Modifiers const& modifiers) const
0177         {
0178             return result_type(fusion::at_c<0>(term.args), modifiers);
0179         }
0180     };
0181 
0182 }}}
0183 
0184 #endif