meta_compiler.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. #if !defined(BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_0347PM)
  7. #define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_0347PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/meta_compiler.hpp>
  12. #include <boost/spirit/home/qi/domain.hpp>
  13. #include <boost/spirit/home/qi/parser.hpp>
  14. #include <boost/spirit/home/support/string_traits.hpp>
  15. #include <boost/type_traits/remove_reference.hpp>
  16. #include <boost/utility/enable_if.hpp>
  17. #include <boost/fusion/include/at.hpp>
  18. namespace boost { namespace spirit
  19. {
  20. template <typename T>
  21. struct use_terminal<qi::domain, T
  22. , typename enable_if<traits::is_parser<T> >::type> // enables parsers
  23. : mpl::true_ {};
  24. namespace qi
  25. {
  26. template <typename T, typename Modifiers, typename Enable = void>
  27. struct make_primitive // by default, return it as-is
  28. {
  29. typedef T result_type;
  30. template <typename T_>
  31. T_& operator()(T_& val, unused_type) const
  32. {
  33. return val;
  34. }
  35. template <typename T_>
  36. T_ const& operator()(T_ const& val, unused_type) const
  37. {
  38. return val;
  39. }
  40. };
  41. template <typename Tag, typename Elements
  42. , typename Modifiers, typename Enable = void>
  43. struct make_composite;
  44. template <typename Directive, typename Body
  45. , typename Modifiers, typename Enable = void>
  46. struct make_directive
  47. {
  48. typedef Body result_type;
  49. result_type operator()(unused_type, Body const& body, unused_type) const
  50. {
  51. return body; // By default, a directive simply returns its subject
  52. }
  53. };
  54. }
  55. // Qi primitive meta-compiler
  56. template <>
  57. struct make_component<qi::domain, proto::tag::terminal>
  58. {
  59. template <typename Sig>
  60. struct result;
  61. template <typename This, typename Elements, typename Modifiers>
  62. struct result<This(Elements, Modifiers)>
  63. {
  64. typedef typename qi::make_primitive<
  65. typename remove_const<typename Elements::car_type>::type,
  66. typename remove_reference<Modifiers>::type>::result_type
  67. type;
  68. };
  69. template <typename Elements, typename Modifiers>
  70. typename result<make_component(Elements, Modifiers)>::type
  71. operator()(Elements const& elements, Modifiers const& modifiers) const
  72. {
  73. typedef typename remove_const<typename Elements::car_type>::type term;
  74. return qi::make_primitive<term, Modifiers>()(elements.car, modifiers);
  75. }
  76. };
  77. // Qi composite meta-compiler
  78. template <typename Tag>
  79. struct make_component<qi::domain, Tag>
  80. {
  81. template <typename Sig>
  82. struct result;
  83. template <typename This, typename Elements, typename Modifiers>
  84. struct result<This(Elements, Modifiers)>
  85. {
  86. typedef typename
  87. qi::make_composite<Tag, Elements,
  88. typename remove_reference<Modifiers>::type>::result_type
  89. type;
  90. };
  91. template <typename Elements, typename Modifiers>
  92. typename result<make_component(Elements, Modifiers)>::type
  93. operator()(Elements const& elements, Modifiers const& modifiers) const
  94. {
  95. return qi::make_composite<Tag, Elements, Modifiers>()(
  96. elements, modifiers);
  97. }
  98. };
  99. // Qi function meta-compiler
  100. template <>
  101. struct make_component<qi::domain, proto::tag::function>
  102. {
  103. template <typename Sig>
  104. struct result;
  105. template <typename This, typename Elements, typename Modifiers>
  106. struct result<This(Elements, Modifiers)>
  107. {
  108. typedef typename
  109. qi::make_composite<
  110. typename remove_const<typename Elements::car_type>::type,
  111. typename Elements::cdr_type,
  112. typename remove_reference<Modifiers>::type
  113. >::result_type
  114. type;
  115. };
  116. template <typename Elements, typename Modifiers>
  117. typename result<make_component(Elements, Modifiers)>::type
  118. operator()(Elements const& elements, Modifiers const& modifiers) const
  119. {
  120. return qi::make_composite<
  121. typename remove_const<typename Elements::car_type>::type,
  122. typename Elements::cdr_type,
  123. Modifiers>()(elements.cdr, modifiers);
  124. }
  125. };
  126. // Qi directive meta-compiler
  127. template <>
  128. struct make_component<qi::domain, tag::directive>
  129. {
  130. template <typename Sig>
  131. struct result;
  132. template <typename This, typename Elements, typename Modifiers>
  133. struct result<This(Elements, Modifiers)>
  134. {
  135. typedef typename
  136. qi::make_directive<
  137. typename remove_const<typename Elements::car_type>::type,
  138. typename remove_const<typename Elements::cdr_type::car_type>::type,
  139. typename remove_reference<Modifiers>::type
  140. >::result_type
  141. type;
  142. };
  143. template <typename Elements, typename Modifiers>
  144. typename result<make_component(Elements, Modifiers)>::type
  145. operator()(Elements const& elements, Modifiers const& modifiers) const
  146. {
  147. return qi::make_directive<
  148. typename remove_const<typename Elements::car_type>::type,
  149. typename remove_const<typename Elements::cdr_type::car_type>::type,
  150. Modifiers>()(elements.car, elements.cdr.car, modifiers);
  151. }
  152. };
  153. }}
  154. #endif