/Src/Dependencies/Boost/boost/spirit/home/classic/dynamic/for.hpp

http://hadesmem.googlecode.com/ · C++ Header · 187 lines · 138 code · 26 blank · 23 comment · 2 complexity · f2d98a6587abbb4a7be5a7b34b68f88a MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Joel de Guzman
  3. Copyright (c) 2002-2003 Martin Wille
  4. http://spirit.sourceforge.net/
  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. #ifndef BOOST_SPIRIT_FOR_HPP
  9. #define BOOST_SPIRIT_FOR_HPP
  10. ////////////////////////////////////////////////////////////////////////////////
  11. #include <boost/spirit/home/classic/namespace.hpp>
  12. #include <boost/spirit/home/classic/core/parser.hpp>
  13. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  14. #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
  15. ////////////////////////////////////////////////////////////////////////////////
  16. namespace boost { namespace spirit {
  17. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  18. namespace impl
  19. {
  20. template <typename FuncT>
  21. struct for_functor
  22. {
  23. typedef typename boost::call_traits<FuncT>::param_type param_t;
  24. for_functor(param_t f) : func(f) {}
  25. for_functor() {}
  26. FuncT func;
  27. };
  28. template <typename InitF>
  29. struct for_init_functor : for_functor<InitF>
  30. {
  31. typedef for_functor<InitF> base_t;
  32. typedef typename base_t::param_t param_t;
  33. for_init_functor(param_t f) : base_t(f) {}
  34. for_init_functor() : base_t() {}
  35. void init() const { /*return*/ this->func(); }
  36. };
  37. template <typename StepF>
  38. struct for_step_functor : for_functor<StepF>
  39. {
  40. typedef for_functor<StepF> base_t;
  41. typedef typename base_t::param_t param_t;
  42. for_step_functor(param_t f) : base_t(f) {}
  43. for_step_functor() : base_t() {}
  44. void step() const { /*return*/ this->func(); }
  45. };
  46. //////////////////////////////////
  47. // for_parser
  48. template
  49. <
  50. typename InitF, typename CondT, typename StepF,
  51. typename ParsableT
  52. >
  53. struct for_parser
  54. : private for_init_functor<InitF>
  55. , private for_step_functor<StepF>
  56. , private condition_evaluator<typename as_parser<CondT>::type>
  57. , public unary
  58. <
  59. typename as_parser<ParsableT>::type,
  60. parser< for_parser<InitF, CondT, StepF, ParsableT> >
  61. >
  62. {
  63. typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
  64. typedef as_parser<CondT> cond_as_parser_t;
  65. typedef typename cond_as_parser_t::type condition_t;
  66. typedef condition_evaluator<condition_t> eval_t;
  67. typedef as_parser<ParsableT> as_parser_t;
  68. typedef typename as_parser_t::type parser_t;
  69. typedef unary< parser_t, parser< self_t > > base_t;
  70. //////////////////////////////
  71. // constructor, saves init, condition and step functors
  72. // for later use the parse member function
  73. for_parser
  74. (
  75. InitF const &i, CondT const &c, StepF const &s,
  76. ParsableT const &p
  77. )
  78. : for_init_functor<InitF>(i)
  79. , for_step_functor<StepF>(s)
  80. , eval_t(cond_as_parser_t::convert(c))
  81. , base_t(as_parser_t::convert(p))
  82. { }
  83. for_parser()
  84. : for_init_functor<InitF>()
  85. , for_step_functor<StepF>()
  86. , eval_t()
  87. , base_t()
  88. {}
  89. //////////////////////////////
  90. // parse member function
  91. template <typename ScannerT>
  92. typename parser_result<self_t, ScannerT>::type
  93. parse(ScannerT const &scan) const
  94. {
  95. typedef typename parser_result<self_t, ScannerT>::type
  96. result_t;
  97. typedef typename parser_result<parser_t, ScannerT>::type
  98. body_result_t;
  99. typename ScannerT::iterator_t save(scan.first);
  100. std::size_t length = 0;
  101. int eval_length = 0;
  102. this->init();
  103. while ((eval_length = this->evaluate(scan))>=0)
  104. {
  105. length += eval_length;
  106. body_result_t tmp(this->subject().parse(scan));
  107. if (tmp)
  108. {
  109. length+=tmp.length();
  110. }
  111. else
  112. {
  113. return scan.no_match();
  114. }
  115. this->step();
  116. }
  117. BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
  118. return scan.create_match
  119. (length, attr, save, scan.first);
  120. }
  121. };
  122. //////////////////////////////////
  123. // for_parser_gen generates takes the body parser in brackets
  124. // and returns the for_parser
  125. template <typename InitF, typename CondT, typename StepF>
  126. struct for_parser_gen
  127. {
  128. for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
  129. : init(i)
  130. , condition(c)
  131. , step(s)
  132. {}
  133. template <typename ParsableT>
  134. for_parser<InitF, CondT, StepF, ParsableT>
  135. operator[](ParsableT const &p) const
  136. {
  137. return for_parser<InitF, CondT, StepF, ParsableT>
  138. (init, condition, step, p);
  139. }
  140. InitF const &init;
  141. CondT const &condition;
  142. StepF const &step;
  143. };
  144. } // namespace impl
  145. //////////////////////////////
  146. // for_p, returns for-parser generator
  147. // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
  148. template
  149. <
  150. typename InitF, typename ConditionT, typename StepF
  151. >
  152. impl::for_parser_gen<InitF, ConditionT, StepF>
  153. for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
  154. {
  155. return impl::for_parser_gen<InitF, ConditionT, StepF>
  156. (init_f, condition, step_f);
  157. }
  158. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  159. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  160. #endif // BOOST_SPIRIT_FOR_HPP