Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //  Copyright (c)      2010 Bryce Lelbach
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_LIT_FEB_22_2007_0534PM)
0008 #define BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM
0009 
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013 
0014 #include <boost/spirit/home/support/common_terminals.hpp>
0015 #include <boost/spirit/home/support/string_traits.hpp>
0016 #include <boost/spirit/home/support/info.hpp>
0017 #include <boost/spirit/home/support/char_class.hpp>
0018 #include <boost/spirit/home/support/container.hpp>
0019 #include <boost/spirit/home/support/handles_container.hpp>
0020 #include <boost/spirit/home/support/detail/get_encoding.hpp>
0021 #include <boost/spirit/home/karma/domain.hpp>
0022 #include <boost/spirit/home/karma/meta_compiler.hpp>
0023 #include <boost/spirit/home/karma/delimit_out.hpp>
0024 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0025 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0026 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0027 #include <boost/spirit/home/karma/detail/string_generate.hpp>
0028 #include <boost/spirit/home/karma/detail/string_compare.hpp>
0029 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
0030 #include <boost/fusion/include/at.hpp>
0031 #include <boost/fusion/include/vector.hpp>
0032 #include <boost/fusion/include/cons.hpp>
0033 #include <boost/mpl/if.hpp>
0034 #include <boost/mpl/or.hpp>
0035 #include <boost/mpl/assert.hpp>
0036 #include <boost/mpl/bool.hpp>
0037 #include <boost/utility/enable_if.hpp>
0038 #include <string>
0039 
0040 ///////////////////////////////////////////////////////////////////////////////
0041 namespace boost { namespace spirit
0042 {
0043     ///////////////////////////////////////////////////////////////////////////
0044     // Enablers
0045     ///////////////////////////////////////////////////////////////////////////
0046     template <typename CharEncoding>
0047     struct use_terminal<karma::domain
0048         , tag::char_code<tag::string, CharEncoding> >     // enables string
0049       : mpl::true_ {};
0050 
0051     template <typename T>
0052     struct use_terminal<karma::domain, T
0053       , typename enable_if<traits::is_string<T> >::type>  // enables string literals
0054       : mpl::true_ {};
0055 
0056     template <typename CharEncoding, typename A0>
0057     struct use_terminal<karma::domain
0058       , terminal_ex<
0059             tag::char_code<tag::string, CharEncoding>     // enables string(str)
0060           , fusion::vector1<A0> >
0061     > : traits::is_string<A0> {};
0062 
0063     template <typename CharEncoding>                      // enables string(f)
0064     struct use_lazy_terminal<
0065         karma::domain
0066       , tag::char_code<tag::string, CharEncoding>
0067       , 1 /*arity*/
0068     > : mpl::true_ {};
0069 
0070     // enables lit(str)
0071     template <typename A0>
0072     struct use_terminal<karma::domain
0073           , terminal_ex<tag::lit, fusion::vector1<A0> >
0074           , typename enable_if<traits::is_string<A0> >::type>
0075       : mpl::true_ {};
0076 }} 
0077 
0078 ///////////////////////////////////////////////////////////////////////////////
0079 namespace boost { namespace spirit { namespace karma
0080 {
0081 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0082     using spirit::lit;
0083 #endif
0084     using spirit::lit_type;
0085 
0086     ///////////////////////////////////////////////////////////////////////////
0087     // generate literal strings from a given parameter
0088     ///////////////////////////////////////////////////////////////////////////
0089     template <typename CharEncoding, typename Tag>
0090     struct any_string
0091       : primitive_generator<any_string<CharEncoding, Tag> >
0092     {
0093         typedef typename CharEncoding::char_type char_type;
0094         typedef CharEncoding char_encoding;
0095 
0096         template <typename Context, typename Unused = unused_type>
0097         struct attribute
0098         {
0099             typedef std::basic_string<char_type> type;
0100         };
0101 
0102         // lit has an attached attribute
0103         template <typename OutputIterator, typename Context, typename Delimiter
0104           , typename Attribute>
0105         static bool
0106         generate(OutputIterator& sink, Context& context, Delimiter const& d, 
0107             Attribute const& attr)
0108         {
0109             if (!traits::has_optional_value(attr))
0110                 return false;
0111 
0112             typedef typename attribute<Context>::type attribute_type;
0113             return 
0114                 karma::detail::string_generate(sink
0115                   , traits::extract_from<attribute_type>(attr, context)
0116                   , char_encoding(), Tag()) &&
0117                 karma::delimit_out(sink, d);      // always do post-delimiting
0118         }
0119 
0120         // this lit has no attribute attached, it needs to have been
0121         // initialized from a direct literal
0122         template <typename OutputIterator, typename Context, typename Delimiter>
0123         static bool generate(OutputIterator&, Context&, Delimiter const&, 
0124             unused_type const&)
0125         {
0126             // It is not possible (doesn't make sense) to use string without
0127             // providing any attribute, as the generator doesn't 'know' what
0128             // character to output. The following assertion fires if this
0129             // situation is detected in your code.
0130             BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, string_not_usable_without_attribute, ());
0131             return false;
0132         }
0133 
0134         template <typename Context>
0135         static info what(Context const& /*context*/)
0136         {
0137             return info("any-string");
0138         }
0139     };
0140 
0141     ///////////////////////////////////////////////////////////////////////////
0142     // generate literal strings
0143     ///////////////////////////////////////////////////////////////////////////
0144     template <typename String, typename CharEncoding, typename Tag, bool no_attribute>
0145     struct literal_string
0146       : primitive_generator<literal_string<String, CharEncoding, Tag, no_attribute> >
0147     {
0148         typedef CharEncoding char_encoding;
0149         typedef typename
0150             remove_const<typename traits::char_type_of<String>::type>::type
0151         char_type;
0152         typedef std::basic_string<char_type> string_type;
0153 
0154         template <typename Context, typename Unused = unused_type>
0155         struct attribute
0156           : mpl::if_c<no_attribute, unused_type, string_type>
0157         {};
0158 
0159         literal_string(typename add_reference<String>::type str)
0160           : str_(str)
0161         {}
0162 
0163         // A string("...") which additionally has an associated attribute emits
0164         // its immediate literal only if it matches the attribute, otherwise
0165         // it fails.
0166         template <
0167             typename OutputIterator, typename Context, typename Delimiter
0168           , typename Attribute>
0169         bool generate(OutputIterator& sink, Context& context
0170           , Delimiter const& d, Attribute const& attr) const
0171         {
0172             if (!traits::has_optional_value(attr))
0173                 return false;
0174 
0175             // fail if attribute isn't matched by immediate literal
0176             typedef typename attribute<Context>::type attribute_type;
0177 
0178             using spirit::traits::get_c_string;
0179             if (!detail::string_compare(
0180                     get_c_string(
0181                         traits::extract_from<attribute_type>(attr, context))
0182                   , get_c_string(str_), char_encoding(), Tag()))
0183             {
0184                 return false;
0185             }
0186             return detail::string_generate(sink, str_, char_encoding(), Tag()) && 
0187                    karma::delimit_out(sink, d);      // always do post-delimiting
0188         }
0189 
0190         // A string("...") without any associated attribute just emits its 
0191         // immediate literal
0192         template <typename OutputIterator, typename Context, typename Delimiter>
0193         bool generate(OutputIterator& sink, Context&, Delimiter const& d
0194           , unused_type) const
0195         {
0196             return detail::string_generate(sink, str_, char_encoding(), Tag()) && 
0197                    karma::delimit_out(sink, d);      // always do post-delimiting
0198         }
0199 
0200         template <typename Context>
0201         info what(Context const& /*context*/) const
0202         {
0203             return info("literal-string", str_);
0204         }
0205 
0206         string_type str_;
0207     };
0208 
0209     ///////////////////////////////////////////////////////////////////////////
0210     // Generator generators: make_xxx function (objects)
0211     ///////////////////////////////////////////////////////////////////////////
0212 
0213     // string
0214     template <typename CharEncoding, typename Modifiers>
0215     struct make_primitive<
0216         tag::char_code<tag::string, CharEncoding>
0217       , Modifiers>
0218     {
0219         static bool const lower = 
0220             has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0221         static bool const upper = 
0222             has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0223 
0224         typedef any_string<
0225             typename spirit::detail::get_encoding_with_case<
0226                 Modifiers, CharEncoding, lower || upper>::type
0227           , typename detail::get_casetag<Modifiers, lower || upper>::type
0228         > result_type;
0229 
0230         result_type operator()(unused_type, unused_type) const
0231         {
0232             return result_type();
0233         }
0234     };
0235 
0236     // string literal 
0237     template <typename T, typename Modifiers>
0238     struct make_primitive<T, Modifiers
0239       , typename enable_if<traits::is_string<T> >::type>
0240     {
0241         static bool const lower =
0242             has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0243 
0244         static bool const upper =
0245             has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0246 
0247         typedef typename add_const<T>::type const_string;
0248         typedef literal_string<
0249             const_string
0250           , typename spirit::detail::get_encoding_with_case<
0251                 Modifiers, unused_type, lower || upper>::type
0252           , typename detail::get_casetag<Modifiers, lower || upper>::type
0253           , true
0254         > result_type;
0255 
0256         result_type operator()(
0257             typename add_reference<const_string>::type str, unused_type) const
0258         {
0259             return result_type(str);
0260         }
0261     };
0262 
0263     ///////////////////////////////////////////////////////////////////////////
0264     namespace detail
0265     {
0266         template <typename CharEncoding, typename Modifiers, typename A0
0267           , bool no_attribute>
0268         struct make_string_direct
0269         {
0270             static bool const lower = 
0271                 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0272             static bool const upper = 
0273                 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0274 
0275             typedef typename add_const<A0>::type const_string;
0276             typedef literal_string<
0277                 const_string
0278               , typename spirit::detail::get_encoding_with_case<
0279                     Modifiers, unused_type, lower || upper>::type
0280               , typename detail::get_casetag<Modifiers, lower || upper>::type
0281               , no_attribute
0282             > result_type;
0283 
0284             template <typename Terminal>
0285             result_type operator()(Terminal const& term, unused_type) const
0286             {
0287                 return result_type(fusion::at_c<0>(term.args));
0288             }
0289         };
0290     }
0291 
0292     // string("..."), lit("...")
0293     template <typename CharEncoding, typename Modifiers, typename A0>
0294     struct make_primitive<
0295             terminal_ex<
0296                 tag::char_code<tag::string, CharEncoding>
0297               , fusion::vector1<A0> >
0298           , Modifiers>
0299       : detail::make_string_direct<CharEncoding, Modifiers, A0, false>
0300     {};
0301 
0302     template <typename Modifiers, typename A0>
0303     struct make_primitive<
0304             terminal_ex<tag::lit, fusion::vector1<A0> >
0305           , Modifiers
0306           , typename enable_if<traits::is_string<A0> >::type>
0307       : detail::make_string_direct<
0308             typename traits::char_encoding_from_char<
0309                 typename traits::char_type_of<A0>::type>::type
0310           , Modifiers, A0, true>
0311     {};
0312 }}}   // namespace boost::spirit::karma
0313 
0314 namespace boost { namespace spirit { namespace traits
0315 {
0316     ///////////////////////////////////////////////////////////////////////////
0317     template <typename CharEncoding, typename Tag, typename Attribute
0318             , typename Context, typename Iterator>
0319     struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute
0320       , Context, Iterator>
0321       : mpl::false_ {};
0322 
0323     template <typename String, typename CharEncoding, typename Tag
0324             , bool no_attribute, typename Attribute, typename Context
0325             , typename Iterator>
0326     struct handles_container<karma::literal_string<String, CharEncoding, Tag
0327       , no_attribute>, Attribute, Context, Iterator>
0328       : mpl::false_ {};
0329 }}}
0330 
0331 #endif