Chris@102
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
|
Chris@102
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@102
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //
|
Chris@102
|
7 // See http://www.boost.org/libs/move for documentation.
|
Chris@102
|
8 //
|
Chris@102
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
10
|
Chris@102
|
11 #ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
Chris@102
|
12 #define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
15 # include <boost/config.hpp>
|
Chris@102
|
16 #endif
|
Chris@102
|
17 #
|
Chris@102
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
19 # pragma once
|
Chris@102
|
20 #endif
|
Chris@102
|
21
|
Chris@102
|
22 #include <boost/move/detail/config_begin.hpp>
|
Chris@102
|
23 #include <boost/move/detail/workaround.hpp>
|
Chris@102
|
24 #include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
Chris@102
|
25 #include <boost/move/utility_core.hpp>
|
Chris@102
|
26 #include <boost/static_assert.hpp>
|
Chris@102
|
27
|
Chris@102
|
28 #include <cstddef> //For std::size_t,std::nullptr_t
|
Chris@102
|
29
|
Chris@102
|
30 //!\file
|
Chris@102
|
31 //! Describes the default deleter (destruction policy) of <tt>unique_ptr</tt>: <tt>default_delete</tt>.
|
Chris@102
|
32
|
Chris@102
|
33 namespace boost{
|
Chris@102
|
34 namespace move_upd {
|
Chris@102
|
35
|
Chris@102
|
36 namespace bmupmu = ::boost::move_upmu;
|
Chris@102
|
37
|
Chris@102
|
38 ////////////////////////////////////////
|
Chris@102
|
39 //// enable_def_del
|
Chris@102
|
40 ////////////////////////////////////////
|
Chris@102
|
41
|
Chris@102
|
42 //compatible with a pointer type T*:
|
Chris@102
|
43 //When either Y* is convertible to T*
|
Chris@102
|
44 //Y is U[N] and T is U cv []
|
Chris@102
|
45 template<class U, class T>
|
Chris@102
|
46 struct def_del_compatible_cond
|
Chris@102
|
47 : bmupmu::is_convertible<U*, T*>
|
Chris@102
|
48 {};
|
Chris@102
|
49
|
Chris@102
|
50 template<class U, class T, std::size_t N>
|
Chris@102
|
51 struct def_del_compatible_cond<U[N], T[]>
|
Chris@102
|
52 : def_del_compatible_cond<U[], T[]>
|
Chris@102
|
53 {};
|
Chris@102
|
54
|
Chris@102
|
55 template<class U, class T, class Type = bmupmu::nat>
|
Chris@102
|
56 struct enable_def_del
|
Chris@102
|
57 : bmupmu::enable_if_c<def_del_compatible_cond<U, T>::value, Type>
|
Chris@102
|
58 {};
|
Chris@102
|
59
|
Chris@102
|
60 ////////////////////////////////////////
|
Chris@102
|
61 //// enable_defdel_call
|
Chris@102
|
62 ////////////////////////////////////////
|
Chris@102
|
63
|
Chris@102
|
64 //When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N];
|
Chris@102
|
65 //When 2nd is T[], 1st(*)[] shall be convertible to T(*)[];
|
Chris@102
|
66 //Otherwise, 1st* shall be convertible to 2nd*.
|
Chris@102
|
67
|
Chris@102
|
68 template<class U, class T, class Type = bmupmu::nat>
|
Chris@102
|
69 struct enable_defdel_call
|
Chris@102
|
70 : public enable_def_del<U, T, Type>
|
Chris@102
|
71 {};
|
Chris@102
|
72
|
Chris@102
|
73 template<class U, class T, class Type>
|
Chris@102
|
74 struct enable_defdel_call<U, T[], Type>
|
Chris@102
|
75 : public enable_def_del<U[], T[], Type>
|
Chris@102
|
76 {};
|
Chris@102
|
77
|
Chris@102
|
78 template<class U, class T, class Type, std::size_t N>
|
Chris@102
|
79 struct enable_defdel_call<U, T[N], Type>
|
Chris@102
|
80 : public enable_def_del<U[N], T[N], Type>
|
Chris@102
|
81 {};
|
Chris@102
|
82
|
Chris@102
|
83 ////////////////////////////////////////
|
Chris@102
|
84 //// Some bool literal zero conversion utilities
|
Chris@102
|
85 ////////////////////////////////////////
|
Chris@102
|
86
|
Chris@102
|
87 struct bool_conversion {int for_bool; int for_arg(); };
|
Chris@102
|
88 typedef int bool_conversion::* explicit_bool_arg;
|
Chris@102
|
89
|
Chris@102
|
90 #if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE)
|
Chris@102
|
91 typedef decltype(nullptr) nullptr_type;
|
Chris@102
|
92 #elif !defined(BOOST_NO_CXX11_NULLPTR)
|
Chris@102
|
93 typedef std::nullptr_t nullptr_type;
|
Chris@102
|
94 #else
|
Chris@102
|
95 typedef int (bool_conversion::*nullptr_type)();
|
Chris@102
|
96 #endif
|
Chris@102
|
97
|
Chris@102
|
98 } //namespace move_upd {
|
Chris@102
|
99
|
Chris@102
|
100 namespace movelib {
|
Chris@102
|
101
|
Chris@102
|
102 namespace bmupd = boost::move_upd;
|
Chris@102
|
103 namespace bmupmu = ::boost::move_upmu;
|
Chris@102
|
104
|
Chris@102
|
105 //!The class template <tt>default_delete</tt> serves as the default deleter
|
Chris@102
|
106 //!(destruction policy) for the class template <tt>unique_ptr</tt>.
|
Chris@102
|
107 //!
|
Chris@102
|
108 //! \tparam T The type to be deleted. It may be an incomplete type
|
Chris@102
|
109 template <class T>
|
Chris@102
|
110 struct default_delete
|
Chris@102
|
111 {
|
Chris@102
|
112 //! Default constructor.
|
Chris@102
|
113 //!
|
Chris@102
|
114 BOOST_CONSTEXPR default_delete()
|
Chris@102
|
115 //Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
|
Chris@102
|
116 #if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@102
|
117 BOOST_NOEXCEPT
|
Chris@102
|
118 #endif
|
Chris@102
|
119 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@102
|
120 = default;
|
Chris@102
|
121 #else
|
Chris@102
|
122 {};
|
Chris@102
|
123 #endif
|
Chris@102
|
124
|
Chris@102
|
125 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@102
|
126 default_delete(const default_delete&) BOOST_NOEXCEPT = default;
|
Chris@102
|
127 default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
|
Chris@102
|
128 #else
|
Chris@102
|
129 typedef typename bmupmu::remove_extent<T>::type element_type;
|
Chris@102
|
130 #endif
|
Chris@102
|
131
|
Chris@102
|
132 //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
|
Chris@102
|
133 //!
|
Chris@102
|
134 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
135 //! - If T is not an array type and U* is implicitly convertible to T*.
|
Chris@102
|
136 //! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
|
Chris@102
|
137 template <class U>
|
Chris@102
|
138 default_delete(const default_delete<U>&
|
Chris@102
|
139 BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
|
Chris@102
|
140 ) BOOST_NOEXCEPT
|
Chris@102
|
141 {
|
Chris@102
|
142 //If T is not an array type, U derives from T
|
Chris@102
|
143 //and T has no virtual destructor, then you have a problem
|
Chris@102
|
144 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
Chris@102
|
145 }
|
Chris@102
|
146
|
Chris@102
|
147 //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
|
Chris@102
|
148 //!
|
Chris@102
|
149 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
150 //! - If T is not an array type and U* is implicitly convertible to T*.
|
Chris@102
|
151 //! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
|
Chris@102
|
152 template <class U>
|
Chris@102
|
153 BOOST_MOVE_DOC1ST(default_delete&,
|
Chris@102
|
154 typename bmupd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
|
Chris@102
|
155 operator=(const default_delete<U>&) BOOST_NOEXCEPT
|
Chris@102
|
156 {
|
Chris@102
|
157 //If T is not an array type, U derives from T
|
Chris@102
|
158 //and T has no virtual destructor, then you have a problem
|
Chris@102
|
159 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
Chris@102
|
160 return *this;
|
Chris@102
|
161 }
|
Chris@102
|
162
|
Chris@102
|
163 //! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
|
Chris@102
|
164 //! otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
|
Chris@102
|
165 //!
|
Chris@102
|
166 //! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
|
Chris@102
|
167 //! This operator shall not participate in overload resolution unless:
|
Chris@102
|
168 //! - T is not an array type and U* is convertible to T*, OR
|
Chris@102
|
169 //! - T is an array type, and remove_cv<U>::type is the same type as
|
Chris@102
|
170 //! remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
|
Chris@102
|
171 template <class U>
|
Chris@102
|
172 BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
|
Chris@102
|
173 operator()(U* ptr) const BOOST_NOEXCEPT
|
Chris@102
|
174 {
|
Chris@102
|
175 //U must be a complete type
|
Chris@102
|
176 BOOST_STATIC_ASSERT(sizeof(U) > 0);
|
Chris@102
|
177 //If T is not an array type, U derives from T
|
Chris@102
|
178 //and T has no virtual destructor, then you have a problem
|
Chris@102
|
179 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
Chris@102
|
180 element_type * const p = static_cast<element_type*>(ptr);
|
Chris@102
|
181 bmupmu::is_array<T>::value ? delete [] p : delete p;
|
Chris@102
|
182 }
|
Chris@102
|
183
|
Chris@102
|
184 //! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
|
Chris@102
|
185 //!
|
Chris@102
|
186 void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT
|
Chris@102
|
187 { BOOST_STATIC_ASSERT(sizeof(element_type) > 0); }
|
Chris@102
|
188 };
|
Chris@102
|
189
|
Chris@102
|
190 } //namespace movelib {
|
Chris@102
|
191 } //namespace boost{
|
Chris@102
|
192
|
Chris@102
|
193 #include <boost/move/detail/config_end.hpp>
|
Chris@102
|
194
|
Chris@102
|
195 #endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|