Line data Source code
1 : // auto_ptr implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2007-2019 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 3, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // Under Section 7 of GPL version 3, you are granted additional 17 : // permissions described in the GCC Runtime Library Exception, version 18 : // 3.1, as published by the Free Software Foundation. 19 : 20 : // You should have received a copy of the GNU General Public License and 21 : // a copy of the GCC Runtime Library Exception along with this program; 22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 : // <http://www.gnu.org/licenses/>. 24 : 25 : /** @file backward/auto_ptr.h 26 : * This is an internal header file, included by other library headers. 27 : * Do not attempt to use it directly. @headername{memory} 28 : */ 29 : 30 : #ifndef _BACKWARD_AUTO_PTR_H 31 : #define _BACKWARD_AUTO_PTR_H 1 32 : 33 : #include <bits/c++config.h> 34 : #include <debug/debug.h> 35 : 36 : namespace std _GLIBCXX_VISIBILITY(default) 37 : { 38 : _GLIBCXX_BEGIN_NAMESPACE_VERSION 39 : 40 : /** 41 : * A wrapper class to provide auto_ptr with reference semantics. 42 : * For example, an auto_ptr can be assigned (or constructed from) 43 : * the result of a function which returns an auto_ptr by value. 44 : * 45 : * All the auto_ptr_ref stuff should happen behind the scenes. 46 : */ 47 : template<typename _Tp1> 48 : struct auto_ptr_ref 49 : { 50 : _Tp1* _M_ptr; 51 : 52 : explicit 53 : auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } 54 : } _GLIBCXX_DEPRECATED; 55 : 56 : #pragma GCC diagnostic push 57 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 58 : 59 : /** 60 : * @brief A simple smart pointer providing strict ownership semantics. 61 : * 62 : * The Standard says: 63 : * <pre> 64 : * An @c auto_ptr owns the object it holds a pointer to. Copying 65 : * an @c auto_ptr copies the pointer and transfers ownership to the 66 : * destination. If more than one @c auto_ptr owns the same object 67 : * at the same time the behavior of the program is undefined. 68 : * 69 : * The uses of @c auto_ptr include providing temporary 70 : * exception-safety for dynamically allocated memory, passing 71 : * ownership of dynamically allocated memory to a function, and 72 : * returning dynamically allocated memory from a function. @c 73 : * auto_ptr does not meet the CopyConstructible and Assignable 74 : * requirements for Standard Library <a 75 : * href="tables.html#65">container</a> elements and thus 76 : * instantiating a Standard Library container with an @c auto_ptr 77 : * results in undefined behavior. 78 : * </pre> 79 : * Quoted from [20.4.5]/3. 80 : * 81 : * Good examples of what can and cannot be done with auto_ptr can 82 : * be found in the libstdc++ testsuite. 83 : * 84 : * _GLIBCXX_RESOLVE_LIB_DEFECTS 85 : * 127. auto_ptr<> conversion issues 86 : * These resolutions have all been incorporated. 87 : */ 88 : template<typename _Tp> 89 : class auto_ptr 90 : { 91 : private: 92 : _Tp* _M_ptr; 93 : 94 : public: 95 : /// The pointed-to type. 96 : typedef _Tp element_type; 97 : 98 : /** 99 : * @brief An %auto_ptr is usually constructed from a raw pointer. 100 : * @param __p A pointer (defaults to NULL). 101 : * 102 : * This object now @e owns the object pointed to by @a __p. 103 : */ 104 : explicit 105 0 : auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } 106 : 107 : /** 108 : * @brief An %auto_ptr can be constructed from another %auto_ptr. 109 : * @param __a Another %auto_ptr of the same type. 110 : * 111 : * This object now @e owns the object previously owned by @a __a, 112 : * which has given up ownership. 113 : */ 114 : auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } 115 : 116 : /** 117 : * @brief An %auto_ptr can be constructed from another %auto_ptr. 118 : * @param __a Another %auto_ptr of a different but related type. 119 : * 120 : * A pointer-to-Tp1 must be convertible to a 121 : * pointer-to-Tp/element_type. 122 : * 123 : * This object now @e owns the object previously owned by @a __a, 124 : * which has given up ownership. 125 : */ 126 : template<typename _Tp1> 127 : auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } 128 : 129 : /** 130 : * @brief %auto_ptr assignment operator. 131 : * @param __a Another %auto_ptr of the same type. 132 : * 133 : * This object now @e owns the object previously owned by @a __a, 134 : * which has given up ownership. The object that this one @e 135 : * used to own and track has been deleted. 136 : */ 137 : auto_ptr& 138 : operator=(auto_ptr& __a) throw() 139 : { 140 : reset(__a.release()); 141 : return *this; 142 : } 143 : 144 : /** 145 : * @brief %auto_ptr assignment operator. 146 : * @param __a Another %auto_ptr of a different but related type. 147 : * 148 : * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. 149 : * 150 : * This object now @e owns the object previously owned by @a __a, 151 : * which has given up ownership. The object that this one @e 152 : * used to own and track has been deleted. 153 : */ 154 : template<typename _Tp1> 155 : auto_ptr& 156 : operator=(auto_ptr<_Tp1>& __a) throw() 157 : { 158 : reset(__a.release()); 159 : return *this; 160 : } 161 : 162 : /** 163 : * When the %auto_ptr goes out of scope, the object it owns is 164 : * deleted. If it no longer owns anything (i.e., @c get() is 165 : * @c NULL), then this has no effect. 166 : * 167 : * The C++ standard says there is supposed to be an empty throw 168 : * specification here, but omitting it is standard conforming. Its 169 : * presence can be detected only if _Tp::~_Tp() throws, but this is 170 : * prohibited. [17.4.3.6]/2 171 : */ 172 0 : ~auto_ptr() { delete _M_ptr; } 173 : 174 : /** 175 : * @brief Smart pointer dereferencing. 176 : * 177 : * If this %auto_ptr no longer owns anything, then this 178 : * operation will crash. (For a smart pointer, <em>no longer owns 179 : * anything</em> is the same as being a null pointer, and you know 180 : * what happens when you dereference one of those...) 181 : */ 182 : element_type& 183 0 : operator*() const throw() 184 : { 185 : __glibcxx_assert(_M_ptr != 0); 186 : return *_M_ptr; 187 : } 188 : 189 : /** 190 : * @brief Smart pointer dereferencing. 191 : * 192 : * This returns the pointer itself, which the language then will 193 : * automatically cause to be dereferenced. 194 : */ 195 : element_type* 196 : operator->() const throw() 197 : { 198 : __glibcxx_assert(_M_ptr != 0); 199 : return _M_ptr; 200 : } 201 : 202 : /** 203 : * @brief Bypassing the smart pointer. 204 : * @return The raw pointer being managed. 205 : * 206 : * You can get a copy of the pointer that this object owns, for 207 : * situations such as passing to a function which only accepts 208 : * a raw pointer. 209 : * 210 : * @note This %auto_ptr still owns the memory. 211 : */ 212 : element_type* 213 : get() const throw() { return _M_ptr; } 214 : 215 : /** 216 : * @brief Bypassing the smart pointer. 217 : * @return The raw pointer being managed. 218 : * 219 : * You can get a copy of the pointer that this object owns, for 220 : * situations such as passing to a function which only accepts 221 : * a raw pointer. 222 : * 223 : * @note This %auto_ptr no longer owns the memory. When this object 224 : * goes out of scope, nothing will happen. 225 : */ 226 : element_type* 227 : release() throw() 228 : { 229 : element_type* __tmp = _M_ptr; 230 : _M_ptr = 0; 231 : return __tmp; 232 : } 233 : 234 : /** 235 : * @brief Forcibly deletes the managed object. 236 : * @param __p A pointer (defaults to NULL). 237 : * 238 : * This object now @e owns the object pointed to by @a __p. The 239 : * previous object has been deleted. 240 : */ 241 : void 242 : reset(element_type* __p = 0) throw() 243 : { 244 : if (__p != _M_ptr) 245 : { 246 : delete _M_ptr; 247 : _M_ptr = __p; 248 : } 249 : } 250 : 251 : /** 252 : * @brief Automatic conversions 253 : * 254 : * These operations are supposed to convert an %auto_ptr into and from 255 : * an auto_ptr_ref automatically as needed. This would allow 256 : * constructs such as 257 : * @code 258 : * auto_ptr<Derived> func_returning_auto_ptr(.....); 259 : * ... 260 : * auto_ptr<Base> ptr = func_returning_auto_ptr(.....); 261 : * @endcode 262 : * 263 : * But it doesn't work, and won't be fixed. For further details see 264 : * http://cplusplus.github.io/LWG/lwg-closed.html#463 265 : */ 266 : auto_ptr(auto_ptr_ref<element_type> __ref) throw() 267 : : _M_ptr(__ref._M_ptr) { } 268 : 269 : auto_ptr& 270 : operator=(auto_ptr_ref<element_type> __ref) throw() 271 : { 272 : if (__ref._M_ptr != this->get()) 273 : { 274 : delete _M_ptr; 275 : _M_ptr = __ref._M_ptr; 276 : } 277 : return *this; 278 : } 279 : 280 : template<typename _Tp1> 281 : operator auto_ptr_ref<_Tp1>() throw() 282 : { return auto_ptr_ref<_Tp1>(this->release()); } 283 : 284 : template<typename _Tp1> 285 : operator auto_ptr<_Tp1>() throw() 286 : { return auto_ptr<_Tp1>(this->release()); } 287 : } _GLIBCXX_DEPRECATED; 288 : 289 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 290 : // 541. shared_ptr template assignment and void 291 : template<> 292 : class auto_ptr<void> 293 : { 294 : public: 295 : typedef void element_type; 296 : } _GLIBCXX_DEPRECATED; 297 : 298 : #if __cplusplus >= 201103L 299 : template<_Lock_policy _Lp> 300 : template<typename _Tp> 301 : inline 302 : __shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r) 303 : : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) 304 : { __r.release(); } 305 : 306 : template<typename _Tp, _Lock_policy _Lp> 307 : template<typename _Tp1, typename> 308 : inline 309 : __shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r) 310 : : _M_ptr(__r.get()), _M_refcount() 311 : { 312 : __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 313 : static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 314 : _Tp1* __tmp = __r.get(); 315 : _M_refcount = __shared_count<_Lp>(std::move(__r)); 316 : _M_enable_shared_from_this_with(__tmp); 317 : } 318 : 319 : template<typename _Tp> 320 : template<typename _Tp1, typename> 321 : inline 322 : shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r) 323 : : __shared_ptr<_Tp>(std::move(__r)) { } 324 : 325 : template<typename _Tp, typename _Dp> 326 : template<typename _Up, typename> 327 : inline 328 : unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept 329 : : _M_t(__u.release(), deleter_type()) { } 330 : #endif 331 : 332 : #pragma GCC diagnostic pop 333 : 334 : _GLIBCXX_END_NAMESPACE_VERSION 335 : } // namespace 336 : 337 : #endif /* _BACKWARD_AUTO_PTR_H */