]>
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 | |
92f5a8d4 | 7 | // Copyright (c) 2016-2019 Antony Polukhin |
7c673cae FG |
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> | |
b32b8144 | 23 | #include <boost/type_traits/is_nothrow_move_constructible.hpp> |
7c673cae FG |
24 | |
25 | namespace boost { | |
26 | ||
27 | ////////////////////////////////////////////////////////////////////////// | |
28 | // class template recursive_wrapper | |
29 | // | |
30 | // Enables recursive types in templates by breaking cyclic dependencies. | |
31 | // | |
32 | // For example: | |
33 | // | |
34 | // class my; | |
35 | // | |
36 | // typedef variant< int, recursive_wrapper<my> > var; | |
37 | // | |
38 | // class my { | |
39 | // var var_; | |
40 | // ... | |
41 | // }; | |
42 | // | |
43 | template <typename T> class recursive_wrapper; | |
44 | ||
45 | ||
46 | /////////////////////////////////////////////////////////////////////////////// | |
47 | // metafunction is_constructible partial specializations. | |
48 | // | |
49 | // recursive_wrapper<T> is constructible only from T and recursive_wrapper<T>. | |
50 | // | |
51 | template <class T> struct is_constructible<recursive_wrapper<T>, T> : boost::true_type{}; | |
52 | template <class T> struct is_constructible<recursive_wrapper<T>, const T> : boost::true_type{}; | |
53 | template <class T> struct is_constructible<recursive_wrapper<T>, T&> : boost::true_type{}; | |
54 | template <class T> struct is_constructible<recursive_wrapper<T>, const T&> : boost::true_type{}; | |
55 | template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T> > : boost::true_type{}; | |
56 | template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T> > : boost::true_type{}; | |
57 | template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T>& > : boost::true_type{}; | |
58 | template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T>& > : boost::true_type{}; | |
59 | ||
60 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, U > : boost::false_type{}; | |
61 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U > : boost::false_type{}; | |
62 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, U& > : boost::false_type{}; | |
63 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U& > : boost::false_type{}; | |
64 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U> > : boost::false_type{}; | |
65 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U> > : boost::false_type{}; | |
66 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U>& > : boost::false_type{}; | |
67 | template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U>& > : boost::false_type{}; | |
68 | ||
b32b8144 FG |
69 | // recursive_wrapper is not nothrow move constructible, because it's constructor does dynamic memory allocation. |
70 | // This specialisation is required to workaround GCC6 issue: https://svn.boost.org/trac/boost/ticket/12680 | |
71 | template <class T> struct is_nothrow_move_constructible<recursive_wrapper<T> > : boost::false_type{}; | |
7c673cae FG |
72 | |
73 | /////////////////////////////////////////////////////////////////////////////// | |
74 | // metafunction is_recursive_wrapper (modeled on code by David Abrahams) | |
75 | // | |
76 | // True if specified type matches recursive_wrapper<T>. | |
77 | // | |
78 | ||
79 | namespace detail { | |
80 | ||
81 | ||
82 | template <typename T> | |
83 | struct is_recursive_wrapper_impl | |
84 | : mpl::false_ | |
85 | { | |
86 | }; | |
87 | ||
88 | template <typename T> | |
89 | struct is_recursive_wrapper_impl< recursive_wrapper<T> > | |
90 | : mpl::true_ | |
91 | { | |
92 | }; | |
93 | ||
94 | ||
95 | } // namespace detail | |
96 | ||
97 | template< typename T > struct is_recursive_wrapper | |
98 | : public ::boost::integral_constant<bool,(::boost::detail::is_recursive_wrapper_impl<T>::value)> | |
99 | { | |
100 | public: | |
101 | BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T)) | |
102 | }; | |
103 | ||
104 | /////////////////////////////////////////////////////////////////////////////// | |
105 | // metafunction unwrap_recursive | |
106 | // | |
107 | // If specified type T matches recursive_wrapper<U>, then U; else T. | |
108 | // | |
109 | ||
110 | ||
111 | template <typename T> | |
112 | struct unwrap_recursive | |
113 | { | |
114 | typedef T type; | |
115 | ||
116 | BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T)) | |
117 | }; | |
118 | ||
119 | template <typename T> | |
120 | struct unwrap_recursive< recursive_wrapper<T> > | |
121 | { | |
122 | typedef T type; | |
123 | ||
124 | BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T)) | |
125 | }; | |
126 | ||
127 | ||
128 | } // namespace boost | |
129 | ||
130 | #endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP |