File indexing completed on 2025-01-19 09:47:39
0001
0002
0003
0004
0005
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
0045
0046 template <typename CharEncoding>
0047 struct use_terminal<karma::domain
0048 , tag::char_code<tag::string, CharEncoding> >
0049 : mpl::true_ {};
0050
0051 template <typename T>
0052 struct use_terminal<karma::domain, T
0053 , typename enable_if<traits::is_string<T> >::type>
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>
0060 , fusion::vector1<A0> >
0061 > : traits::is_string<A0> {};
0062
0063 template <typename CharEncoding>
0064 struct use_lazy_terminal<
0065 karma::domain
0066 , tag::char_code<tag::string, CharEncoding>
0067 , 1
0068 > : mpl::true_ {};
0069
0070
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
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
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);
0118 }
0119
0120
0121
0122 template <typename OutputIterator, typename Context, typename Delimiter>
0123 static bool generate(OutputIterator&, Context&, Delimiter const&,
0124 unused_type const&)
0125 {
0126
0127
0128
0129
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& )
0136 {
0137 return info("any-string");
0138 }
0139 };
0140
0141
0142
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
0164
0165
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
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);
0188 }
0189
0190
0191
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);
0198 }
0199
0200 template <typename Context>
0201 info what(Context const& ) const
0202 {
0203 return info("literal-string", str_);
0204 }
0205
0206 string_type str_;
0207 };
0208
0209
0210
0211
0212
0213
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
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
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 }}}
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