libstdc++
|
00001 // Guarded Allocation -*- C++ -*- 00002 00003 // Copyright (C) 2014-2015 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(&__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(&__a), _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr)) 00061 { } 00062 00063 /// Transfer ownership of the owned pointer 00064 __allocated_ptr(__allocated_ptr&& __gd) noexcept 00065 : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr) 00066 { __gd._M_ptr = nullptr; } 00067 00068 /// Deallocate the owned pointer 00069 ~__allocated_ptr() 00070 { 00071 if (_M_ptr != nullptr) 00072 std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1); 00073 } 00074 00075 /// Release ownership of the owned pointer 00076 __allocated_ptr& 00077 operator=(std::nullptr_t) noexcept 00078 { 00079 _M_ptr = nullptr; 00080 return *this; 00081 } 00082 00083 /// Get the address that the owned pointer refers to. 00084 value_type* get() { return _S_raw_ptr(_M_ptr); } 00085 00086 private: 00087 value_type* _S_raw_ptr(value_type* __ptr) { return __ptr; } 00088 00089 template<typename _Ptr> 00090 auto _S_raw_ptr(_Ptr __ptr) -> decltype(_S_raw_ptr(__ptr.operator->())) 00091 { return _S_raw_ptr(__ptr.operator->()); } 00092 00093 _Alloc* _M_alloc; 00094 pointer _M_ptr; 00095 }; 00096 00097 /// Allocate space for a single object using __a 00098 template<typename _Alloc> 00099 __allocated_ptr<_Alloc> 00100 __allocate_guarded(_Alloc& __a) 00101 { 00102 return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) }; 00103 } 00104 00105 _GLIBCXX_END_NAMESPACE_VERSION 00106 } // namespace std 00107 00108 #endif 00109 #endif