xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/allocated_ptr.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // Guarded Allocation -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2014-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file bits/allocated_ptr.h
26*38fd1498Szrj  *  This is an internal header file, included by other library headers.
27*38fd1498Szrj  *  Do not attempt to use it directly. @headername{memory}
28*38fd1498Szrj  */
29*38fd1498Szrj 
30*38fd1498Szrj #ifndef _ALLOCATED_PTR_H
31*38fd1498Szrj #define _ALLOCATED_PTR_H 1
32*38fd1498Szrj 
33*38fd1498Szrj #if __cplusplus < 201103L
34*38fd1498Szrj # include <bits/c++0xwarning.h>
35*38fd1498Szrj #else
36*38fd1498Szrj # include <type_traits>
37*38fd1498Szrj # include <bits/ptr_traits.h>
38*38fd1498Szrj # include <bits/alloc_traits.h>
39*38fd1498Szrj 
_GLIBCXX_VISIBILITY(default)40*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
41*38fd1498Szrj {
42*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
43*38fd1498Szrj 
44*38fd1498Szrj   /// Non-standard RAII type for managing pointers obtained from allocators.
45*38fd1498Szrj   template<typename _Alloc>
46*38fd1498Szrj     struct __allocated_ptr
47*38fd1498Szrj     {
48*38fd1498Szrj       using pointer = typename allocator_traits<_Alloc>::pointer;
49*38fd1498Szrj       using value_type = typename allocator_traits<_Alloc>::value_type;
50*38fd1498Szrj 
51*38fd1498Szrj       /// Take ownership of __ptr
52*38fd1498Szrj       __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
53*38fd1498Szrj       : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
54*38fd1498Szrj       { }
55*38fd1498Szrj 
56*38fd1498Szrj       /// Convert __ptr to allocator's pointer type and take ownership of it
57*38fd1498Szrj       template<typename _Ptr,
58*38fd1498Szrj 	       typename _Req = _Require<is_same<_Ptr, value_type*>>>
59*38fd1498Szrj       __allocated_ptr(_Alloc& __a, _Ptr __ptr)
60*38fd1498Szrj       : _M_alloc(std::__addressof(__a)),
61*38fd1498Szrj 	_M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
62*38fd1498Szrj       { }
63*38fd1498Szrj 
64*38fd1498Szrj       /// Transfer ownership of the owned pointer
65*38fd1498Szrj       __allocated_ptr(__allocated_ptr&& __gd) noexcept
66*38fd1498Szrj       : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
67*38fd1498Szrj       { __gd._M_ptr = nullptr; }
68*38fd1498Szrj 
69*38fd1498Szrj       /// Deallocate the owned pointer
70*38fd1498Szrj       ~__allocated_ptr()
71*38fd1498Szrj       {
72*38fd1498Szrj 	if (_M_ptr != nullptr)
73*38fd1498Szrj 	  std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
74*38fd1498Szrj       }
75*38fd1498Szrj 
76*38fd1498Szrj       /// Release ownership of the owned pointer
77*38fd1498Szrj       __allocated_ptr&
78*38fd1498Szrj       operator=(std::nullptr_t) noexcept
79*38fd1498Szrj       {
80*38fd1498Szrj 	_M_ptr = nullptr;
81*38fd1498Szrj 	return *this;
82*38fd1498Szrj       }
83*38fd1498Szrj 
84*38fd1498Szrj       /// Get the address that the owned pointer refers to.
85*38fd1498Szrj       value_type* get() { return std::__to_address(_M_ptr); }
86*38fd1498Szrj 
87*38fd1498Szrj     private:
88*38fd1498Szrj       _Alloc* _M_alloc;
89*38fd1498Szrj       pointer _M_ptr;
90*38fd1498Szrj     };
91*38fd1498Szrj 
92*38fd1498Szrj   /// Allocate space for a single object using __a
93*38fd1498Szrj   template<typename _Alloc>
94*38fd1498Szrj     __allocated_ptr<_Alloc>
95*38fd1498Szrj     __allocate_guarded(_Alloc& __a)
96*38fd1498Szrj     {
97*38fd1498Szrj       return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
98*38fd1498Szrj     }
99*38fd1498Szrj 
100*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
101*38fd1498Szrj } // namespace std
102*38fd1498Szrj 
103*38fd1498Szrj #endif
104*38fd1498Szrj #endif
105