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