Line data Source code
1 : // Allocator that wraps operator new -*- C++ -*- 2 : 3 : // Copyright (C) 2001-2022 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 3, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // Under Section 7 of GPL version 3, you are granted additional 17 : // permissions described in the GCC Runtime Library Exception, version 18 : // 3.1, as published by the Free Software Foundation. 19 : 20 : // You should have received a copy of the GNU General Public License and 21 : // a copy of the GCC Runtime Library Exception along with this program; 22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 : // <http://www.gnu.org/licenses/>. 24 : 25 : /** @file bits/new_allocator.h 26 : * This is an internal header file, included by other library headers. 27 : * Do not attempt to use it directly. @headername{memory} 28 : */ 29 : 30 : #ifndef _STD_NEW_ALLOCATOR_H 31 : #define _STD_NEW_ALLOCATOR_H 1 32 : 33 : #include <bits/c++config.h> 34 : #include <new> 35 : #include <bits/functexcept.h> 36 : #include <bits/move.h> 37 : #if __cplusplus >= 201103L 38 : #include <type_traits> 39 : #endif 40 : 41 : namespace std _GLIBCXX_VISIBILITY(default) 42 : { 43 : _GLIBCXX_BEGIN_NAMESPACE_VERSION 44 : 45 : /** 46 : * @brief An allocator that uses global new, as per C++03 [20.4.1]. 47 : * @ingroup allocators 48 : * 49 : * This is precisely the allocator defined in the C++ Standard. 50 : * - all allocation calls operator new 51 : * - all deallocation calls operator delete 52 : * 53 : * @tparam _Tp Type of allocated object. 54 : */ 55 : template<typename _Tp> 56 : class __new_allocator 57 : { 58 : public: 59 : typedef _Tp value_type; 60 : typedef std::size_t size_type; 61 : typedef std::ptrdiff_t difference_type; 62 : #if __cplusplus <= 201703L 63 : typedef _Tp* pointer; 64 : typedef const _Tp* const_pointer; 65 : typedef _Tp& reference; 66 : typedef const _Tp& const_reference; 67 : 68 : template<typename _Tp1> 69 : struct rebind 70 : { typedef __new_allocator<_Tp1> other; }; 71 : #endif 72 : 73 : #if __cplusplus >= 201103L 74 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 75 : // 2103. propagate_on_container_move_assignment 76 : typedef std::true_type propagate_on_container_move_assignment; 77 : #endif 78 : 79 : _GLIBCXX20_CONSTEXPR 80 11561 : __new_allocator() _GLIBCXX_USE_NOEXCEPT { } 81 : 82 : _GLIBCXX20_CONSTEXPR 83 8825 : __new_allocator(const __new_allocator&) _GLIBCXX_USE_NOEXCEPT { } 84 : 85 : template<typename _Tp1> 86 : _GLIBCXX20_CONSTEXPR 87 : __new_allocator(const __new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } 88 : 89 : #if __cplusplus <= 201703L 90 70002 : ~__new_allocator() _GLIBCXX_USE_NOEXCEPT { } 91 : 92 : pointer 93 : address(reference __x) const _GLIBCXX_NOEXCEPT 94 : { return std::__addressof(__x); } 95 : 96 : const_pointer 97 : address(const_reference __x) const _GLIBCXX_NOEXCEPT 98 : { return std::__addressof(__x); } 99 : #endif 100 : 101 : #if __has_builtin(__builtin_operator_new) >= 201802L 102 : # define _GLIBCXX_OPERATOR_NEW __builtin_operator_new 103 : # define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete 104 : #else 105 : # define _GLIBCXX_OPERATOR_NEW ::operator new 106 : # define _GLIBCXX_OPERATOR_DELETE ::operator delete 107 : #endif 108 : 109 : // NB: __n is permitted to be 0. The C++ standard says nothing 110 : // about what the return value is when __n == 0. 111 : _GLIBCXX_NODISCARD _Tp* 112 142204 : allocate(size_type __n, const void* = static_cast<const void*>(0)) 113 : { 114 : #if __cplusplus >= 201103L 115 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 116 : // 3308. std::allocator<void>().allocate(n) 117 : static_assert(sizeof(_Tp) != 0, "cannot allocate incomplete types"); 118 : #endif 119 : 120 142204 : if (__builtin_expect(__n > this->_M_max_size(), false)) 121 : { 122 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 123 : // 3190. allocator::allocate sometimes returns too little storage 124 0 : if (__n > (std::size_t(-1) / sizeof(_Tp))) 125 0 : std::__throw_bad_array_new_length(); 126 0 : std::__throw_bad_alloc(); 127 : } 128 : 129 : #if __cpp_aligned_new 130 : if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) 131 : { 132 : std::align_val_t __al = std::align_val_t(alignof(_Tp)); 133 : return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp), 134 : __al)); 135 : } 136 : #endif 137 142204 : return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); 138 : } 139 : 140 : // __p is not permitted to be a null pointer. 141 : void 142 147954 : deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__))) 143 : { 144 : #if __cpp_sized_deallocation 145 : # define _GLIBCXX_SIZED_DEALLOC(p, n) (p), (n) * sizeof(_Tp) 146 : #else 147 : # define _GLIBCXX_SIZED_DEALLOC(p, n) (p) 148 : #endif 149 : 150 : #if __cpp_aligned_new 151 : if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) 152 : { 153 : _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n), 154 : std::align_val_t(alignof(_Tp))); 155 : return; 156 : } 157 : #endif 158 147954 : _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n)); 159 : } 160 : 161 : #undef _GLIBCXX_SIZED_DEALLOC 162 : #undef _GLIBCXX_OPERATOR_DELETE 163 : #undef _GLIBCXX_OPERATOR_NEW 164 : 165 : #if __cplusplus <= 201703L 166 : size_type 167 : max_size() const _GLIBCXX_USE_NOEXCEPT 168 : { return _M_max_size(); } 169 : 170 : #if __cplusplus >= 201103L 171 : template<typename _Up, typename... _Args> 172 : void 173 142204 : construct(_Up* __p, _Args&&... __args) 174 : noexcept(std::is_nothrow_constructible<_Up, _Args...>::value) 175 142204 : { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 176 : 177 : template<typename _Up> 178 : void 179 26276 : destroy(_Up* __p) 180 : noexcept(std::is_nothrow_destructible<_Up>::value) 181 142131 : { __p->~_Up(); } 182 : #else 183 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 184 : // 402. wrong new expression in [some_] allocator::construct 185 : void 186 : construct(pointer __p, const _Tp& __val) 187 : { ::new((void *)__p) _Tp(__val); } 188 : 189 : void 190 : destroy(pointer __p) { __p->~_Tp(); } 191 : #endif 192 : #endif // ! C++20 193 : 194 : template<typename _Up> 195 : friend _GLIBCXX20_CONSTEXPR bool 196 : operator==(const __new_allocator&, const __new_allocator<_Up>&) 197 : _GLIBCXX_NOTHROW 198 : { return true; } 199 : 200 : #if __cpp_impl_three_way_comparison < 201907L 201 : template<typename _Up> 202 : friend _GLIBCXX20_CONSTEXPR bool 203 : operator!=(const __new_allocator&, const __new_allocator<_Up>&) 204 : _GLIBCXX_NOTHROW 205 : { return false; } 206 : #endif 207 : 208 : private: 209 : _GLIBCXX_CONSTEXPR size_type 210 : _M_max_size() const _GLIBCXX_USE_NOEXCEPT 211 : { 212 : #if __PTRDIFF_MAX__ < __SIZE_MAX__ 213 : return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp); 214 : #else 215 : return std::size_t(-1) / sizeof(_Tp); 216 : #endif 217 : } 218 : }; 219 : 220 : _GLIBCXX_END_NAMESPACE_VERSION 221 : } // namespace 222 : 223 : #endif