xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/allocated_ptr.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
14d5abbe8Smrg // Guarded Allocation -*- C++ -*-
24d5abbe8Smrg 
3*b1e83836Smrg // Copyright (C) 2014-2022 Free Software Foundation, Inc.
44d5abbe8Smrg //
54d5abbe8Smrg // This file is part of the GNU ISO C++ Library.  This library is free
64d5abbe8Smrg // software; you can redistribute it and/or modify it under the
74d5abbe8Smrg // terms of the GNU General Public License as published by the
84d5abbe8Smrg // Free Software Foundation; either version 3, or (at your option)
94d5abbe8Smrg // any later version.
104d5abbe8Smrg 
114d5abbe8Smrg // This library is distributed in the hope that it will be useful,
124d5abbe8Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134d5abbe8Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144d5abbe8Smrg // GNU General Public License for more details.
154d5abbe8Smrg 
164d5abbe8Smrg // Under Section 7 of GPL version 3, you are granted additional
174d5abbe8Smrg // permissions described in the GCC Runtime Library Exception, version
184d5abbe8Smrg // 3.1, as published by the Free Software Foundation.
194d5abbe8Smrg 
204d5abbe8Smrg // You should have received a copy of the GNU General Public License and
214d5abbe8Smrg // a copy of the GCC Runtime Library Exception along with this program;
224d5abbe8Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234d5abbe8Smrg // <http://www.gnu.org/licenses/>.
244d5abbe8Smrg 
254d5abbe8Smrg /** @file bits/allocated_ptr.h
264d5abbe8Smrg  *  This is an internal header file, included by other library headers.
274d5abbe8Smrg  *  Do not attempt to use it directly. @headername{memory}
284d5abbe8Smrg  */
294d5abbe8Smrg 
304d5abbe8Smrg #ifndef _ALLOCATED_PTR_H
314d5abbe8Smrg #define _ALLOCATED_PTR_H 1
324d5abbe8Smrg 
334d5abbe8Smrg #if __cplusplus < 201103L
344d5abbe8Smrg # include <bits/c++0xwarning.h>
354d5abbe8Smrg #else
364d5abbe8Smrg # include <type_traits>
374d5abbe8Smrg # include <bits/ptr_traits.h>
384d5abbe8Smrg # include <bits/alloc_traits.h>
394d5abbe8Smrg 
_GLIBCXX_VISIBILITY(default)404d5abbe8Smrg namespace std _GLIBCXX_VISIBILITY(default)
414d5abbe8Smrg {
424d5abbe8Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
43*b1e83836Smrg /// @cond undocumented
444d5abbe8Smrg 
454d5abbe8Smrg   /// Non-standard RAII type for managing pointers obtained from allocators.
464d5abbe8Smrg   template<typename _Alloc>
474d5abbe8Smrg     struct __allocated_ptr
484d5abbe8Smrg     {
494d5abbe8Smrg       using pointer = typename allocator_traits<_Alloc>::pointer;
504d5abbe8Smrg       using value_type = typename allocator_traits<_Alloc>::value_type;
514d5abbe8Smrg 
524d5abbe8Smrg       /// Take ownership of __ptr
534d5abbe8Smrg       __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
54f9a78e0eSmrg       : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
554d5abbe8Smrg       { }
564d5abbe8Smrg 
574d5abbe8Smrg       /// Convert __ptr to allocator's pointer type and take ownership of it
584d5abbe8Smrg       template<typename _Ptr,
594d5abbe8Smrg 	       typename _Req = _Require<is_same<_Ptr, value_type*>>>
604d5abbe8Smrg       __allocated_ptr(_Alloc& __a, _Ptr __ptr)
61f9a78e0eSmrg       : _M_alloc(std::__addressof(__a)),
62f9a78e0eSmrg 	_M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
634d5abbe8Smrg       { }
644d5abbe8Smrg 
654d5abbe8Smrg       /// Transfer ownership of the owned pointer
664d5abbe8Smrg       __allocated_ptr(__allocated_ptr&& __gd) noexcept
674d5abbe8Smrg       : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
684d5abbe8Smrg       { __gd._M_ptr = nullptr; }
694d5abbe8Smrg 
704d5abbe8Smrg       /// Deallocate the owned pointer
714d5abbe8Smrg       ~__allocated_ptr()
724d5abbe8Smrg       {
734d5abbe8Smrg 	if (_M_ptr != nullptr)
744d5abbe8Smrg 	  std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
754d5abbe8Smrg       }
764d5abbe8Smrg 
774d5abbe8Smrg       /// Release ownership of the owned pointer
784d5abbe8Smrg       __allocated_ptr&
794d5abbe8Smrg       operator=(std::nullptr_t) noexcept
804d5abbe8Smrg       {
814d5abbe8Smrg 	_M_ptr = nullptr;
824d5abbe8Smrg 	return *this;
834d5abbe8Smrg       }
844d5abbe8Smrg 
854d5abbe8Smrg       /// Get the address that the owned pointer refers to.
86a3e9eb18Smrg       value_type* get() { return std::__to_address(_M_ptr); }
874d5abbe8Smrg 
884d5abbe8Smrg     private:
894d5abbe8Smrg       _Alloc* _M_alloc;
904d5abbe8Smrg       pointer _M_ptr;
914d5abbe8Smrg     };
924d5abbe8Smrg 
934d5abbe8Smrg   /// Allocate space for a single object using __a
944d5abbe8Smrg   template<typename _Alloc>
954d5abbe8Smrg     __allocated_ptr<_Alloc>
964d5abbe8Smrg     __allocate_guarded(_Alloc& __a)
974d5abbe8Smrg     {
984d5abbe8Smrg       return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
994d5abbe8Smrg     }
1004d5abbe8Smrg 
101*b1e83836Smrg /// @endcond
1024d5abbe8Smrg _GLIBCXX_END_NAMESPACE_VERSION
1034d5abbe8Smrg } // namespace std
1044d5abbe8Smrg 
1054d5abbe8Smrg #endif
1064d5abbe8Smrg #endif
107