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 //
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_CHAR_CLASS_AUG_10_2009_0720AM)
0007 #define BOOST_SPIRIT_KARMA_CHAR_CLASS_AUG_10_2009_0720AM
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/string_traits.hpp>
0015 #include <boost/spirit/home/support/info.hpp>
0016 #include <boost/spirit/home/support/char_class.hpp>
0017 #include <boost/spirit/home/support/detail/get_encoding.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/char/char_generator.hpp>
0022 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0023 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0024 #include <boost/spirit/home/karma/detail/generate_to.hpp>
0025 
0026 ///////////////////////////////////////////////////////////////////////////////
0027 namespace boost { namespace spirit 
0028 { 
0029     ///////////////////////////////////////////////////////////////////////////
0030     // Enablers
0031     ///////////////////////////////////////////////////////////////////////////
0032     // enables alnum, alpha, graph, etc.
0033     template <typename CharClass, typename CharEncoding>
0034     struct use_terminal<karma::domain
0035         , tag::char_code<CharClass, CharEncoding> >
0036       : mpl::true_ {};
0037 
0038 }}
0039 
0040 ///////////////////////////////////////////////////////////////////////////////
0041 namespace boost { namespace spirit { namespace karma
0042 {
0043     // hoist the char classification namespaces into karma sub-namespaces of 
0044     // the same name
0045     namespace ascii { using namespace boost::spirit::ascii; }
0046     namespace iso8859_1 { using namespace boost::spirit::iso8859_1; }
0047     namespace standard { using namespace boost::spirit::standard; }
0048     namespace standard_wide { using namespace boost::spirit::standard_wide; }
0049 #if defined(BOOST_SPIRIT_UNICODE)
0050     namespace unicode { using namespace boost::spirit::unicode; }
0051 #endif
0052 
0053     // Import the standard namespace into the karma namespace. This allows 
0054     // for default handling of all character/string related operations if not 
0055     // prefixed with a character set namespace.
0056     using namespace boost::spirit::standard;
0057 
0058     // Import encoding
0059     using spirit::encoding;
0060 
0061     ///////////////////////////////////////////////////////////////////////////
0062     //
0063     //  char_class
0064     //      generates a single character if it matches the given character 
0065     //      class
0066     //
0067     ///////////////////////////////////////////////////////////////////////////
0068     template <typename Tag, typename CharEncoding, typename CharClass>
0069     struct char_class
0070       : char_generator<
0071             char_class<Tag, CharEncoding, CharClass>
0072           , CharEncoding, CharClass>
0073     {
0074         typedef typename Tag::char_encoding char_encoding;
0075         typedef typename char_encoding::char_type char_type;
0076         typedef typename Tag::char_class classification;
0077 
0078         template <typename Context, typename Unused>
0079         struct attribute
0080         {
0081             typedef char_type type;
0082         };
0083 
0084         // char_class needs an attached attribute
0085         template <typename Attribute, typename CharParam, typename Context>
0086         bool test(Attribute const& attr, CharParam& ch, Context&) const
0087         {
0088             ch = attr;
0089 
0090             using spirit::char_class::classify;
0091             return classify<char_encoding>::is(classification(), attr);
0092         }
0093 
0094         // char_class shouldn't be used without any associated attribute
0095         template <typename CharParam, typename Context>
0096         bool test(unused_type, CharParam&, Context&) const
0097         {
0098             // It is not possible (doesn't make sense) to use char_ generators
0099             // without providing any attribute, as the generator doesn't 'know'
0100             // what to output. The following assertion fires if this situation
0101             // is detected in your code.
0102             BOOST_SPIRIT_ASSERT_FAIL(CharParam
0103               , char_class_not_usable_without_attribute, ());
0104             return false;
0105         }
0106 
0107         template <typename Context>
0108         static info what(Context const& /*context*/)
0109         {
0110             typedef spirit::char_class::what<char_encoding> what_;
0111             return info(what_::is(classification()));
0112         }
0113     };
0114 
0115     ///////////////////////////////////////////////////////////////////////////
0116     //
0117     //  space
0118     //      generates a single character from the associated parameter
0119     //
0120     ///////////////////////////////////////////////////////////////////////////
0121     template <typename CharEncoding>
0122     struct any_space
0123       : char_generator<any_space<CharEncoding>, CharEncoding, tag::space>
0124     {
0125         typedef typename CharEncoding::char_type char_type;
0126         typedef CharEncoding char_encoding;
0127 
0128         template <typename Context, typename Unused>
0129         struct attribute
0130         {
0131             typedef char_type type;
0132         };
0133 
0134         // any_space has an attached parameter
0135         template <typename Attribute, typename CharParam, typename Context>
0136         bool test(Attribute const& attr, CharParam& ch, Context&) const
0137         {
0138             ch = CharParam(attr);
0139 
0140             using spirit::char_class::classify;
0141             return classify<char_encoding>::is(tag::space(), attr);
0142         }
0143 
0144         // any_space has no attribute attached, use single space character
0145         template <typename CharParam, typename Context>
0146         bool test(unused_type, CharParam& ch, Context&) const
0147         {
0148             ch = ' ';
0149             return true;
0150         }
0151 
0152         template <typename Context>
0153         static info what(Context const& /*context*/)
0154         {
0155             return info("space");
0156         }
0157     };
0158 
0159     ///////////////////////////////////////////////////////////////////////////
0160     // Generator generators: make_xxx function (objects)
0161     ///////////////////////////////////////////////////////////////////////////
0162 
0163     namespace detail
0164     {
0165         template <typename Tag, bool lower = false, bool upper = false>
0166         struct make_char_class : mpl::identity<Tag> {};
0167 
0168         template <>
0169         struct make_char_class<tag::alpha, true, false> 
0170           : mpl::identity<tag::lower> {};
0171 
0172         template <>
0173         struct make_char_class<tag::alpha, false, true> 
0174           : mpl::identity<tag::upper> {};
0175 
0176         template <>
0177         struct make_char_class<tag::alnum, true, false> 
0178           : mpl::identity<tag::lowernum> {};
0179 
0180         template <>
0181         struct make_char_class<tag::alnum, false, true> 
0182           : mpl::identity<tag::uppernum> {};
0183     }
0184 
0185     // enables alnum, alpha, graph, etc.
0186     template <typename CharClass, typename CharEncoding, typename Modifiers>
0187     struct make_primitive<tag::char_code<CharClass, CharEncoding>, Modifiers>
0188     {
0189         static bool const lower = 
0190             has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0191         static bool const upper = 
0192             has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0193 
0194         typedef tag::char_code<
0195             typename detail::make_char_class<CharClass, lower, upper>::type
0196           , CharEncoding>
0197         tag_type;
0198 
0199         typedef char_class<
0200             tag_type
0201           , typename spirit::detail::get_encoding_with_case<
0202                 Modifiers, CharEncoding, lower || upper>::type
0203           , typename detail::get_casetag<Modifiers, lower || upper>::type
0204         > result_type;
0205 
0206         result_type operator()(unused_type, unused_type) const
0207         {
0208             return result_type();
0209         }
0210     };
0211 
0212     // space is special
0213     template <typename CharEncoding, typename Modifiers>
0214     struct make_primitive<tag::char_code<tag::space, CharEncoding>, Modifiers>
0215     {
0216         typedef any_space<CharEncoding> result_type;
0217 
0218         result_type operator()(unused_type, unused_type) const
0219         {
0220             return result_type();
0221         }
0222     };
0223 
0224 }}}  // namespace boost::spirit::karma
0225 
0226 #endif // !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)