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-2021 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 #include <boost/type_traits/is_nothrow_move_constructible.hpp> 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 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{}; 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 131