wrap_action.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  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. #if !defined(BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM)
  9. #define BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/spirit/include/phoenix_core.hpp>
  14. #include <boost/spirit/include/phoenix_bind.hpp>
  15. #include <boost/spirit/include/phoenix_scope.hpp>
  16. #include <boost/spirit/home/support/attributes.hpp>
  17. #include <boost/spirit/home/lex/lexer/pass_flags.hpp>
  18. ///////////////////////////////////////////////////////////////////////////////
  19. namespace boost { namespace spirit { namespace lex { namespace lexertl
  20. {
  21. namespace detail
  22. {
  23. template <typename FunctionType, typename Iterator, typename Context
  24. , typename IdType>
  25. struct wrap_action
  26. {
  27. // plain functions with 5 arguments, function objects (including
  28. // phoenix actors) are not touched at all
  29. template <typename F>
  30. static FunctionType call(F const& f)
  31. {
  32. return f;
  33. }
  34. // semantic actions with 4 arguments
  35. template <typename F>
  36. static void arg4_action(F* f, Iterator& start, Iterator& end
  37. , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType& id
  38. , Context const&)
  39. {
  40. f(start, end, pass, id);
  41. }
  42. template <typename A0, typename A1, typename A2, typename A3>
  43. static FunctionType call(void (*f)(A0, A1, A2, A3))
  44. {
  45. void (*pf)(void(*)(A0, A1, A2, A3)
  46. , Iterator&, Iterator&, BOOST_SCOPED_ENUM(pass_flags)&
  47. , IdType&, Context const&) = &wrap_action::arg4_action;
  48. using phoenix::arg_names::_1;
  49. using phoenix::arg_names::_2;
  50. using phoenix::arg_names::_3;
  51. using phoenix::arg_names::_4;
  52. using phoenix::arg_names::_5;
  53. return phoenix::bind(pf, f, _1, _2, _3, _4, _5);
  54. }
  55. // semantic actions with 3 arguments
  56. template <typename F>
  57. static void arg3_action(F* f, Iterator& start, Iterator& end
  58. , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType
  59. , Context const&)
  60. {
  61. f(start, end, pass);
  62. }
  63. template <typename A0, typename A1, typename A2>
  64. static FunctionType call(void (*f)(A0, A1, A2))
  65. {
  66. void (*pf)(void(*)(A0, A1, A2), Iterator&, Iterator&
  67. , BOOST_SCOPED_ENUM(pass_flags)&, IdType
  68. , Context const&) = &wrap_action::arg3_action;
  69. using phoenix::arg_names::_1;
  70. using phoenix::arg_names::_2;
  71. using phoenix::arg_names::_3;
  72. using phoenix::arg_names::_4;
  73. using phoenix::arg_names::_5;
  74. return phoenix::bind(pf, f, _1, _2, _3, _4, _5);
  75. }
  76. // semantic actions with 2 arguments
  77. template <typename F>
  78. static void arg2_action(F* f, Iterator& start, Iterator& end
  79. , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&)
  80. {
  81. f (start, end);
  82. }
  83. template <typename A0, typename A1>
  84. static FunctionType call(void (*f)(A0, A1))
  85. {
  86. void (*pf)(void(*)(A0, A1), Iterator&, Iterator&
  87. , BOOST_SCOPED_ENUM(pass_flags)&
  88. , IdType, Context const&) = &wrap_action::arg2_action;
  89. using phoenix::arg_names::_1;
  90. using phoenix::arg_names::_2;
  91. using phoenix::arg_names::_3;
  92. using phoenix::arg_names::_4;
  93. using phoenix::arg_names::_5;
  94. return phoenix::bind(pf, f, _1, _2, _3, _4, _5);
  95. }
  96. // we assume that either both iterators are to be passed to the
  97. // semantic action or none iterator at all (i.e. it's not possible
  98. // to have a lexer semantic action function taking one arguments).
  99. // semantic actions with 0 argument
  100. template <typename F>
  101. static void arg0_action(F* f, Iterator&, Iterator&
  102. , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&)
  103. {
  104. f();
  105. }
  106. static FunctionType call(void (*f)())
  107. {
  108. void (*pf)(void(*)(), Iterator&, Iterator&
  109. , BOOST_SCOPED_ENUM(pass_flags)&
  110. , IdType, Context const&) = &arg0_action;
  111. using phoenix::arg_names::_1;
  112. using phoenix::arg_names::_2;
  113. using phoenix::arg_names::_3;
  114. using phoenix::arg_names::_4;
  115. using phoenix::arg_names::_5;
  116. return phoenix::bind(pf, f, _1, _2, _3, _4, _5);
  117. }
  118. };
  119. // specialization allowing to skip wrapping for lexer types not
  120. // supporting semantic actions
  121. template <typename Iterator, typename Context, typename Idtype>
  122. struct wrap_action<unused_type, Iterator, Context, Idtype>
  123. {
  124. // plain function objects are not touched at all
  125. template <typename F>
  126. static F const& call(F const& f)
  127. {
  128. return f;
  129. }
  130. };
  131. }
  132. }}}}
  133. #endif