Back to home page

EIC code displayed by LXR

 
 

    


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

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_CHAR_GENERATOR_SEP_07_2009_0417PM)
0008 #define BOOST_SPIRIT_CHAR_GENERATOR_SEP_07_2009_0417PM
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/generator.hpp>
0016 #include <boost/spirit/home/karma/detail/generate_to.hpp>
0017 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0018 #include <boost/spirit/home/karma/meta_compiler.hpp>
0019 #include <boost/spirit/home/karma/delimit_out.hpp>
0020 #include <boost/spirit/home/support/unused.hpp>
0021 #include <boost/spirit/home/support/info.hpp>
0022 #include <boost/spirit/home/support/container.hpp>
0023 #include <boost/proto/operators.hpp>
0024 #include <boost/proto/tags.hpp>
0025 
0026 namespace boost { namespace spirit
0027 {
0028     ///////////////////////////////////////////////////////////////////////////
0029     // Enablers
0030     ///////////////////////////////////////////////////////////////////////////
0031     template <>
0032     struct use_operator<karma::domain, proto::tag::complement> // enables ~
0033       : mpl::true_ {};
0034 
0035 }}
0036 
0037 namespace boost { namespace spirit { namespace traits // classification
0038 {
0039     namespace detail
0040     {
0041         BOOST_MPL_HAS_XXX_TRAIT_DEF(char_generator_id)
0042     }
0043 
0044     template <typename T>
0045     struct is_char_generator : detail::has_char_generator_id<T> {};
0046 }}}
0047 
0048 namespace boost { namespace spirit { namespace karma
0049 {
0050     ///////////////////////////////////////////////////////////////////////////
0051     // The base char_parser
0052     ///////////////////////////////////////////////////////////////////////////
0053     template <typename Derived, typename CharEncoding, typename Tag
0054       , typename Char = typename CharEncoding::char_type, typename Attr = Char>
0055     struct char_generator : primitive_generator<Derived>
0056     {
0057         typedef CharEncoding char_encoding;
0058         typedef Tag tag;
0059         typedef Char char_type;
0060         struct char_generator_id;
0061 
0062         // if Attr is unused_type, Derived must supply its own attribute
0063         // metafunction
0064         template <typename Context, typename Unused>
0065         struct attribute
0066         {
0067             typedef Attr type;
0068         };
0069 
0070         template <
0071             typename OutputIterator, typename Context, typename Delimiter
0072           , typename Attribute>
0073         bool generate(OutputIterator& sink, Context& context, Delimiter const& d
0074           , Attribute const& attr) const
0075         {
0076             if (!traits::has_optional_value(attr))
0077                 return false;
0078 
0079             Attr ch = Attr();
0080             if (!this->derived().test(traits::extract_from<Attr>(attr, context), ch, context))
0081                 return false;
0082 
0083             return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&
0084                    karma::delimit_out(sink, d);       // always do post-delimiting
0085         }
0086 
0087         // Requirement: g.test(attr, ch, context) -> bool
0088         //
0089         //  attr:       associated attribute
0090         //  ch:         character to be generated (set by test())
0091         //  context:    enclosing rule context
0092     };
0093 
0094     ///////////////////////////////////////////////////////////////////////////
0095     // negated_char_generator handles ~cg expressions (cg is a char_generator)
0096     ///////////////////////////////////////////////////////////////////////////
0097     template <typename Positive>
0098     struct negated_char_generator
0099       : char_generator<negated_char_generator<Positive>
0100           , typename Positive::char_encoding, typename Positive::tag>
0101     {
0102         negated_char_generator(Positive const& positive)
0103           : positive(positive) {}
0104 
0105         template <typename Attribute, typename CharParam, typename Context>
0106         bool test(Attribute const& attr, CharParam& ch, Context& context) const
0107         {
0108             return !positive.test(attr, ch, context);
0109         }
0110 
0111         template <typename Context>
0112         info what(Context& context) const
0113         {
0114             return info("not", positive.what(context));
0115         }
0116 
0117         Positive positive;
0118     };
0119 
0120     ///////////////////////////////////////////////////////////////////////////
0121     // Generator generators: make_xxx function (objects)
0122     ///////////////////////////////////////////////////////////////////////////
0123     namespace detail
0124     {
0125         template <typename Positive>
0126         struct make_negated_char_generator
0127         {
0128             typedef negated_char_generator<Positive> result_type;
0129             result_type operator()(Positive const& positive) const
0130             {
0131                 return result_type(positive);
0132             }
0133         };
0134 
0135         template <typename Positive>
0136         struct make_negated_char_generator<negated_char_generator<Positive> >
0137         {
0138             typedef Positive result_type;
0139             result_type operator()(negated_char_generator<Positive> const& ncg) const
0140             {
0141                 return ncg.positive;
0142             }
0143         };
0144     }
0145 
0146     template <typename Elements, typename Modifiers>
0147     struct make_composite<proto::tag::complement, Elements, Modifiers>
0148     {
0149         typedef typename
0150             fusion::result_of::value_at_c<Elements, 0>::type
0151         subject;
0152 
0153         BOOST_SPIRIT_ASSERT_MSG((
0154             traits::is_char_generator<subject>::value
0155         ), subject_is_not_negatable, (subject));
0156 
0157         typedef typename
0158             detail::make_negated_char_generator<subject>::result_type
0159         result_type;
0160 
0161         result_type operator()(Elements const& elements, unused_type) const
0162         {
0163             return detail::make_negated_char_generator<subject>()(
0164                 fusion::at_c<0>(elements));
0165         }
0166     };
0167 
0168 }}}
0169 
0170 #endif