libstdc++
|
00001 // Guarded Allocation -*- C++ -*- 00002 00003 // Copyright (C) 2014-2018 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/allocated_ptr.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{memory} 00028 */ 00029 00030 #ifndef _ALLOCATED_PTR_H 00031 #define _ALLOCATED_PTR_H 1 00032 00033 #if __cplusplus < 201103L 00034 # include <bits/c++0xwarning.h> 00035 #else 00036 # include <type_traits> 00037 # include <bits/ptr_traits.h> 00038 # include <bits/alloc_traits.h> 00039 00040 namespace std _GLIBCXX_VISIBILITY(default) 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 /// Non-standard RAII type for managing pointers obtained from allocators. 00045 template<typename _Alloc> 00046 struct __allocated_ptr 00047 { 00048 using pointer = typename allocator_traits<_Alloc>::pointer; 00049 using value_type = typename allocator_traits<_Alloc>::value_type; 00050 00051 /// Take ownership of __ptr 00052 __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept 00053 : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr) 00054 { } 00055 00056 /// Convert __ptr to allocator's pointer type and take ownership of it 00057 template<typename _Ptr, 00058 typename _Req = _Require<is_same<_Ptr, value_type*>>> 00059 __allocated_ptr(_Alloc& __a, _Ptr __ptr) 00060 : _M_alloc(std::__addressof(__a)), 00061 _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr)) 00062 { } 00063 00064 /// Transfer ownership of the owned pointer 00065 __allocated_ptr(__allocated_ptr&& __gd) noexcept 00066 : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr) 00067 { __gd._M_ptr = nullptr; } 00068 00069 /// Deallocate the owned pointer 00070 ~__allocated_ptr() 00071 { 00072 if (_M_ptr != nullptr) 00073 std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1); 00074 } 00075 00076 /// Release ownership of the owned pointer 00077 __allocated_ptr& 00078 operator=(std::nullptr_t) noexcept 00079 { 00080 _M_ptr = nullptr; 00081 return *this; 00082 } 00083 00084 /// Get the address that the owned pointer refers to. 00085 value_type* get() { return std::__to_address(_M_ptr); } 00086 00087 private: 00088 _Alloc* _M_alloc; 00089 pointer _M_ptr; 00090 }; 00091 00092 /// Allocate space for a single object using __a 00093 template<typename _Alloc> 00094 __allocated_ptr<_Alloc> 00095 __allocate_guarded(_Alloc& __a) 00096 { 00097 return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) }; 00098 } 00099 00100 _GLIBCXX_END_NAMESPACE_VERSION 00101 } // namespace std 00102 00103 #endif 00104 #endif