char_class.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_CHAR_CLASS_APRIL_16_2006_1051AM)
  7. #define BOOST_SPIRIT_CHAR_CLASS_APRIL_16_2006_1051AM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/char/char_parser.hpp>
  12. #include <boost/spirit/home/qi/domain.hpp>
  13. #include <boost/spirit/home/support/char_class.hpp>
  14. #include <boost/spirit/home/support/common_terminals.hpp>
  15. #include <boost/spirit/home/support/info.hpp>
  16. #include <boost/spirit/home/support/modify.hpp>
  17. #include <boost/spirit/home/support/detail/get_encoding.hpp>
  18. #include <boost/mpl/eval_if.hpp>
  19. namespace boost { namespace spirit
  20. {
  21. ///////////////////////////////////////////////////////////////////////////
  22. // Enablers
  23. ///////////////////////////////////////////////////////////////////////////
  24. // enables alnum, alpha, graph, etc.
  25. template <typename CharClass, typename CharEncoding>
  26. struct use_terminal<qi::domain, tag::char_code<CharClass, CharEncoding> >
  27. : mpl::true_ {};
  28. }}
  29. namespace boost { namespace spirit { namespace qi
  30. {
  31. // hoist the char classification namespaces into qi sub-namespaces of the
  32. // same name
  33. namespace ascii { using namespace boost::spirit::ascii; }
  34. namespace iso8859_1 { using namespace boost::spirit::iso8859_1; }
  35. namespace standard { using namespace boost::spirit::standard; }
  36. namespace standard_wide { using namespace boost::spirit::standard_wide; }
  37. #if defined(BOOST_SPIRIT_UNICODE)
  38. namespace unicode { using namespace boost::spirit::unicode; }
  39. #endif
  40. // Import the standard namespace into the qi namespace. This allows
  41. // for default handling of all character/string related operations if not
  42. // prefixed with a character set namespace.
  43. using namespace boost::spirit::standard;
  44. // Import encoding
  45. using spirit::encoding;
  46. ///////////////////////////////////////////////////////////////////////////
  47. // Generic char classification parser (for alnum, alpha, graph, etc.)
  48. ///////////////////////////////////////////////////////////////////////////
  49. template <typename Tag>
  50. struct char_class
  51. : char_parser<char_class<Tag>, typename Tag::char_encoding::char_type>
  52. {
  53. typedef typename Tag::char_encoding char_encoding;
  54. typedef typename Tag::char_class classification;
  55. template <typename CharParam, typename Context>
  56. bool test(CharParam ch, Context&) const
  57. {
  58. using spirit::char_class::classify;
  59. return traits::ischar<CharParam, char_encoding>::call(ch) &&
  60. classify<char_encoding>::is(classification(), ch);
  61. }
  62. template <typename Context>
  63. info what(Context& /*context*/) const
  64. {
  65. typedef spirit::char_class::what<char_encoding> what_;
  66. return info(what_::is(classification()));
  67. }
  68. };
  69. namespace detail
  70. {
  71. template <typename Tag, bool no_case = false>
  72. struct make_char_class : mpl::identity<Tag> {};
  73. template <>
  74. struct make_char_class<tag::lower, true> : mpl::identity<tag::alpha> {};
  75. template <>
  76. struct make_char_class<tag::upper, true> : mpl::identity<tag::alpha> {};
  77. }
  78. ///////////////////////////////////////////////////////////////////////////
  79. // Parser generators: make_xxx function (objects)
  80. ///////////////////////////////////////////////////////////////////////////
  81. template <typename CharClass, typename CharEncoding, typename Modifiers>
  82. struct make_primitive<tag::char_code<CharClass, CharEncoding>, Modifiers>
  83. {
  84. static bool const no_case =
  85. has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
  86. typedef typename
  87. spirit::detail::get_encoding<Modifiers, CharEncoding>::type
  88. char_encoding;
  89. typedef tag::char_code<
  90. typename detail::make_char_class<CharClass, no_case>::type
  91. , char_encoding>
  92. tag;
  93. typedef char_class<tag> result_type;
  94. result_type operator()(unused_type, unused_type) const
  95. {
  96. return result_type();
  97. }
  98. };
  99. }}}
  100. #endif