annotate DEPENDENCIES/generic/include/boost/spirit/home/karma/char/char_class.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 2 //
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #if !defined(BOOST_SPIRIT_KARMA_CHAR_CLASS_AUG_10_2009_0720AM)
Chris@16 7 #define BOOST_SPIRIT_KARMA_CHAR_CLASS_AUG_10_2009_0720AM
Chris@16 8
Chris@16 9 #if defined(_MSC_VER)
Chris@16 10 #pragma once
Chris@16 11 #endif
Chris@16 12
Chris@16 13 #include <boost/spirit/home/support/common_terminals.hpp>
Chris@16 14 #include <boost/spirit/home/support/string_traits.hpp>
Chris@16 15 #include <boost/spirit/home/support/info.hpp>
Chris@16 16 #include <boost/spirit/home/support/char_class.hpp>
Chris@16 17 #include <boost/spirit/home/support/detail/get_encoding.hpp>
Chris@16 18 #include <boost/spirit/home/karma/domain.hpp>
Chris@16 19 #include <boost/spirit/home/karma/meta_compiler.hpp>
Chris@16 20 #include <boost/spirit/home/karma/delimit_out.hpp>
Chris@16 21 #include <boost/spirit/home/karma/char/char_generator.hpp>
Chris@16 22 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
Chris@16 23 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
Chris@16 24 #include <boost/spirit/home/karma/detail/generate_to.hpp>
Chris@16 25
Chris@16 26 ///////////////////////////////////////////////////////////////////////////////
Chris@16 27 namespace boost { namespace spirit
Chris@16 28 {
Chris@16 29 ///////////////////////////////////////////////////////////////////////////
Chris@16 30 // Enablers
Chris@16 31 ///////////////////////////////////////////////////////////////////////////
Chris@16 32 // enables alnum, alpha, graph, etc.
Chris@16 33 template <typename CharClass, typename CharEncoding>
Chris@16 34 struct use_terminal<karma::domain
Chris@16 35 , tag::char_code<CharClass, CharEncoding> >
Chris@16 36 : mpl::true_ {};
Chris@16 37
Chris@16 38 }}
Chris@16 39
Chris@16 40 ///////////////////////////////////////////////////////////////////////////////
Chris@16 41 namespace boost { namespace spirit { namespace karma
Chris@16 42 {
Chris@16 43 // hoist the char classification namespaces into karma sub-namespaces of
Chris@16 44 // the same name
Chris@16 45 namespace ascii { using namespace boost::spirit::ascii; }
Chris@16 46 namespace iso8859_1 { using namespace boost::spirit::iso8859_1; }
Chris@16 47 namespace standard { using namespace boost::spirit::standard; }
Chris@16 48 namespace standard_wide { using namespace boost::spirit::standard_wide; }
Chris@16 49 #if defined(BOOST_SPIRIT_UNICODE)
Chris@16 50 namespace unicode { using namespace boost::spirit::unicode; }
Chris@16 51 #endif
Chris@16 52
Chris@16 53 // Import the standard namespace into the karma namespace. This allows
Chris@16 54 // for default handling of all character/string related operations if not
Chris@16 55 // prefixed with a character set namespace.
Chris@16 56 using namespace boost::spirit::standard;
Chris@16 57
Chris@16 58 // Import encoding
Chris@16 59 using spirit::encoding;
Chris@16 60
Chris@16 61 ///////////////////////////////////////////////////////////////////////////
Chris@16 62 //
Chris@16 63 // char_class
Chris@16 64 // generates a single character if it matches the given character
Chris@16 65 // class
Chris@16 66 //
Chris@16 67 ///////////////////////////////////////////////////////////////////////////
Chris@16 68 template <typename Tag, typename CharEncoding, typename CharClass>
Chris@16 69 struct char_class
Chris@16 70 : char_generator<
Chris@16 71 char_class<Tag, CharEncoding, CharClass>
Chris@16 72 , CharEncoding, CharClass>
Chris@16 73 {
Chris@16 74 typedef typename Tag::char_encoding char_encoding;
Chris@16 75 typedef typename char_encoding::char_type char_type;
Chris@16 76 typedef typename Tag::char_class classification;
Chris@16 77
Chris@16 78 template <typename Context, typename Unused>
Chris@16 79 struct attribute
Chris@16 80 {
Chris@16 81 typedef char_type type;
Chris@16 82 };
Chris@16 83
Chris@16 84 // char_class needs an attached attribute
Chris@16 85 template <typename Attribute, typename CharParam, typename Context>
Chris@16 86 bool test(Attribute const& attr, CharParam& ch, Context&) const
Chris@16 87 {
Chris@16 88 ch = attr;
Chris@16 89
Chris@16 90 using spirit::char_class::classify;
Chris@16 91 return classify<char_encoding>::is(classification(), attr);
Chris@16 92 }
Chris@16 93
Chris@16 94 // char_class shouldn't be used without any associated attribute
Chris@16 95 template <typename CharParam, typename Context>
Chris@16 96 bool test(unused_type, CharParam&, Context&) const
Chris@16 97 {
Chris@16 98 // It is not possible (doesn't make sense) to use char_ generators
Chris@16 99 // without providing any attribute, as the generator doesn't 'know'
Chris@16 100 // what to output. The following assertion fires if this situation
Chris@16 101 // is detected in your code.
Chris@16 102 BOOST_SPIRIT_ASSERT_FAIL(CharParam
Chris@16 103 , char_class_not_usable_without_attribute, ());
Chris@16 104 return false;
Chris@16 105 }
Chris@16 106
Chris@16 107 template <typename Context>
Chris@16 108 static info what(Context const& /*context*/)
Chris@16 109 {
Chris@16 110 typedef spirit::char_class::what<char_encoding> what_;
Chris@16 111 return info(what_::is(classification()));
Chris@16 112 }
Chris@16 113 };
Chris@16 114
Chris@16 115 ///////////////////////////////////////////////////////////////////////////
Chris@16 116 //
Chris@16 117 // space
Chris@16 118 // generates a single character from the associated parameter
Chris@16 119 //
Chris@16 120 ///////////////////////////////////////////////////////////////////////////
Chris@16 121 template <typename CharEncoding>
Chris@16 122 struct any_space
Chris@16 123 : char_generator<any_space<CharEncoding>, CharEncoding, tag::space>
Chris@16 124 {
Chris@16 125 typedef typename CharEncoding::char_type char_type;
Chris@16 126 typedef CharEncoding char_encoding;
Chris@16 127
Chris@16 128 template <typename Context, typename Unused>
Chris@16 129 struct attribute
Chris@16 130 {
Chris@16 131 typedef char_type type;
Chris@16 132 };
Chris@16 133
Chris@16 134 // any_space has an attached parameter
Chris@16 135 template <typename Attribute, typename CharParam, typename Context>
Chris@16 136 bool test(Attribute const& attr, CharParam& ch, Context&) const
Chris@16 137 {
Chris@16 138 ch = CharParam(attr);
Chris@16 139
Chris@16 140 using spirit::char_class::classify;
Chris@16 141 return classify<char_encoding>::is(tag::space(), attr);
Chris@16 142 }
Chris@16 143
Chris@16 144 // any_space has no attribute attached, use single space character
Chris@16 145 template <typename CharParam, typename Context>
Chris@16 146 bool test(unused_type, CharParam& ch, Context&) const
Chris@16 147 {
Chris@16 148 ch = ' ';
Chris@16 149 return true;
Chris@16 150 }
Chris@16 151
Chris@16 152 template <typename Context>
Chris@16 153 static info what(Context const& /*context*/)
Chris@16 154 {
Chris@16 155 return info("space");
Chris@16 156 }
Chris@16 157 };
Chris@16 158
Chris@16 159 ///////////////////////////////////////////////////////////////////////////
Chris@16 160 // Generator generators: make_xxx function (objects)
Chris@16 161 ///////////////////////////////////////////////////////////////////////////
Chris@16 162
Chris@16 163 namespace detail
Chris@16 164 {
Chris@16 165 template <typename Tag, bool lower = false, bool upper = false>
Chris@16 166 struct make_char_class : mpl::identity<Tag> {};
Chris@16 167
Chris@16 168 template <>
Chris@16 169 struct make_char_class<tag::alpha, true, false>
Chris@16 170 : mpl::identity<tag::lower> {};
Chris@16 171
Chris@16 172 template <>
Chris@16 173 struct make_char_class<tag::alpha, false, true>
Chris@16 174 : mpl::identity<tag::upper> {};
Chris@16 175
Chris@16 176 template <>
Chris@16 177 struct make_char_class<tag::alnum, true, false>
Chris@16 178 : mpl::identity<tag::lowernum> {};
Chris@16 179
Chris@16 180 template <>
Chris@16 181 struct make_char_class<tag::alnum, false, true>
Chris@16 182 : mpl::identity<tag::uppernum> {};
Chris@16 183 }
Chris@16 184
Chris@16 185 // enables alnum, alpha, graph, etc.
Chris@16 186 template <typename CharClass, typename CharEncoding, typename Modifiers>
Chris@16 187 struct make_primitive<tag::char_code<CharClass, CharEncoding>, Modifiers>
Chris@16 188 {
Chris@16 189 static bool const lower =
Chris@16 190 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Chris@16 191 static bool const upper =
Chris@16 192 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
Chris@16 193
Chris@16 194 typedef tag::char_code<
Chris@16 195 typename detail::make_char_class<CharClass, lower, upper>::type
Chris@16 196 , CharEncoding>
Chris@16 197 tag_type;
Chris@16 198
Chris@16 199 typedef char_class<
Chris@16 200 tag_type
Chris@16 201 , typename spirit::detail::get_encoding_with_case<
Chris@16 202 Modifiers, CharEncoding, lower || upper>::type
Chris@16 203 , typename detail::get_casetag<Modifiers, lower || upper>::type
Chris@16 204 > result_type;
Chris@16 205
Chris@16 206 result_type operator()(unused_type, unused_type) const
Chris@16 207 {
Chris@16 208 return result_type();
Chris@16 209 }
Chris@16 210 };
Chris@16 211
Chris@16 212 // space is special
Chris@16 213 template <typename CharEncoding, typename Modifiers>
Chris@16 214 struct make_primitive<tag::char_code<tag::space, CharEncoding>, Modifiers>
Chris@16 215 {
Chris@16 216 typedef any_space<CharEncoding> result_type;
Chris@16 217
Chris@16 218 result_type operator()(unused_type, unused_type) const
Chris@16 219 {
Chris@16 220 return result_type();
Chris@16 221 }
Chris@16 222 };
Chris@16 223
Chris@16 224 }}} // namespace boost::spirit::karma
Chris@16 225
Chris@16 226 #endif // !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)