conditions.ipp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Martin Wille
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #ifndef BOOST_SPIRIT_CONDITIONS_IPP
  9. #define BOOST_SPIRIT_CONDITIONS_IPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include <boost/spirit/home/classic/meta/parser_traits.hpp>
  12. #include <boost/spirit/home/classic/core/composite/epsilon.hpp>
  13. ///////////////////////////////////////////////////////////////////////////////
  14. namespace boost { namespace spirit {
  15. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  16. namespace impl {
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //
  19. // condition evaluation
  20. //
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //////////////////////////////////
  23. // condition_parser_selector, decides which parser to use for a condition
  24. // If the template argument is a parser then that parser is used.
  25. // If the template argument is a functor then a condition parser using
  26. // the functor is chosen
  27. template <typename T> struct embed_t_accessor
  28. {
  29. typedef typename T::embed_t type;
  30. };
  31. template <typename ConditionT>
  32. struct condition_parser_selector
  33. {
  34. typedef
  35. typename mpl::if_<
  36. is_parser<ConditionT>,
  37. ConditionT,
  38. condition_parser<ConditionT>
  39. >::type
  40. type;
  41. typedef typename embed_t_accessor<type>::type embed_t;
  42. };
  43. //////////////////////////////////
  44. // condition_evaluator, uses a parser to check wether a condition is met
  45. // takes a parser or a functor that can be evaluated in boolean context
  46. // as template parameter.
  47. // JDG 4-15-03 refactored
  48. template <typename ConditionT>
  49. struct condition_evaluator
  50. {
  51. typedef condition_parser_selector<ConditionT> selector_t;
  52. typedef typename selector_t::type selected_t;
  53. typedef typename selector_t::embed_t cond_embed_t;
  54. typedef typename boost::call_traits<cond_embed_t>::param_type
  55. param_t;
  56. condition_evaluator(param_t s) : cond(s) {}
  57. /////////////////////////////
  58. // evaluate, checks wether condition is met
  59. // returns length of a match or a negative number for no-match
  60. template <typename ScannerT>
  61. std::ptrdiff_t
  62. evaluate(ScannerT const &scan) const
  63. {
  64. typedef typename ScannerT::iterator_t iterator_t;
  65. typedef typename parser_result<selected_t, ScannerT>::type cres_t;
  66. iterator_t save(scan.first);
  67. cres_t result = cond.parse(scan);
  68. if (!result) // reset the position if evaluation
  69. scan.first = save; // fails.
  70. return result.length();
  71. }
  72. cond_embed_t cond;
  73. };
  74. ///////////////////////////////////////////////////////////////////////////////
  75. } // namespace impl
  76. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  77. }} // namespace boost::spirit
  78. #endif