You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.2KB

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