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 13 #ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP 14 #define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP 15 16 #include "boost/variant/detail/enable_recursive_fwd.hpp" 17 #include "boost/variant/variant_fwd.hpp" 18 19 #if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) 20 # include "boost/mpl/apply.hpp" 21 # include "boost/mpl/eval_if.hpp" 22 # include "boost/mpl/lambda.hpp" 23 #endif 24 25 #include "boost/variant/detail/substitute.hpp" 26 #include "boost/mpl/aux_/config/ctps.hpp" 27 #include "boost/mpl/bool_fwd.hpp" 28 #include "boost/mpl/if.hpp" 29 #include "boost/mpl/or.hpp" 30 #include "boost/type_traits/is_pointer.hpp" 31 #include "boost/type_traits/is_reference.hpp" 32 #include "boost/type_traits/is_same.hpp" 33 34 #include "boost/variant/recursive_wrapper.hpp" 35 36 namespace boost { 37 namespace detail { namespace variant { 38 39 #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 40 41 # define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \ 42 substitute< T , Dest , Source > \ 43 /**/ 44 45 #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 46 47 /////////////////////////////////////////////////////////////////////////////// 48 // (detail) class template rebind1 49 // 50 // Limited workaround in case 'substitute' metafunction unavailable. 51 // 52 53 template <typename T, typename U1> 54 struct rebind1 55 { 56 private: 57 typedef typename mpl::lambda< 58 mpl::identity<T> 59 >::type le_; 60 61 public: 62 typedef typename mpl::eval_if< 63 is_same< le_, mpl::identity<T> > 64 , le_ // identity<T> 65 , mpl::apply1<le_, U1> 66 >::type type; 67 }; 68 69 # define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \ 70 rebind1< T , Dest > \ 71 /**/ 72 73 #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 74 75 /////////////////////////////////////////////////////////////////////////////// 76 // (detail) metafunction enable_recursive 77 // 78 // See boost/variant/detail/enable_recursive_fwd.hpp for more information. 79 // 80 81 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) 82 83 template <typename T, typename RecursiveVariant, typename NoWrapper> 84 struct enable_recursive 85 : BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL( 86 T, RecursiveVariant, ::boost::recursive_variant_ 87 ) 88 { 89 }; 90 91 template <typename T, typename RecursiveVariant> 92 struct enable_recursive< T,RecursiveVariant,mpl::false_ > 93 { 94 private: // helpers, for metafunction result (below) 95 96 typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL( 97 T, RecursiveVariant, ::boost::recursive_variant_ 98 )::type t_; 99 100 public: // metafunction result 101 102 // [Wrap with recursive_wrapper only if rebind really changed something:] 103 typedef typename mpl::if_< 104 mpl::or_< 105 is_same< t_,T > 106 , is_reference<t_> 107 , is_pointer<t_> 108 > 109 , t_ 110 , boost::recursive_wrapper<t_> 111 >::type type; 112 113 }; 114 115 #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) 116 117 template <typename T, typename RecursiveVariant, typename NoWrapper> 118 struct enable_recursive 119 { 120 private: // helpers, for metafunction result (below) 121 122 typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL( 123 T, RecursiveVariant, ::boost::recursive_variant_ 124 )::type t_; 125 126 public: // metafunction result 127 128 // [Wrap with recursive_wrapper only if rebind really changed something:] 129 typedef typename mpl::if_< 130 mpl::or_< 131 NoWrapper 132 , is_same< t_,T > 133 , is_reference<t_> 134 , is_pointer<t_> 135 > 136 , t_ 137 , boost::recursive_wrapper<t_> 138 >::type type; 139 140 }; 141 142 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround 143 144 /////////////////////////////////////////////////////////////////////////////// 145 // (detail) metafunction class quoted_enable_recursive 146 // 147 // Same behavior as enable_recursive metafunction (see above). 148 // 149 template <typename RecursiveVariant, typename NoWrapper> 150 struct quoted_enable_recursive 151 { 152 template <typename T> 153 struct apply 154 : enable_recursive<T, RecursiveVariant, NoWrapper> 155 { 156 }; 157 }; 158 159 }} // namespace detail::variant 160 } // namespace boost 161 162 #endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP 163