]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //----------------------------------------------------------------------------- |
2 | // boost variant/recursive_wrapper_fwd.hpp header file | |
3 | // See http://www.boost.org for updates, documentation, and revision history. | |
4 | //----------------------------------------------------------------------------- | |
5 | // | |
6 | // Copyright (c) 2002 Eric Friedman, Itay Maman | |
7 | // Copyright (c) 2016 Antony Polukhin | |
8 | // | |
9 | // Portions Copyright (C) 2002 David Abrahams | |
10 | // | |
11 | // Distributed under the Boost Software License, Version 1.0. (See | |
12 | // accompanying file LICENSE_1_0.txt or copy at | |
13 | // http://www.boost.org/LICENSE_1_0.txt) | |
14 | ||
15 | #ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP | |
16 | #define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP | |
17 | ||
18 | #include <boost/mpl/bool.hpp> | |
19 | #include <boost/mpl/aux_/config/ctps.hpp> | |
20 | #include <boost/mpl/aux_/lambda_support.hpp> | |
21 | #include <boost/type_traits/integral_constant.hpp> | |
22 | #include <boost/type_traits/is_constructible.hpp> | |
23 | ||
24 | namespace boost { | |
25 | ||
26 | ////////////////////////////////////////////////////////////////////////// | |
27 | // class template recursive_wrapper | |
28 | // | |
29 | // Enables recursive types in templates by breaking cyclic dependencies. | |
30 | // | |
31 | // For example: | |
32 | // | |
33 | // class my; | |
34 | // | |
35 | // typedef variant< int, recursive_wrapper<my> > var; | |
36 | // | |
37 | // class my { | |
38 | // var var_; | |
39 | // ... | |
40 | // }; | |
41 | // | |
42 | template <typename T> class recursive_wrapper; | |
43 | ||
44 | ||
45 | /////////////////////////////////////////////////////////////////////////////// | |
46 | // metafunction is_constructible partial specializations. | |
47 | // | |
48 | // recursive_wrapper<T> is constructible only from T and recursive_wrapper<T>. | |
49 | // | |
50 | template <class T> struct is_constructible<recursive_wrapper<T>, T> : boost::true_type{}; | |
51 | template <class T> struct is_constructible<recursive_wrapper<T>, const T> : boost::true_type{}; | |
52 | template <class T> struct is_constructible<recursive_wrapper<T>, T&> : boost::true_type{}; | |
53 | template <class T> struct is_constructible<recursive_wrapper<T>, const T&> : boost::true_type{}; | |
54 | template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T> > : boost::true_type{}; | |
55 | template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T> > : boost::true_type{}; | |
56 | template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T>& > : boost::true_type{}; | |
57 | template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T>& > : boost::true_type{}; | |
58 | ||
59 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, U > : boost::false_type{}; | |
60 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U > : boost::false_type{}; | |
61 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, U& > : boost::false_type{}; | |
62 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U& > : boost::false_type{}; | |
63 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U> > : boost::false_type{}; | |
64 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U> > : boost::false_type{}; | |
65 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U>& > : boost::false_type{}; | |
66 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U>& > : boost::false_type{}; | |
67 | ||
68 | ||
69 | /////////////////////////////////////////////////////////////////////////////// | |
70 | // metafunction is_recursive_wrapper (modeled on code by David Abrahams) | |
71 | // | |
72 | // True if specified type matches recursive_wrapper<T>. | |
73 | // | |
74 | ||
75 | namespace detail { | |
76 | ||
77 | ||
78 | template <typename T> | |
79 | struct is_recursive_wrapper_impl | |
80 | : mpl::false_ | |
81 | { | |
82 | }; | |
83 | ||
84 | template <typename T> | |
85 | struct is_recursive_wrapper_impl< recursive_wrapper<T> > | |
86 | : mpl::true_ | |
87 | { | |
88 | }; | |
89 | ||
90 | ||
91 | } // namespace detail | |
92 | ||
93 | template< typename T > struct is_recursive_wrapper | |
94 | : public ::boost::integral_constant<bool,(::boost::detail::is_recursive_wrapper_impl<T>::value)> | |
95 | { | |
96 | public: | |
97 | BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T)) | |
98 | }; | |
99 | ||
100 | /////////////////////////////////////////////////////////////////////////////// | |
101 | // metafunction unwrap_recursive | |
102 | // | |
103 | // If specified type T matches recursive_wrapper<U>, then U; else T. | |
104 | // | |
105 | ||
106 | ||
107 | template <typename T> | |
108 | struct unwrap_recursive | |
109 | { | |
110 | typedef T type; | |
111 | ||
112 | BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T)) | |
113 | }; | |
114 | ||
115 | template <typename T> | |
116 | struct unwrap_recursive< recursive_wrapper<T> > | |
117 | { | |
118 | typedef T type; | |
119 | ||
120 | BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T)) | |
121 | }; | |
122 | ||
123 | ||
124 | } // namespace boost | |
125 | ||
126 | #endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP |