/Src/Dependencies/Boost/boost/spirit/home/qi/string/lit.hpp

http://hadesmem.googlecode.com/ · C++ Header · 312 lines · 249 code · 40 blank · 23 comment · 2 complexity · 64eda9e676147aa295c457034acaa111 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Copyright (c) 2010 Bryce Lelbach
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #if !defined(BOOST_SPIRIT_LIT_APR_18_2006_1125PM)
  9. #define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/spirit/home/qi/domain.hpp>
  14. #include <boost/spirit/home/qi/skip_over.hpp>
  15. #include <boost/spirit/home/qi/detail/string_parse.hpp>
  16. #include <boost/spirit/home/qi/parser.hpp>
  17. #include <boost/spirit/home/qi/meta_compiler.hpp>
  18. #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
  19. #include <boost/spirit/home/qi/detail/enable_lit.hpp>
  20. #include <boost/spirit/home/support/info.hpp>
  21. #include <boost/spirit/home/support/char_class.hpp>
  22. #include <boost/spirit/home/support/modify.hpp>
  23. #include <boost/spirit/home/support/unused.hpp>
  24. #include <boost/spirit/home/support/common_terminals.hpp>
  25. #include <boost/spirit/home/support/string_traits.hpp>
  26. #include <boost/spirit/home/support/detail/get_encoding.hpp>
  27. #include <boost/spirit/home/support/handles_container.hpp>
  28. #include <boost/fusion/include/at.hpp>
  29. #include <boost/fusion/include/value_at.hpp>
  30. #include <boost/type_traits/add_reference.hpp>
  31. #include <boost/type_traits/add_const.hpp>
  32. #include <boost/mpl/assert.hpp>
  33. #include <boost/mpl/if.hpp>
  34. #include <boost/detail/workaround.hpp>
  35. #include <boost/utility/enable_if.hpp>
  36. #include <string>
  37. namespace boost { namespace spirit
  38. {
  39. ///////////////////////////////////////////////////////////////////////////
  40. // Enablers
  41. ///////////////////////////////////////////////////////////////////////////
  42. template <typename T>
  43. struct use_terminal<qi::domain, T
  44. , typename enable_if<traits::is_string<T> >::type> // enables strings
  45. : mpl::true_ {};
  46. template <typename CharEncoding, typename A0>
  47. struct use_terminal<qi::domain
  48. , terminal_ex<
  49. tag::char_code<tag::string, CharEncoding> // enables string(str)
  50. , fusion::vector1<A0> >
  51. > : traits::is_string<A0> {};
  52. template <typename CharEncoding> // enables string(f)
  53. struct use_lazy_terminal<
  54. qi::domain
  55. , tag::char_code<tag::string, CharEncoding>
  56. , 1 /*arity*/
  57. > : mpl::true_ {};
  58. // enables lit(...)
  59. template <typename A0>
  60. struct use_terminal<qi::domain
  61. , terminal_ex<tag::lit, fusion::vector1<A0> >
  62. , typename enable_if<traits::is_string<A0> >::type>
  63. : mpl::true_ {};
  64. }}
  65. namespace boost { namespace spirit { namespace qi
  66. {
  67. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  68. using spirit::lit;
  69. #endif
  70. using spirit::lit_type;
  71. ///////////////////////////////////////////////////////////////////////////
  72. // Parse for literal strings
  73. ///////////////////////////////////////////////////////////////////////////
  74. template <typename String, bool no_attribute>
  75. struct literal_string
  76. : primitive_parser<literal_string<String, no_attribute> >
  77. {
  78. typedef typename
  79. remove_const<typename traits::char_type_of<String>::type>::type
  80. char_type;
  81. typedef std::basic_string<char_type> string_type;
  82. literal_string(typename add_reference<String>::type str)
  83. : str(str)
  84. {}
  85. template <typename Context, typename Iterator>
  86. struct attribute
  87. {
  88. typedef typename mpl::if_c<
  89. no_attribute, unused_type, string_type>::type
  90. type;
  91. };
  92. template <typename Iterator, typename Context
  93. , typename Skipper, typename Attribute>
  94. bool parse(Iterator& first, Iterator const& last
  95. , Context& /*context*/, Skipper const& skipper, Attribute& attr) const
  96. {
  97. qi::skip_over(first, last, skipper);
  98. return detail::string_parse(str, first, last, attr);
  99. }
  100. template <typename Context>
  101. info what(Context& /*context*/) const
  102. {
  103. return info("literal-string", str);
  104. }
  105. String str;
  106. private:
  107. // silence MSVC warning C4512: assignment operator could not be generated
  108. literal_string& operator= (literal_string const&);
  109. };
  110. template <typename String, bool no_attribute>
  111. struct no_case_literal_string
  112. : primitive_parser<no_case_literal_string<String, no_attribute> >
  113. {
  114. typedef typename
  115. remove_const<typename traits::char_type_of<String>::type>::type
  116. char_type;
  117. typedef std::basic_string<char_type> string_type;
  118. template <typename CharEncoding>
  119. no_case_literal_string(char_type const* in, CharEncoding encoding)
  120. : str_lo(in)
  121. , str_hi(in)
  122. {
  123. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  124. encoding; // suppresses warning: C4100: 'encoding' : unreferenced formal parameter
  125. #endif
  126. typename string_type::iterator loi = str_lo.begin();
  127. typename string_type::iterator hii = str_hi.begin();
  128. for (; loi != str_lo.end(); ++loi, ++hii, ++in)
  129. {
  130. typedef typename CharEncoding::char_type encoded_char_type;
  131. *loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
  132. *hii = static_cast<char_type>(encoding.toupper(encoded_char_type(*hii)));
  133. }
  134. }
  135. template <typename Context, typename Iterator>
  136. struct attribute
  137. {
  138. typedef typename mpl::if_c<
  139. no_attribute, unused_type, string_type>::type
  140. type;
  141. };
  142. template <typename Iterator, typename Context
  143. , typename Skipper, typename Attribute>
  144. bool parse(Iterator& first, Iterator const& last
  145. , Context& /*context*/, Skipper const& skipper, Attribute& attr) const
  146. {
  147. qi::skip_over(first, last, skipper);
  148. return detail::string_parse(str_lo, str_hi, first, last, attr);
  149. }
  150. template <typename Context>
  151. info what(Context& /*context*/) const
  152. {
  153. return info("no-case-literal-string", str_lo);
  154. }
  155. string_type str_lo, str_hi;
  156. };
  157. ///////////////////////////////////////////////////////////////////////////
  158. // Parser generators: make_xxx function (objects)
  159. ///////////////////////////////////////////////////////////////////////////
  160. template <typename T, typename Modifiers>
  161. struct make_primitive<T, Modifiers
  162. , typename enable_if<traits::is_string<T> >::type>
  163. {
  164. typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
  165. typedef typename add_const<T>::type const_string;
  166. typedef typename mpl::if_<
  167. no_case
  168. , no_case_literal_string<const_string, true>
  169. , literal_string<const_string, true> >::type
  170. result_type;
  171. result_type operator()(
  172. typename add_reference<const_string>::type str, unused_type) const
  173. {
  174. return op(str, no_case());
  175. }
  176. template <typename String>
  177. result_type op(String const& str, mpl::false_) const
  178. {
  179. return result_type(str);
  180. }
  181. template <typename String>
  182. result_type op(String const& str, mpl::true_) const
  183. {
  184. typename spirit::detail::get_encoding<Modifiers,
  185. spirit::char_encoding::standard>::type encoding;
  186. return result_type(traits::get_c_string(str), encoding);
  187. }
  188. };
  189. // lit("...")
  190. template <typename Modifiers, typename A0>
  191. struct make_primitive<
  192. terminal_ex<tag::lit, fusion::vector1<A0> >
  193. , Modifiers
  194. , typename enable_if<traits::is_string<A0> >::type>
  195. {
  196. typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
  197. typedef typename add_const<A0>::type const_string;
  198. typedef typename mpl::if_<
  199. no_case
  200. , no_case_literal_string<const_string, true>
  201. , literal_string<const_string, true> >::type
  202. result_type;
  203. template <typename Terminal>
  204. result_type operator()(Terminal const& term, unused_type) const
  205. {
  206. return op(fusion::at_c<0>(term.args), no_case());
  207. }
  208. template <typename String>
  209. result_type op(String const& str, mpl::false_) const
  210. {
  211. return result_type(str);
  212. }
  213. template <typename String>
  214. result_type op(String const& str, mpl::true_) const
  215. {
  216. typedef typename traits::char_encoding_from_char<
  217. typename traits::char_type_of<A0>::type>::type encoding_type;
  218. typename spirit::detail::get_encoding<Modifiers,
  219. encoding_type>::type encoding;
  220. return result_type(traits::get_c_string(str), encoding);
  221. }
  222. };
  223. ///////////////////////////////////////////////////////////////////////////
  224. // string("...")
  225. template <typename CharEncoding, typename Modifiers, typename A0>
  226. struct make_primitive<
  227. terminal_ex<
  228. tag::char_code<tag::string, CharEncoding>
  229. , fusion::vector1<A0> >
  230. , Modifiers>
  231. {
  232. typedef CharEncoding encoding;
  233. typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
  234. typedef typename add_const<A0>::type const_string;
  235. typedef typename mpl::if_<
  236. no_case
  237. , no_case_literal_string<const_string, false>
  238. , literal_string<const_string, false> >::type
  239. result_type;
  240. template <typename Terminal>
  241. result_type operator()(Terminal const& term, unused_type) const
  242. {
  243. return op(fusion::at_c<0>(term.args), no_case());
  244. }
  245. template <typename String>
  246. result_type op(String const& str, mpl::false_) const
  247. {
  248. return result_type(str);
  249. }
  250. template <typename String>
  251. result_type op(String const& str, mpl::true_) const
  252. {
  253. return result_type(traits::get_c_string(str), encoding());
  254. }
  255. };
  256. }}}
  257. namespace boost { namespace spirit { namespace traits
  258. {
  259. ///////////////////////////////////////////////////////////////////////////
  260. template <typename String, bool no_attribute, typename Attribute
  261. ,typename Context, typename Iterator>
  262. struct handles_container<qi::literal_string<String, no_attribute>
  263. , Attribute, Context, Iterator>
  264. : mpl::true_ {};
  265. template <typename String, bool no_attribute, typename Attribute
  266. , typename Context, typename Iterator>
  267. struct handles_container<qi::no_case_literal_string<String, no_attribute>
  268. , Attribute, Context, Iterator>
  269. : mpl::true_ {};
  270. }}}
  271. #endif