11debfc3dSmrg // Guarded Allocation -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg // Copyright (C) 2014-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /** @file bits/allocated_ptr.h
261debfc3dSmrg * This is an internal header file, included by other library headers.
271debfc3dSmrg * Do not attempt to use it directly. @headername{memory}
281debfc3dSmrg */
291debfc3dSmrg
301debfc3dSmrg #ifndef _ALLOCATED_PTR_H
311debfc3dSmrg #define _ALLOCATED_PTR_H 1
321debfc3dSmrg
331debfc3dSmrg #if __cplusplus < 201103L
341debfc3dSmrg # include <bits/c++0xwarning.h>
351debfc3dSmrg #else
361debfc3dSmrg # include <type_traits>
371debfc3dSmrg # include <bits/ptr_traits.h>
381debfc3dSmrg # include <bits/alloc_traits.h>
391debfc3dSmrg
_GLIBCXX_VISIBILITY(default)401debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
411debfc3dSmrg {
421debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
431debfc3dSmrg
441debfc3dSmrg /// Non-standard RAII type for managing pointers obtained from allocators.
451debfc3dSmrg template<typename _Alloc>
461debfc3dSmrg struct __allocated_ptr
471debfc3dSmrg {
481debfc3dSmrg using pointer = typename allocator_traits<_Alloc>::pointer;
491debfc3dSmrg using value_type = typename allocator_traits<_Alloc>::value_type;
501debfc3dSmrg
511debfc3dSmrg /// Take ownership of __ptr
521debfc3dSmrg __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
531debfc3dSmrg : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
541debfc3dSmrg { }
551debfc3dSmrg
561debfc3dSmrg /// Convert __ptr to allocator's pointer type and take ownership of it
571debfc3dSmrg template<typename _Ptr,
581debfc3dSmrg typename _Req = _Require<is_same<_Ptr, value_type*>>>
591debfc3dSmrg __allocated_ptr(_Alloc& __a, _Ptr __ptr)
601debfc3dSmrg : _M_alloc(std::__addressof(__a)),
611debfc3dSmrg _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
621debfc3dSmrg { }
631debfc3dSmrg
641debfc3dSmrg /// Transfer ownership of the owned pointer
651debfc3dSmrg __allocated_ptr(__allocated_ptr&& __gd) noexcept
661debfc3dSmrg : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
671debfc3dSmrg { __gd._M_ptr = nullptr; }
681debfc3dSmrg
691debfc3dSmrg /// Deallocate the owned pointer
701debfc3dSmrg ~__allocated_ptr()
711debfc3dSmrg {
721debfc3dSmrg if (_M_ptr != nullptr)
731debfc3dSmrg std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
741debfc3dSmrg }
751debfc3dSmrg
761debfc3dSmrg /// Release ownership of the owned pointer
771debfc3dSmrg __allocated_ptr&
781debfc3dSmrg operator=(std::nullptr_t) noexcept
791debfc3dSmrg {
801debfc3dSmrg _M_ptr = nullptr;
811debfc3dSmrg return *this;
821debfc3dSmrg }
831debfc3dSmrg
841debfc3dSmrg /// Get the address that the owned pointer refers to.
85a2dc1f3fSmrg value_type* get() { return std::__to_address(_M_ptr); }
861debfc3dSmrg
871debfc3dSmrg private:
881debfc3dSmrg _Alloc* _M_alloc;
891debfc3dSmrg pointer _M_ptr;
901debfc3dSmrg };
911debfc3dSmrg
921debfc3dSmrg /// Allocate space for a single object using __a
931debfc3dSmrg template<typename _Alloc>
941debfc3dSmrg __allocated_ptr<_Alloc>
951debfc3dSmrg __allocate_guarded(_Alloc& __a)
961debfc3dSmrg {
971debfc3dSmrg return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
981debfc3dSmrg }
991debfc3dSmrg
1001debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
1011debfc3dSmrg } // namespace std
1021debfc3dSmrg
1031debfc3dSmrg #endif
1041debfc3dSmrg #endif
105