enable_recursive.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //-----------------------------------------------------------------------------
  2. // boost variant/detail/enable_recursive.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003
  7. // Eric Friedman
  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_DETAIL_ENABLE_RECURSIVE_HPP
  13. #define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
  14. #include <boost/variant/detail/enable_recursive_fwd.hpp>
  15. #include <boost/variant/variant_fwd.hpp>
  16. #if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
  17. # include <boost/mpl/apply.hpp>
  18. # include <boost/mpl/eval_if.hpp>
  19. # include <boost/mpl/lambda.hpp>
  20. #endif
  21. #include <boost/variant/detail/substitute.hpp>
  22. #include <boost/mpl/aux_/config/ctps.hpp>
  23. #include <boost/mpl/bool_fwd.hpp>
  24. #include <boost/mpl/if.hpp>
  25. #include <boost/mpl/or.hpp>
  26. #include <boost/type_traits/is_pointer.hpp>
  27. #include <boost/type_traits/is_reference.hpp>
  28. #include <boost/type_traits/is_same.hpp>
  29. #include <boost/variant/recursive_wrapper.hpp>
  30. namespace boost {
  31. namespace detail { namespace variant {
  32. #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  33. # define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \
  34. substitute< T , Dest , Source > \
  35. /**/
  36. #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // (detail) class template rebind1
  39. //
  40. // Limited workaround in case 'substitute' metafunction unavailable.
  41. //
  42. template <typename T, typename U1>
  43. struct rebind1
  44. {
  45. private:
  46. typedef typename mpl::lambda<
  47. mpl::identity<T>
  48. >::type le_;
  49. public:
  50. typedef typename mpl::eval_if<
  51. is_same< le_, mpl::identity<T> >
  52. , le_ // identity<T>
  53. , mpl::apply1<le_, U1>
  54. >::type type;
  55. };
  56. # define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \
  57. rebind1< T , Dest > \
  58. /**/
  59. #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  60. ///////////////////////////////////////////////////////////////////////////////
  61. // (detail) metafunction enable_recursive
  62. //
  63. // See boost/variant/detail/enable_recursive_fwd.hpp for more information.
  64. //
  65. template <typename T, typename RecursiveVariant, typename NoWrapper>
  66. struct enable_recursive
  67. : BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(
  68. T, RecursiveVariant, ::boost::recursive_variant_
  69. )
  70. {
  71. };
  72. template <typename T, typename RecursiveVariant>
  73. struct enable_recursive< T,RecursiveVariant,mpl::false_ >
  74. {
  75. private: // helpers, for metafunction result (below)
  76. typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(
  77. T, RecursiveVariant, ::boost::recursive_variant_
  78. )::type t_;
  79. public: // metafunction result
  80. // [Wrap with recursive_wrapper only if rebind really changed something:]
  81. typedef typename mpl::if_<
  82. mpl::or_<
  83. is_same< t_,T >
  84. , is_reference<t_>
  85. , is_pointer<t_>
  86. >
  87. , t_
  88. , boost::recursive_wrapper<t_>
  89. >::type type;
  90. };
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // (detail) metafunction class quoted_enable_recursive
  93. //
  94. // Same behavior as enable_recursive metafunction (see above).
  95. //
  96. template <typename RecursiveVariant, typename NoWrapper>
  97. struct quoted_enable_recursive
  98. {
  99. template <typename T>
  100. struct apply
  101. : enable_recursive<T, RecursiveVariant, NoWrapper>
  102. {
  103. };
  104. };
  105. }} // namespace detail::variant
  106. } // namespace boost
  107. #endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP