meta_compiler.hpp 5.9 KB

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