annotate DEPENDENCIES/generic/include/boost/spirit/home/karma/string/lit.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 // Copyright (c) 2010 Bryce Lelbach
Chris@16 3 //
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 #if !defined(BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM)
Chris@16 8 #define BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM
Chris@16 9
Chris@16 10 #if defined(_MSC_VER)
Chris@16 11 #pragma once
Chris@16 12 #endif
Chris@16 13
Chris@16 14 #include <boost/spirit/home/support/common_terminals.hpp>
Chris@16 15 #include <boost/spirit/home/support/string_traits.hpp>
Chris@16 16 #include <boost/spirit/home/support/info.hpp>
Chris@16 17 #include <boost/spirit/home/support/char_class.hpp>
Chris@16 18 #include <boost/spirit/home/support/container.hpp>
Chris@16 19 #include <boost/spirit/home/support/handles_container.hpp>
Chris@16 20 #include <boost/spirit/home/support/detail/get_encoding.hpp>
Chris@16 21 #include <boost/spirit/home/karma/domain.hpp>
Chris@16 22 #include <boost/spirit/home/karma/meta_compiler.hpp>
Chris@16 23 #include <boost/spirit/home/karma/delimit_out.hpp>
Chris@16 24 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
Chris@16 25 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
Chris@16 26 #include <boost/spirit/home/karma/detail/extract_from.hpp>
Chris@16 27 #include <boost/spirit/home/karma/detail/string_generate.hpp>
Chris@16 28 #include <boost/spirit/home/karma/detail/string_compare.hpp>
Chris@16 29 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
Chris@16 30 #include <boost/fusion/include/at.hpp>
Chris@16 31 #include <boost/fusion/include/vector.hpp>
Chris@16 32 #include <boost/fusion/include/cons.hpp>
Chris@16 33 #include <boost/mpl/if.hpp>
Chris@16 34 #include <boost/mpl/or.hpp>
Chris@16 35 #include <boost/mpl/assert.hpp>
Chris@16 36 #include <boost/mpl/bool.hpp>
Chris@16 37 #include <boost/utility/enable_if.hpp>
Chris@16 38 #include <string>
Chris@16 39
Chris@16 40 ///////////////////////////////////////////////////////////////////////////////
Chris@16 41 namespace boost { namespace spirit
Chris@16 42 {
Chris@16 43 ///////////////////////////////////////////////////////////////////////////
Chris@16 44 // Enablers
Chris@16 45 ///////////////////////////////////////////////////////////////////////////
Chris@16 46 template <typename CharEncoding>
Chris@16 47 struct use_terminal<karma::domain
Chris@16 48 , tag::char_code<tag::string, CharEncoding> > // enables string
Chris@16 49 : mpl::true_ {};
Chris@16 50
Chris@16 51 template <typename T>
Chris@16 52 struct use_terminal<karma::domain, T
Chris@16 53 , typename enable_if<traits::is_string<T> >::type> // enables string literals
Chris@16 54 : mpl::true_ {};
Chris@16 55
Chris@16 56 template <typename CharEncoding, typename A0>
Chris@16 57 struct use_terminal<karma::domain
Chris@16 58 , terminal_ex<
Chris@16 59 tag::char_code<tag::string, CharEncoding> // enables string(str)
Chris@16 60 , fusion::vector1<A0> >
Chris@16 61 > : traits::is_string<A0> {};
Chris@16 62
Chris@16 63 template <typename CharEncoding> // enables string(f)
Chris@16 64 struct use_lazy_terminal<
Chris@16 65 karma::domain
Chris@16 66 , tag::char_code<tag::string, CharEncoding>
Chris@16 67 , 1 /*arity*/
Chris@16 68 > : mpl::true_ {};
Chris@16 69
Chris@16 70 // enables lit(str)
Chris@16 71 template <typename A0>
Chris@16 72 struct use_terminal<karma::domain
Chris@16 73 , terminal_ex<tag::lit, fusion::vector1<A0> >
Chris@16 74 , typename enable_if<traits::is_string<A0> >::type>
Chris@16 75 : mpl::true_ {};
Chris@16 76 }}
Chris@16 77
Chris@16 78 ///////////////////////////////////////////////////////////////////////////////
Chris@16 79 namespace boost { namespace spirit { namespace karma
Chris@16 80 {
Chris@16 81 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
Chris@16 82 using spirit::lit;
Chris@16 83 #endif
Chris@16 84 using spirit::lit_type;
Chris@16 85
Chris@16 86 ///////////////////////////////////////////////////////////////////////////
Chris@16 87 // generate literal strings from a given parameter
Chris@16 88 ///////////////////////////////////////////////////////////////////////////
Chris@16 89 template <typename CharEncoding, typename Tag>
Chris@16 90 struct any_string
Chris@16 91 : primitive_generator<any_string<CharEncoding, Tag> >
Chris@16 92 {
Chris@16 93 typedef typename CharEncoding::char_type char_type;
Chris@16 94 typedef CharEncoding char_encoding;
Chris@16 95
Chris@16 96 template <typename Context, typename Unused = unused_type>
Chris@16 97 struct attribute
Chris@16 98 {
Chris@16 99 typedef std::basic_string<char_type> type;
Chris@16 100 };
Chris@16 101
Chris@16 102 // lit has an attached attribute
Chris@16 103 template <typename OutputIterator, typename Context, typename Delimiter
Chris@16 104 , typename Attribute>
Chris@16 105 static bool
Chris@16 106 generate(OutputIterator& sink, Context& context, Delimiter const& d,
Chris@16 107 Attribute const& attr)
Chris@16 108 {
Chris@16 109 if (!traits::has_optional_value(attr))
Chris@16 110 return false;
Chris@16 111
Chris@16 112 typedef typename attribute<Context>::type attribute_type;
Chris@16 113 return
Chris@16 114 karma::detail::string_generate(sink
Chris@16 115 , traits::extract_from<attribute_type>(attr, context)
Chris@16 116 , char_encoding(), Tag()) &&
Chris@16 117 karma::delimit_out(sink, d); // always do post-delimiting
Chris@16 118 }
Chris@16 119
Chris@16 120 // this lit has no attribute attached, it needs to have been
Chris@16 121 // initialized from a direct literal
Chris@16 122 template <typename OutputIterator, typename Context, typename Delimiter>
Chris@16 123 static bool generate(OutputIterator&, Context&, Delimiter const&,
Chris@16 124 unused_type const&)
Chris@16 125 {
Chris@16 126 // It is not possible (doesn't make sense) to use string without
Chris@16 127 // providing any attribute, as the generator doesn't 'know' what
Chris@16 128 // character to output. The following assertion fires if this
Chris@16 129 // situation is detected in your code.
Chris@16 130 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, string_not_usable_without_attribute, ());
Chris@16 131 return false;
Chris@16 132 }
Chris@16 133
Chris@16 134 template <typename Context>
Chris@16 135 static info what(Context const& /*context*/)
Chris@16 136 {
Chris@16 137 return info("any-string");
Chris@16 138 }
Chris@16 139 };
Chris@16 140
Chris@16 141 ///////////////////////////////////////////////////////////////////////////
Chris@16 142 // generate literal strings
Chris@16 143 ///////////////////////////////////////////////////////////////////////////
Chris@16 144 template <typename String, typename CharEncoding, typename Tag, bool no_attribute>
Chris@16 145 struct literal_string
Chris@16 146 : primitive_generator<literal_string<String, CharEncoding, Tag, no_attribute> >
Chris@16 147 {
Chris@16 148 typedef CharEncoding char_encoding;
Chris@16 149 typedef typename
Chris@16 150 remove_const<typename traits::char_type_of<String>::type>::type
Chris@16 151 char_type;
Chris@16 152 typedef std::basic_string<char_type> string_type;
Chris@16 153
Chris@16 154 template <typename Context, typename Unused = unused_type>
Chris@16 155 struct attribute
Chris@16 156 : mpl::if_c<no_attribute, unused_type, string_type>
Chris@16 157 {};
Chris@16 158
Chris@16 159 literal_string(typename add_reference<String>::type str)
Chris@16 160 : str_(str)
Chris@16 161 {}
Chris@16 162
Chris@16 163 // A string("...") which additionally has an associated attribute emits
Chris@16 164 // its immediate literal only if it matches the attribute, otherwise
Chris@16 165 // it fails.
Chris@16 166 template <
Chris@16 167 typename OutputIterator, typename Context, typename Delimiter
Chris@16 168 , typename Attribute>
Chris@16 169 bool generate(OutputIterator& sink, Context& context
Chris@16 170 , Delimiter const& d, Attribute const& attr) const
Chris@16 171 {
Chris@16 172 if (!traits::has_optional_value(attr))
Chris@16 173 return false;
Chris@16 174
Chris@16 175 // fail if attribute isn't matched by immediate literal
Chris@16 176 typedef typename attribute<Context>::type attribute_type;
Chris@16 177
Chris@16 178 typedef typename spirit::result_of::extract_from<attribute_type, Attribute>::type
Chris@16 179 extracted_string_type;
Chris@16 180
Chris@16 181 using spirit::traits::get_c_string;
Chris@16 182 if (!detail::string_compare(
Chris@16 183 get_c_string(
Chris@16 184 traits::extract_from<attribute_type>(attr, context))
Chris@16 185 , get_c_string(str_), char_encoding(), Tag()))
Chris@16 186 {
Chris@16 187 return false;
Chris@16 188 }
Chris@16 189 return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
Chris@16 190 karma::delimit_out(sink, d); // always do post-delimiting
Chris@16 191 }
Chris@16 192
Chris@16 193 // A string("...") without any associated attribute just emits its
Chris@16 194 // immediate literal
Chris@16 195 template <typename OutputIterator, typename Context, typename Delimiter>
Chris@16 196 bool generate(OutputIterator& sink, Context&, Delimiter const& d
Chris@16 197 , unused_type) const
Chris@16 198 {
Chris@16 199 return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
Chris@16 200 karma::delimit_out(sink, d); // always do post-delimiting
Chris@16 201 }
Chris@16 202
Chris@16 203 template <typename Context>
Chris@16 204 info what(Context const& /*context*/) const
Chris@16 205 {
Chris@16 206 return info("literal-string", str_);
Chris@16 207 }
Chris@16 208
Chris@16 209 string_type str_;
Chris@16 210 };
Chris@16 211
Chris@16 212 ///////////////////////////////////////////////////////////////////////////
Chris@16 213 // Generator generators: make_xxx function (objects)
Chris@16 214 ///////////////////////////////////////////////////////////////////////////
Chris@16 215
Chris@16 216 // string
Chris@16 217 template <typename CharEncoding, typename Modifiers>
Chris@16 218 struct make_primitive<
Chris@16 219 tag::char_code<tag::string, CharEncoding>
Chris@16 220 , Modifiers>
Chris@16 221 {
Chris@16 222 static bool const lower =
Chris@16 223 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Chris@16 224 static bool const upper =
Chris@16 225 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
Chris@16 226
Chris@16 227 typedef any_string<
Chris@16 228 typename spirit::detail::get_encoding_with_case<
Chris@16 229 Modifiers, CharEncoding, lower || upper>::type
Chris@16 230 , typename detail::get_casetag<Modifiers, lower || upper>::type
Chris@16 231 > result_type;
Chris@16 232
Chris@16 233 result_type operator()(unused_type, unused_type) const
Chris@16 234 {
Chris@16 235 return result_type();
Chris@16 236 }
Chris@16 237 };
Chris@16 238
Chris@16 239 // string literal
Chris@16 240 template <typename T, typename Modifiers>
Chris@16 241 struct make_primitive<T, Modifiers
Chris@16 242 , typename enable_if<traits::is_string<T> >::type>
Chris@16 243 {
Chris@16 244 static bool const lower =
Chris@16 245 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Chris@16 246
Chris@16 247 static bool const upper =
Chris@16 248 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
Chris@16 249
Chris@16 250 typedef typename add_const<T>::type const_string;
Chris@16 251 typedef literal_string<
Chris@16 252 const_string
Chris@16 253 , typename spirit::detail::get_encoding_with_case<
Chris@16 254 Modifiers, unused_type, lower || upper>::type
Chris@16 255 , typename detail::get_casetag<Modifiers, lower || upper>::type
Chris@16 256 , true
Chris@16 257 > result_type;
Chris@16 258
Chris@16 259 result_type operator()(
Chris@16 260 typename add_reference<const_string>::type str, unused_type) const
Chris@16 261 {
Chris@16 262 return result_type(str);
Chris@16 263 }
Chris@16 264 };
Chris@16 265
Chris@16 266 ///////////////////////////////////////////////////////////////////////////
Chris@16 267 namespace detail
Chris@16 268 {
Chris@16 269 template <typename CharEncoding, typename Modifiers, typename A0
Chris@16 270 , bool no_attribute>
Chris@16 271 struct make_string_direct
Chris@16 272 {
Chris@16 273 static bool const lower =
Chris@16 274 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Chris@16 275 static bool const upper =
Chris@16 276 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
Chris@16 277
Chris@16 278 typedef typename add_const<A0>::type const_string;
Chris@16 279 typedef literal_string<
Chris@16 280 const_string
Chris@16 281 , typename spirit::detail::get_encoding_with_case<
Chris@16 282 Modifiers, unused_type, lower || upper>::type
Chris@16 283 , typename detail::get_casetag<Modifiers, lower || upper>::type
Chris@16 284 , no_attribute
Chris@16 285 > result_type;
Chris@16 286
Chris@16 287 template <typename Terminal>
Chris@16 288 result_type operator()(Terminal const& term, unused_type) const
Chris@16 289 {
Chris@16 290 return result_type(fusion::at_c<0>(term.args));
Chris@16 291 }
Chris@16 292 };
Chris@16 293 }
Chris@16 294
Chris@16 295 // string("..."), lit("...")
Chris@16 296 template <typename CharEncoding, typename Modifiers, typename A0>
Chris@16 297 struct make_primitive<
Chris@16 298 terminal_ex<
Chris@16 299 tag::char_code<tag::string, CharEncoding>
Chris@16 300 , fusion::vector1<A0> >
Chris@16 301 , Modifiers>
Chris@16 302 : detail::make_string_direct<CharEncoding, Modifiers, A0, false>
Chris@16 303 {};
Chris@16 304
Chris@16 305 template <typename Modifiers, typename A0>
Chris@16 306 struct make_primitive<
Chris@16 307 terminal_ex<tag::lit, fusion::vector1<A0> >
Chris@16 308 , Modifiers
Chris@16 309 , typename enable_if<traits::is_string<A0> >::type>
Chris@16 310 : detail::make_string_direct<
Chris@16 311 typename traits::char_encoding_from_char<
Chris@16 312 typename traits::char_type_of<A0>::type>::type
Chris@16 313 , Modifiers, A0, true>
Chris@16 314 {};
Chris@16 315 }}} // namespace boost::spirit::karma
Chris@16 316
Chris@16 317 namespace boost { namespace spirit { namespace traits
Chris@16 318 {
Chris@16 319 ///////////////////////////////////////////////////////////////////////////
Chris@16 320 template <typename CharEncoding, typename Tag, typename Attribute
Chris@16 321 , typename Context, typename Iterator>
Chris@16 322 struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute
Chris@16 323 , Context, Iterator>
Chris@16 324 : mpl::false_ {};
Chris@16 325
Chris@16 326 template <typename String, typename CharEncoding, typename Tag
Chris@16 327 , bool no_attribute, typename Attribute, typename Context
Chris@16 328 , typename Iterator>
Chris@16 329 struct handles_container<karma::literal_string<String, CharEncoding, Tag
Chris@16 330 , no_attribute>, Attribute, Context, Iterator>
Chris@16 331 : mpl::false_ {};
Chris@16 332 }}}
Chris@16 333
Chris@16 334 #endif