wrap_action.hpp 5.6 KB

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