File indexing completed on 2026-05-03 08:13:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___FORMAT_BUFFER_H
0011 #define _LIBCPP___FORMAT_BUFFER_H
0012
0013 #include <__algorithm/copy_n.h>
0014 #include <__algorithm/fill_n.h>
0015 #include <__algorithm/max.h>
0016 #include <__algorithm/min.h>
0017 #include <__algorithm/ranges_copy.h>
0018 #include <__algorithm/ranges_copy_n.h>
0019 #include <__algorithm/transform.h>
0020 #include <__algorithm/unwrap_iter.h>
0021 #include <__concepts/same_as.h>
0022 #include <__config>
0023 #include <__format/concepts.h>
0024 #include <__format/enable_insertable.h>
0025 #include <__format/format_to_n_result.h>
0026 #include <__iterator/back_insert_iterator.h>
0027 #include <__iterator/concepts.h>
0028 #include <__iterator/incrementable_traits.h>
0029 #include <__iterator/iterator_traits.h>
0030 #include <__iterator/wrap_iter.h>
0031 #include <__memory/addressof.h>
0032 #include <__memory/allocate_at_least.h>
0033 #include <__memory/allocator.h>
0034 #include <__memory/allocator_traits.h>
0035 #include <__memory/construct_at.h>
0036 #include <__memory/ranges_construct_at.h>
0037 #include <__memory/uninitialized_algorithms.h>
0038 #include <__type_traits/add_pointer.h>
0039 #include <__type_traits/conditional.h>
0040 #include <__utility/exception_guard.h>
0041 #include <__utility/move.h>
0042 #include <stdexcept>
0043 #include <string_view>
0044
0045 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0046 # pragma GCC system_header
0047 #endif
0048
0049 _LIBCPP_PUSH_MACROS
0050 #include <__undef_macros>
0051
0052 _LIBCPP_BEGIN_NAMESPACE_STD
0053
0054 #if _LIBCPP_STD_VER >= 20
0055
0056 namespace __format {
0057
0058
0059 class _LIBCPP_HIDE_FROM_ABI __max_output_size {
0060 public:
0061 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __max_output_size(size_t __max_size) : __max_size_{__max_size} {}
0062
0063
0064
0065
0066 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __write_request(size_t __code_units) {
0067 size_t __result =
0068 __code_units_written_ < __max_size_ ? std::min(__code_units, __max_size_ - __code_units_written_) : 0;
0069 __code_units_written_ += __code_units;
0070 return __result;
0071 }
0072
0073 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __code_units_written() const noexcept { return __code_units_written_; }
0074
0075 private:
0076 size_t __max_size_;
0077
0078
0079 size_t __code_units_written_{0};
0080 };
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template <__fmt_char_type _CharT>
0183 class _LIBCPP_TEMPLATE_VIS __output_buffer {
0184 public:
0185 using value_type _LIBCPP_NODEBUG = _CharT;
0186 using __prepare_write_type _LIBCPP_NODEBUG = void (*)(__output_buffer<_CharT>&, size_t);
0187
0188 [[nodiscard]]
0189 _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, __prepare_write_type __function)
0190 : __output_buffer{__ptr, __capacity, __function, nullptr} {}
0191
0192 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(
0193 _CharT* __ptr, size_t __capacity, __prepare_write_type __function, __max_output_size* __max_output_size)
0194 : __ptr_(__ptr), __capacity_(__capacity), __prepare_write_(__function), __max_output_size_(__max_output_size) {}
0195
0196 _LIBCPP_HIDE_FROM_ABI void __buffer_flushed() { __size_ = 0; }
0197
0198 _LIBCPP_HIDE_FROM_ABI void __buffer_moved(_CharT* __ptr, size_t __capacity) {
0199 __ptr_ = __ptr;
0200 __capacity_ = __capacity;
0201 }
0202
0203 _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return std::back_insert_iterator{*this}; }
0204
0205
0206 _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
0207 if (__max_output_size_ && __max_output_size_->__write_request(1) == 0)
0208 return;
0209
0210 _LIBCPP_ASSERT_INTERNAL(
0211 __ptr_ && __size_ < __capacity_ && __available() >= 1, "attempted to write outside the buffer");
0212
0213 __ptr_[__size_++] = __c;
0214
0215
0216
0217 if (__size_ == __capacity_)
0218 __prepare_write(0);
0219 }
0220
0221
0222
0223
0224
0225 template <__fmt_char_type _InCharT>
0226 _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 size_t __n = __str.size();
0239 if (__max_output_size_) {
0240 __n = __max_output_size_->__write_request(__n);
0241 if (__n == 0)
0242 return;
0243 }
0244
0245 const _InCharT* __first = __str.data();
0246 do {
0247 __prepare_write(__n);
0248 size_t __chunk = std::min(__n, __available());
0249 std::copy_n(__first, __chunk, std::addressof(__ptr_[__size_]));
0250 __size_ += __chunk;
0251 __first += __chunk;
0252 __n -= __chunk;
0253 } while (__n);
0254 }
0255
0256
0257
0258
0259 template <contiguous_iterator _Iterator,
0260 class _UnaryOperation,
0261 __fmt_char_type _InCharT = typename iterator_traits<_Iterator>::value_type>
0262 _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) {
0263 _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range");
0264
0265 size_t __n = static_cast<size_t>(__last - __first);
0266 if (__max_output_size_) {
0267 __n = __max_output_size_->__write_request(__n);
0268 if (__n == 0)
0269 return;
0270 }
0271
0272 do {
0273 __prepare_write(__n);
0274 size_t __chunk = std::min(__n, __available());
0275 std::transform(__first, __first + __chunk, std::addressof(__ptr_[__size_]), __operation);
0276 __size_ += __chunk;
0277 __first += __chunk;
0278 __n -= __chunk;
0279 } while (__n);
0280 }
0281
0282
0283 _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
0284 if (__max_output_size_) {
0285 __n = __max_output_size_->__write_request(__n);
0286 if (__n == 0)
0287 return;
0288 }
0289
0290 do {
0291 __prepare_write(__n);
0292 size_t __chunk = std::min(__n, __available());
0293 std::fill_n(std::addressof(__ptr_[__size_]), __chunk, __value);
0294 __size_ += __chunk;
0295 __n -= __chunk;
0296 } while (__n);
0297 }
0298
0299 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __capacity() const { return __capacity_; }
0300 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __size() const { return __size_; }
0301
0302 private:
0303 _CharT* __ptr_;
0304 size_t __capacity_;
0305 size_t __size_{0};
0306 void (*__prepare_write_)(__output_buffer<_CharT>&, size_t);
0307 __max_output_size* __max_output_size_;
0308
0309 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __available() const { return __capacity_ - __size_; }
0310
0311 _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __code_units) {
0312
0313 __code_units += 1;
0314 if (__available() < __code_units)
0315 __prepare_write_(*this, __code_units + 1);
0316 }
0317 };
0318
0319 template <class _OutIt, class _CharT>
0320 concept __enable_direct_output =
0321 __fmt_char_type<_CharT> &&
0322 (same_as<_OutIt, _CharT*>
0323
0324
0325 || same_as<_OutIt, __wrap_iter<_CharT*>>);
0326
0327
0328
0329
0330
0331
0332
0333
0334 template <class _Container>
0335 concept __insertable =
0336 __enable_insertable<_Container> && __fmt_char_type<typename _Container::value_type> &&
0337 requires(_Container& __t,
0338 add_pointer_t<typename _Container::value_type> __first,
0339 add_pointer_t<typename _Container::value_type> __last) { __t.insert(__t.end(), __first, __last); };
0340
0341
0342 template <class _It>
0343 struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container {
0344 using type _LIBCPP_NODEBUG = void;
0345 };
0346
0347 template <__insertable _Container>
0348 struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container<back_insert_iterator<_Container>> {
0349 using type _LIBCPP_NODEBUG = _Container;
0350 };
0351
0352
0353 template <__fmt_char_type _CharT>
0354 class _LIBCPP_TEMPLATE_VIS __allocating_buffer : public __output_buffer<_CharT> {
0355 public:
0356 __allocating_buffer(const __allocating_buffer&) = delete;
0357 __allocating_buffer& operator=(const __allocating_buffer&) = delete;
0358
0359 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __allocating_buffer() : __allocating_buffer{nullptr} {}
0360
0361 [[nodiscard]]
0362 _LIBCPP_HIDE_FROM_ABI explicit __allocating_buffer(__max_output_size* __max_output_size)
0363 : __output_buffer<_CharT>{__small_buffer_, __buffer_size_, __prepare_write, __max_output_size} {}
0364
0365 _LIBCPP_HIDE_FROM_ABI ~__allocating_buffer() {
0366 if (__ptr_ != __small_buffer_)
0367 _Alloc{}.deallocate(__ptr_, this->__capacity());
0368 }
0369
0370 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, this->__size()}; }
0371
0372 private:
0373 using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>;
0374
0375
0376
0377 static constexpr size_t __buffer_size_ = 256;
0378 _CharT __small_buffer_[__buffer_size_];
0379
0380 _CharT* __ptr_{__small_buffer_};
0381
0382 _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
0383 if (__capacity < __buffer_size_)
0384 return;
0385
0386 _LIBCPP_ASSERT_INTERNAL(__capacity > this->__capacity(), "the buffer must grow");
0387
0388
0389
0390 _Alloc __alloc;
0391 auto __result = std::__allocate_at_least(__alloc, __capacity);
0392 std::copy_n(__ptr_, this->__size(), __result.ptr);
0393 if (__ptr_ != __small_buffer_)
0394 __alloc.deallocate(__ptr_, this->__capacity());
0395
0396 __ptr_ = __result.ptr;
0397 this->__buffer_moved(__ptr_, __result.count);
0398 }
0399
0400 _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __size_hint) {
0401 __grow_buffer(std::max<size_t>(this->__capacity() + __size_hint, this->__capacity() * 1.6));
0402 }
0403
0404 _LIBCPP_HIDE_FROM_ABI static void __prepare_write(__output_buffer<_CharT>& __buffer, size_t __size_hint) {
0405 static_cast<__allocating_buffer<_CharT>&>(__buffer).__prepare_write(__size_hint);
0406 }
0407 };
0408
0409
0410 template <class _OutIt, __fmt_char_type _CharT>
0411 class _LIBCPP_TEMPLATE_VIS __direct_iterator_buffer : public __output_buffer<_CharT> {
0412 public:
0413 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it)
0414 : __direct_iterator_buffer{__out_it, nullptr} {}
0415
0416 [[nodiscard]]
0417 _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
0418 : __output_buffer<_CharT>{std::__unwrap_iter(__out_it), __buffer_size, __prepare_write, __max_output_size},
0419 __out_it_(__out_it) {}
0420
0421 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return __out_it_ + this->__size(); }
0422
0423 private:
0424
0425
0426
0427
0428 static constexpr size_t __buffer_size = -1;
0429
0430 _OutIt __out_it_;
0431
0432 _LIBCPP_HIDE_FROM_ABI static void
0433 __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
0434 std::__throw_length_error("__direct_iterator_buffer");
0435 }
0436 };
0437
0438
0439 template <class _OutIt, __fmt_char_type _CharT>
0440 class _LIBCPP_TEMPLATE_VIS __container_inserter_buffer : public __output_buffer<_CharT> {
0441 public:
0442 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it)
0443 : __container_inserter_buffer{__out_it, nullptr} {}
0444
0445 [[nodiscard]]
0446 _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
0447 : __output_buffer<_CharT>{__small_buffer_, __buffer_size, __prepare_write, __max_output_size},
0448 __container_{__out_it.__get_container()} {}
0449
0450 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
0451 __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size());
0452 return std::back_inserter(*__container_);
0453 }
0454
0455 private:
0456 typename __back_insert_iterator_container<_OutIt>::type* __container_;
0457
0458
0459
0460
0461
0462 static constexpr size_t __buffer_size = 256;
0463 _CharT __small_buffer_[__buffer_size];
0464
0465 _LIBCPP_HIDE_FROM_ABI void __prepare_write() {
0466 __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size());
0467 this->__buffer_flushed();
0468 }
0469
0470 _LIBCPP_HIDE_FROM_ABI static void
0471 __prepare_write(__output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
0472 static_cast<__container_inserter_buffer<_OutIt, _CharT>&>(__buffer).__prepare_write();
0473 }
0474 };
0475
0476
0477
0478
0479
0480 template <class _OutIt, __fmt_char_type _CharT>
0481 class _LIBCPP_TEMPLATE_VIS __iterator_buffer : public __allocating_buffer<_CharT> {
0482 public:
0483 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it)
0484 : __allocating_buffer<_CharT>{}, __out_it_{std::move(__out_it)} {}
0485
0486 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
0487 : __allocating_buffer<_CharT>{__max_output_size}, __out_it_{std::move(__out_it)} {}
0488
0489 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
0490 return std::ranges::copy(this->__view(), std::move(__out_it_)).out;
0491 }
0492
0493 private:
0494 _OutIt __out_it_;
0495 };
0496
0497
0498 template <class _OutIt, __fmt_char_type _CharT>
0499 class _LIBCPP_TEMPLATE_VIS __buffer_selector {
0500 using _Container _LIBCPP_NODEBUG = __back_insert_iterator_container<_OutIt>::type;
0501
0502 public:
0503 using type _LIBCPP_NODEBUG =
0504 conditional_t<!same_as<_Container, void>,
0505 __container_inserter_buffer<_OutIt, _CharT>,
0506 conditional_t<__enable_direct_output<_OutIt, _CharT>,
0507 __direct_iterator_buffer<_OutIt, _CharT>,
0508 __iterator_buffer<_OutIt, _CharT>>>;
0509 };
0510
0511
0512 template <class _OutIt, __fmt_char_type _CharT>
0513 class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer : private __buffer_selector<_OutIt, _CharT>::type {
0514 public:
0515 using _Base _LIBCPP_NODEBUG = __buffer_selector<_OutIt, _CharT>::type;
0516
0517 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_to_n_buffer(_OutIt __out_it, iter_difference_t<_OutIt> __n)
0518 : _Base{std::move(__out_it), std::addressof(__max_output_size_)},
0519 __max_output_size_{__n < 0 ? size_t{0} : static_cast<size_t>(__n)} {}
0520
0521 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); }
0522
0523 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && {
0524 return {static_cast<_Base&&>(*this).__out_it(),
0525 static_cast<iter_difference_t<_OutIt>>(__max_output_size_.__code_units_written())};
0526 }
0527
0528 private:
0529 __max_output_size __max_output_size_;
0530 };
0531
0532
0533
0534
0535
0536 template <__fmt_char_type _CharT>
0537 class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer : private __output_buffer<_CharT> {
0538 public:
0539 using _Base _LIBCPP_NODEBUG = __output_buffer<_CharT>;
0540
0541 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __formatted_size_buffer()
0542 : _Base{nullptr, 0, __prepare_write, std::addressof(__max_output_size_)} {}
0543
0544 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); }
0545
0546
0547
0548 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __result() && { return __max_output_size_.__code_units_written(); }
0549
0550 private:
0551 __max_output_size __max_output_size_{0};
0552
0553 _LIBCPP_HIDE_FROM_ABI static void
0554 __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
0555
0556 _LIBCPP_ASSERT_INTERNAL(
0557 false, "Since __max_output_size_.__max_size_ == 0 there should never be call to this function.");
0558 }
0559 };
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 template <__fmt_char_type _CharT>
0580 class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
0581 using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>;
0582
0583 public:
0584 using value_type _LIBCPP_NODEBUG = _CharT;
0585
0586 struct __iterator {
0587 using difference_type _LIBCPP_NODEBUG = ptrdiff_t;
0588 using value_type _LIBCPP_NODEBUG = _CharT;
0589
0590 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
0591 : __buffer_(std::addressof(__buffer)) {}
0592 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) {
0593 __buffer_->push_back(__c);
0594 return *this;
0595 }
0596 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) {
0597 __buffer_->push_back(__c);
0598 return *this;
0599 }
0600
0601 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; }
0602 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; }
0603 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; }
0604 __retarget_buffer* __buffer_;
0605 };
0606
0607 __retarget_buffer(const __retarget_buffer&) = delete;
0608 __retarget_buffer& operator=(const __retarget_buffer&) = delete;
0609
0610 _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) {
0611
0612
0613
0614
0615
0616
0617
0618 auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT)));
0619 __ptr_ = __result.ptr;
0620 __capacity_ = __result.count;
0621 }
0622
0623 _LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() {
0624 ranges::destroy_n(__ptr_, __size_);
0625 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
0626 }
0627
0628 _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; }
0629
0630 _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
0631 std::construct_at(__ptr_ + __size_, __c);
0632 ++__size_;
0633
0634 if (__size_ == __capacity_)
0635 __grow_buffer();
0636 }
0637
0638 template <__fmt_char_type _InCharT>
0639 _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
0640 size_t __n = __str.size();
0641 if (__size_ + __n >= __capacity_)
0642
0643 __grow_buffer(__size_ + __n + 1);
0644
0645 std::uninitialized_copy_n(__str.data(), __n, __ptr_ + __size_);
0646 __size_ += __n;
0647 }
0648
0649 template <contiguous_iterator _Iterator,
0650 class _UnaryOperation,
0651 __fmt_char_type _InCharT = typename iterator_traits<_Iterator>::value_type>
0652 _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) {
0653 _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range");
0654
0655 size_t __n = static_cast<size_t>(__last - __first);
0656 if (__size_ + __n >= __capacity_)
0657
0658 __grow_buffer(__size_ + __n + 1);
0659
0660 std::uninitialized_default_construct_n(__ptr_ + __size_, __n);
0661 std::transform(__first, __last, __ptr_ + __size_, std::move(__operation));
0662 __size_ += __n;
0663 }
0664
0665 _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
0666 if (__size_ + __n >= __capacity_)
0667
0668 __grow_buffer(__size_ + __n + 1);
0669
0670 std::uninitialized_fill_n(__ptr_ + __size_, __n, __value);
0671 __size_ += __n;
0672 }
0673
0674 _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, __size_}; }
0675
0676 private:
0677 _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); }
0678
0679 _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
0680 _LIBCPP_ASSERT_INTERNAL(__capacity > __capacity_, "the buffer must grow");
0681 auto __result = std::__allocate_at_least(__alloc_, __capacity);
0682 auto __guard = std::__make_exception_guard([&] {
0683 allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count);
0684 });
0685
0686
0687 std::uninitialized_move_n(__ptr_, __size_, __result.ptr);
0688 __guard.__complete();
0689 ranges::destroy_n(__ptr_, __size_);
0690 allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
0691
0692 __ptr_ = __result.ptr;
0693 __capacity_ = __result.count;
0694 }
0695 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
0696 _CharT* __ptr_;
0697 size_t __capacity_;
0698 size_t __size_{0};
0699 };
0700
0701 }
0702
0703 #endif
0704
0705 _LIBCPP_END_NAMESPACE_STD
0706
0707 _LIBCPP_POP_MACROS
0708
0709 #endif