parse_auto.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Hartmut Kaiser
  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_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM)
  7. #define BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/parse.hpp>
  12. #include <boost/spirit/home/qi/auto/create_parser.hpp>
  13. #include <boost/utility/enable_if.hpp>
  14. #include <boost/mpl/not.hpp>
  15. #include <boost/mpl/and.hpp>
  16. namespace boost { namespace spirit { namespace qi { namespace detail
  17. {
  18. ///////////////////////////////////////////////////////////////////////////
  19. template <typename Expr>
  20. struct parse_impl<Expr
  21. , typename enable_if<
  22. mpl::and_<
  23. traits::meta_create_exists<qi::domain, Expr>
  24. , mpl::not_<traits::matches<qi::domain, Expr> > >
  25. >::type>
  26. {
  27. template <typename Iterator>
  28. static bool call(Iterator& first, Iterator last, Expr& expr)
  29. {
  30. return qi::parse(first, last, create_parser<Expr>(), expr);
  31. }
  32. template <typename Iterator>
  33. static bool call(Iterator& first, Iterator last, Expr const& expr)
  34. {
  35. return qi::parse(first, last, create_parser<Expr>()
  36. , const_cast<Expr&>(expr));
  37. }
  38. };
  39. // the following specializations are needed to explicitly disambiguate
  40. // the two possible specializations for parse_impl<char> and
  41. // parse_impl<wchar_t>
  42. template <>
  43. struct parse_impl<char>
  44. {
  45. template <typename Iterator>
  46. static bool call(Iterator& first, Iterator last, char& expr)
  47. {
  48. return qi::parse(first, last, create_parser<char>(), expr);
  49. }
  50. template <typename Iterator>
  51. static bool call(Iterator& first, Iterator last, char const&)
  52. {
  53. return qi::parse(first, last, create_parser<char>());
  54. }
  55. };
  56. template <>
  57. struct parse_impl<wchar_t>
  58. {
  59. template <typename Iterator>
  60. static bool call(Iterator& first, Iterator last, wchar_t& expr)
  61. {
  62. return qi::parse(first, last, create_parser<wchar_t>(), expr);
  63. }
  64. template <typename Iterator>
  65. static bool call(Iterator& first, Iterator last, wchar_t const&)
  66. {
  67. return qi::parse(first, last, create_parser<wchar_t>());
  68. }
  69. };
  70. ///////////////////////////////////////////////////////////////////////////
  71. template <typename Expr>
  72. struct phrase_parse_impl<Expr
  73. , typename enable_if<
  74. mpl::and_<
  75. traits::meta_create_exists<qi::domain, Expr>
  76. , mpl::not_<traits::matches<qi::domain, Expr> > >
  77. >::type>
  78. {
  79. template <typename Iterator, typename Skipper>
  80. static bool call(Iterator& first, Iterator last, Expr& expr
  81. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  82. {
  83. return qi::phrase_parse(first, last, create_parser<Expr>()
  84. , skipper, post_skip, expr);
  85. }
  86. template <typename Iterator, typename Skipper>
  87. static bool call(Iterator& first, Iterator last, Expr const& expr
  88. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  89. {
  90. return qi::phrase_parse(first, last, create_parser<Expr>()
  91. , skipper, post_skip, const_cast<Expr&>(expr));
  92. }
  93. };
  94. // the following specializations are needed to explicitly disambiguate
  95. // the two possible specializations for phrase_parse_impl<char> and
  96. // phrase_parse_impl<wchar_t>
  97. template <>
  98. struct phrase_parse_impl<char>
  99. {
  100. template <typename Iterator, typename Skipper>
  101. static bool call(Iterator& first, Iterator last, char& expr
  102. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  103. {
  104. return qi::phrase_parse(first, last, create_parser<char>()
  105. , skipper, post_skip, expr);
  106. }
  107. template <typename Iterator, typename Skipper>
  108. static bool call(Iterator& first, Iterator last, char const&
  109. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  110. {
  111. return qi::phrase_parse(first, last, create_parser<char>()
  112. , skipper, post_skip);
  113. }
  114. };
  115. template <>
  116. struct phrase_parse_impl<wchar_t>
  117. {
  118. template <typename Iterator, typename Skipper>
  119. static bool call(Iterator& first, Iterator last, wchar_t& expr
  120. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  121. {
  122. return qi::phrase_parse(first, last, create_parser<wchar_t>()
  123. , skipper, post_skip, expr);
  124. }
  125. template <typename Iterator, typename Skipper>
  126. static bool call(Iterator& first, Iterator last, wchar_t const&
  127. , Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
  128. {
  129. return qi::phrase_parse(first, last, create_parser<wchar_t>()
  130. , skipper, post_skip);
  131. }
  132. };
  133. }}}}
  134. namespace boost { namespace spirit { namespace qi
  135. {
  136. ///////////////////////////////////////////////////////////////////////////
  137. template <typename Iterator, typename Expr>
  138. inline bool
  139. parse(
  140. Iterator& first
  141. , Iterator last
  142. , Expr& expr)
  143. {
  144. // Make sure the iterator is at least a forward_iterator. If you got a
  145. // compilation error here, then you are using an input_iterator while
  146. // calling this function, you need to supply at least a
  147. // forward_iterator instead.
  148. BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
  149. return detail::parse_impl<Expr>::call(first, last, expr);
  150. }
  151. ///////////////////////////////////////////////////////////////////////////
  152. template <typename Iterator, typename Expr, typename Skipper>
  153. inline bool
  154. phrase_parse(
  155. Iterator& first
  156. , Iterator last
  157. , Expr& expr
  158. , Skipper const& skipper
  159. , BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
  160. {
  161. // Make sure the iterator is at least a forward_iterator. If you got a
  162. // compilation error here, then you are using an input_iterator while
  163. // calling this function, you need to supply at least a
  164. // forward_iterator instead.
  165. BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
  166. return detail::phrase_parse_impl<Expr>::call(
  167. first, last, expr, skipper, post_skip);
  168. }
  169. }}}
  170. #endif