expect_function.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #ifndef BOOST_SPIRIT_QI_DETAIL_EXPECT_FUNCTION_HPP
  7. #define BOOST_SPIRIT_QI_DETAIL_EXPECT_FUNCTION_HPP
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/unused.hpp>
  12. #include <boost/spirit/home/support/multi_pass_wrapper.hpp>
  13. #include <boost/throw_exception.hpp>
  14. namespace boost { namespace spirit { namespace qi { namespace detail
  15. {
  16. #ifdef _MSC_VER
  17. # pragma warning(push)
  18. # pragma warning(disable: 4512) // assignment operator could not be generated.
  19. #endif
  20. template <
  21. typename Iterator, typename Context
  22. , typename Skipper, typename Exception>
  23. struct expect_function
  24. {
  25. typedef Iterator iterator_type;
  26. typedef Context context_type;
  27. expect_function(
  28. Iterator& first_, Iterator const& last_
  29. , Context& context_, Skipper const& skipper_)
  30. : first(first_)
  31. , last(last_)
  32. , context(context_)
  33. , skipper(skipper_)
  34. , is_first(true)
  35. {
  36. }
  37. template <typename Component, typename Attribute>
  38. bool operator()(Component const& component, Attribute& attr) const
  39. {
  40. // if this is not the first component in the expect chain we
  41. // need to flush any multi_pass iterator we might be acting on
  42. if (!is_first)
  43. spirit::traits::clear_queue(first);
  44. // if we are testing the first component in the sequence,
  45. // return true if the parser fails, if this is not the first
  46. // component, throw exception if the parser fails
  47. if (!component.parse(first, last, context, skipper, attr))
  48. {
  49. if (is_first)
  50. {
  51. is_first = false;
  52. return true; // true means the match failed
  53. }
  54. boost::throw_exception(Exception(first, last, component.what(context)));
  55. #if defined(BOOST_NO_EXCEPTIONS)
  56. return true; // for systems not supporting exceptions
  57. #endif
  58. }
  59. is_first = false;
  60. return false;
  61. }
  62. template <typename Component>
  63. bool operator()(Component const& component) const
  64. {
  65. // if this is not the first component in the expect chain we
  66. // need to flush any multi_pass iterator we might be acting on
  67. if (!is_first)
  68. spirit::traits::clear_queue(first);
  69. // if we are testing the first component in the sequence,
  70. // return true if the parser fails, if this not the first
  71. // component, throw exception if the parser fails
  72. if (!component.parse(first, last, context, skipper, unused))
  73. {
  74. if (is_first)
  75. {
  76. is_first = false;
  77. return true;
  78. }
  79. boost::throw_exception(Exception(first, last, component.what(context)));
  80. #if defined(BOOST_NO_EXCEPTIONS)
  81. return false; // for systems not supporting exceptions
  82. #endif
  83. }
  84. is_first = false;
  85. return false;
  86. }
  87. Iterator& first;
  88. Iterator const& last;
  89. Context& context;
  90. Skipper const& skipper;
  91. mutable bool is_first;
  92. };
  93. #ifdef _MSC_VER
  94. # pragma warning(pop)
  95. #endif
  96. }}}}
  97. #endif