Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/stl_tempbuf.h
1 // Temporary buffer implementation -*- C++ -*- 2 3 // Copyright (C) 2001-2025 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 /* 26 * 27 * Copyright (c) 1994 28 * Hewlett-Packard Company 29 * 30 * Permission to use, copy, modify, distribute and sell this software 31 * and its documentation for any purpose is hereby granted without fee, 32 * provided that the above copyright notice appear in all copies and 33 * that both that copyright notice and this permission notice appear 34 * in supporting documentation. Hewlett-Packard Company makes no 35 * representations about the suitability of this software for any 36 * purpose. It is provided "as is" without express or implied warranty. 37 * 38 * 39 * Copyright (c) 1996,1997 40 * Silicon Graphics Computer Systems, Inc. 41 * 42 * Permission to use, copy, modify, distribute and sell this software 43 * and its documentation for any purpose is hereby granted without fee, 44 * provided that the above copyright notice appear in all copies and 45 * that both that copyright notice and this permission notice appear 46 * in supporting documentation. Silicon Graphics makes no 47 * representations about the suitability of this software for any 48 * purpose. It is provided "as is" without express or implied warranty. 49 */ 50 51 /** @file bits/stl_tempbuf.h 52 * This is an internal header file, included by other library headers. 53 * Do not attempt to use it directly. @headername{memory} 54 */ 55 56 #ifndef _STL_TEMPBUF_H 57 #define _STL_TEMPBUF_H 1 58 59 #include <new> 60 #include <bits/exception_defines.h> 61 #include <bits/stl_construct.h> 62 #include <bits/stl_pair.h> 63 #include <ext/numeric_traits.h> 64 65 namespace std _GLIBCXX_VISIBILITY(default) 66 { 67 _GLIBCXX_BEGIN_NAMESPACE_VERSION 68 69 #if __has_builtin(__builtin_operator_new) >= 201802L 70 # define _GLIBCXX_OPERATOR_NEW __builtin_operator_new 71 # define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete 72 #else 73 # define _GLIBCXX_OPERATOR_NEW ::operator new 74 # define _GLIBCXX_OPERATOR_DELETE ::operator delete 75 #endif 76 77 namespace __detail 78 { 79 // Equivalent to std::get_temporary_buffer but won't return a smaller size. 80 // It either returns a buffer of __len elements, or a null pointer. 81 template<typename _Tp> 82 inline _Tp* 83 __get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOTHROW 84 { 85 if (__builtin_expect(size_t(__len) > (size_t(-1) / sizeof(_Tp)), 0)) 86 return 0; 87 88 #if __cpp_aligned_new && __cplusplus >= 201103L 89 if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) 90 return (_Tp*) _GLIBCXX_OPERATOR_NEW(__len * sizeof(_Tp), 91 align_val_t(alignof(_Tp)), 92 nothrow_t()); 93 #endif 94 return (_Tp*) _GLIBCXX_OPERATOR_NEW(__len * sizeof(_Tp), nothrow_t()); 95 } 96 97 // Equivalent to std::return_temporary_buffer but with a size argument. 98 // The size is the number of elements, not the number of bytes. 99 template<typename _Tp> 100 inline void 101 __return_temporary_buffer(_Tp* __p, 102 size_t __len __attribute__((__unused__))) 103 { 104 #if __cpp_sized_deallocation 105 # define _GLIBCXX_SIZED_DEALLOC(T, p, n) (p), (n) * sizeof(T) 106 #else 107 # define _GLIBCXX_SIZED_DEALLOC(T, p, n) (p) 108 #endif 109 110 #if __cpp_aligned_new && __cplusplus >= 201103L 111 if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) 112 { 113 _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(_Tp, __p, __len), 114 align_val_t(alignof(_Tp))); 115 return; 116 } 117 #endif 118 _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(_Tp, __p, __len)); 119 } 120 #undef _GLIBCXX_SIZED_DEALLOC 121 } 122 123 /** 124 * @brief Allocates a temporary buffer. 125 * @param __len The number of objects of type Tp. 126 * @return See full description. 127 * 128 * Reinventing the wheel, but this time with prettier spokes! 129 * 130 * This function tries to obtain storage for @c __len adjacent Tp 131 * objects. The objects themselves are not constructed, of course. 132 * A pair<> is returned containing <em>the buffer's address and 133 * capacity (in the units of sizeof(_Tp)), or a pair of 0 values if 134 * no storage can be obtained.</em> Note that the capacity obtained 135 * may be less than that requested if the memory is unavailable; 136 * you should compare len with the .second return value. 137 * 138 * Provides the nothrow exception guarantee. 139 */ 140 template<typename _Tp> 141 _GLIBCXX17_DEPRECATED 142 pair<_Tp*, ptrdiff_t> 143 get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT 144 { 145 const ptrdiff_t __max = 146 __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp); 147 if (__len > __max) 148 __len = __max; 149 150 while (__len > 0) 151 { 152 if (_Tp* __tmp = __detail::__get_temporary_buffer<_Tp>(__len)) 153 return pair<_Tp*, ptrdiff_t>(__tmp, __len); 154 __len = __len == 1 ? 0 : ((__len + 1) / 2); 155 } 156 return pair<_Tp*, ptrdiff_t>(); 157 } 158 159 /** 160 * @brief The companion to get_temporary_buffer(). 161 * @param __p A buffer previously allocated by get_temporary_buffer. 162 * @return None. 163 * 164 * Frees the memory pointed to by __p. 165 */ 166 template<typename _Tp> 167 _GLIBCXX17_DEPRECATED 168 inline void 169 return_temporary_buffer(_Tp* __p) 170 { 171 #if __cpp_aligned_new && __cplusplus >= 201103L 172 if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) 173 _GLIBCXX_OPERATOR_DELETE(__p, align_val_t(alignof(_Tp))); 174 else 175 #endif 176 _GLIBCXX_OPERATOR_DELETE(__p); 177 } 178 179 #undef _GLIBCXX_OPERATOR_DELETE 180 #undef _GLIBCXX_OPERATOR_NEW 181 182 /** 183 * This class is used in two places: stl_algo.h and ext/memory, 184 * where it is wrapped as the temporary_buffer class. See 185 * temporary_buffer docs for more notes. 186 */ 187 template<typename _ForwardIterator, typename _Tp> 188 class _Temporary_buffer 189 { 190 // concept requirements 191 __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) 192 193 public: 194 typedef _Tp value_type; 195 typedef value_type* pointer; 196 typedef pointer iterator; 197 typedef ptrdiff_t size_type; 198 199 protected: 200 size_type _M_original_len; 201 struct _Impl 202 { 203 #pragma GCC diagnostic push 204 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 205 explicit 206 _Impl(ptrdiff_t __original_len) 207 { 208 pair<pointer, size_type> __p( 209 std::get_temporary_buffer<value_type>(__original_len)); 210 _M_len = __p.second; 211 _M_buffer = __p.first; 212 } 213 #pragma GCC diagnostic pop 214 215 ~_Impl() 216 { std::__detail::__return_temporary_buffer(_M_buffer, _M_len); } 217 218 size_type _M_len; 219 pointer _M_buffer; 220 } _M_impl; 221 222 public: 223 /// As per Table mumble. 224 size_type 225 size() const 226 { return _M_impl._M_len; } 227 228 /// Returns the size requested by the constructor; may be >size(). 229 size_type 230 requested_size() const 231 { return _M_original_len; } 232 233 /// As per Table mumble. 234 iterator 235 begin() 236 { return _M_impl._M_buffer; } 237 238 /// As per Table mumble. 239 iterator 240 end() 241 { return _M_impl._M_buffer + _M_impl._M_len; } 242 243 /** 244 * Constructs a temporary buffer of a size somewhere between 245 * zero and the given length. 246 */ 247 _Temporary_buffer(_ForwardIterator __seed, size_type __original_len); 248 249 ~_Temporary_buffer() 250 { std::_Destroy(_M_impl._M_buffer, _M_impl._M_buffer + _M_impl._M_len); } 251 252 private: 253 // Disable copy constructor and assignment operator. 254 _Temporary_buffer(const _Temporary_buffer&); 255 256 void 257 operator=(const _Temporary_buffer&); 258 }; 259 260 261 template<bool> 262 struct __uninitialized_construct_buf_dispatch 263 { 264 template<typename _Pointer, typename _ForwardIterator> 265 static void 266 __ucr(_Pointer __first, _Pointer __last, 267 _ForwardIterator __seed) 268 { 269 if (__builtin_expect(__first == __last, 0)) 270 return; 271 272 _Pointer __cur = __first; 273 __try 274 { 275 std::_Construct(std::__addressof(*__first), 276 _GLIBCXX_MOVE(*__seed)); 277 _Pointer __prev = __cur; 278 ++__cur; 279 for(; __cur != __last; ++__cur, ++__prev) 280 std::_Construct(std::__addressof(*__cur), 281 _GLIBCXX_MOVE(*__prev)); 282 *__seed = _GLIBCXX_MOVE(*__prev); 283 } 284 __catch(...) 285 { 286 std::_Destroy(__first, __cur); 287 __throw_exception_again; 288 } 289 } 290 }; 291 292 template<> 293 struct __uninitialized_construct_buf_dispatch<true> 294 { 295 template<typename _Pointer, typename _ForwardIterator> 296 static void 297 __ucr(_Pointer, _Pointer, _ForwardIterator) { } 298 }; 299 300 // Constructs objects in the range [first, last). 301 // Note that while these new objects will take valid values, 302 // their exact value is not defined. In particular they may 303 // be 'moved from'. 304 // 305 // While *__seed may be altered during this algorithm, it will have 306 // the same value when the algorithm finishes, unless one of the 307 // constructions throws. 308 // 309 // Requirements: 310 // _Tp is move constructible and constructible from std::move(*__seed). 311 template<typename _Tp, typename _ForwardIterator> 312 inline void 313 __uninitialized_construct_buf(_Tp* __first, _Tp* __last, 314 _ForwardIterator __seed) 315 { 316 std::__uninitialized_construct_buf_dispatch< 317 __has_trivial_constructor(_Tp)>:: 318 __ucr(__first, __last, __seed); 319 } 320 321 template<typename _ForwardIterator, typename _Tp> 322 _Temporary_buffer<_ForwardIterator, _Tp>:: 323 _Temporary_buffer(_ForwardIterator __seed, size_type __original_len) 324 : _M_original_len(__original_len), _M_impl(__original_len) 325 { 326 std::__uninitialized_construct_buf(begin(), end(), __seed); 327 } 328 329 _GLIBCXX_END_NAMESPACE_VERSION 330 } // namespace 331 332 #endif /* _STL_TEMPBUF_H */