recursive_variant.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //-----------------------------------------------------------------------------
  2. // boost variant/recursive_variant.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003 Eric Friedman
  7. // Copyright (c) 2013-2024 Antony Polukhin
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
  13. #define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
  14. #include <boost/variant/variant_fwd.hpp>
  15. #include <boost/variant/detail/enable_recursive.hpp>
  16. #include <boost/variant/detail/substitute_fwd.hpp>
  17. #include <boost/variant/detail/make_variant_list.hpp>
  18. #include <boost/variant/detail/over_sequence.hpp>
  19. #include <boost/mpl/aux_/lambda_arity_param.hpp>
  20. #include <boost/mpl/equal.hpp>
  21. #include <boost/mpl/eval_if.hpp>
  22. #include <boost/mpl/identity.hpp>
  23. #include <boost/mpl/if.hpp>
  24. #include <boost/mpl/protect.hpp>
  25. #include <boost/mpl/transform.hpp>
  26. #include <boost/type_traits/is_same.hpp>
  27. #include <boost/preprocessor/cat.hpp>
  28. #include <boost/preprocessor/repeat.hpp>
  29. #include <boost/mpl/bool.hpp>
  30. #include <boost/mpl/is_sequence.hpp>
  31. #include <boost/variant/variant.hpp>
  32. namespace boost {
  33. namespace detail { namespace variant {
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // (detail) metafunction specialization substitute
  36. //
  37. // Handles embedded variant types when substituting for recursive_variant_.
  38. //
  39. template <
  40. BOOST_VARIANT_ENUM_PARAMS(typename T)
  41. , typename RecursiveVariant
  42. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
  43. >
  44. struct substitute<
  45. ::boost::variant<
  46. recursive_flag< T0 >
  47. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  48. >
  49. , RecursiveVariant
  50. , ::boost::recursive_variant_
  51. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
  52. >
  53. {
  54. typedef ::boost::variant<
  55. recursive_flag< T0 >
  56. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  57. > type;
  58. };
  59. template <
  60. BOOST_VARIANT_ENUM_PARAMS(typename T)
  61. , typename RecursiveVariant
  62. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
  63. >
  64. struct substitute<
  65. ::boost::variant<
  66. ::boost::detail::variant::over_sequence< T0 >
  67. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  68. >
  69. , RecursiveVariant
  70. , ::boost::recursive_variant_
  71. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
  72. >
  73. {
  74. private:
  75. typedef T0 initial_types;
  76. typedef typename mpl::transform<
  77. initial_types
  78. , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
  79. >::type types;
  80. public:
  81. typedef typename mpl::if_<
  82. mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
  83. , ::boost::variant<
  84. ::boost::detail::variant::over_sequence< T0 >
  85. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  86. >
  87. , ::boost::variant< over_sequence<types> >
  88. >::type type;
  89. };
  90. template <
  91. BOOST_VARIANT_ENUM_PARAMS(typename T)
  92. , typename RecursiveVariant
  93. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
  94. >
  95. struct substitute<
  96. ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
  97. , RecursiveVariant
  98. , ::boost::recursive_variant_
  99. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
  100. >
  101. {
  102. typedef ::boost::variant<
  103. typename enable_recursive<
  104. T0
  105. , RecursiveVariant
  106. , mpl::true_
  107. >::type,
  108. typename enable_recursive<
  109. TN
  110. , RecursiveVariant
  111. , mpl::true_
  112. >::type...
  113. > type;
  114. };
  115. }} // namespace detail::variant
  116. ///////////////////////////////////////////////////////////////////////////////
  117. // metafunction make_recursive_variant
  118. //
  119. // See docs and boost/variant/variant_fwd.hpp for more information.
  120. //
  121. template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
  122. struct make_recursive_variant
  123. {
  124. public: // metafunction result
  125. typedef boost::variant<
  126. detail::variant::recursive_flag< T0 >
  127. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  128. > type;
  129. };
  130. ///////////////////////////////////////////////////////////////////////////////
  131. // metafunction make_recursive_variant_over
  132. //
  133. // See docs and boost/variant/variant_fwd.hpp for more information.
  134. //
  135. template <typename Types>
  136. struct make_recursive_variant_over
  137. {
  138. private: // precondition assertions
  139. BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
  140. public: // metafunction result
  141. typedef typename make_recursive_variant<
  142. detail::variant::over_sequence< Types >
  143. >::type type;
  144. };
  145. } // namespace boost
  146. #endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP