358 size_t useNewCapacity = newCapacity;
359 size_t oldCapacity = capacity ();
360 if (atLeast) [[likely]] {
361 if (useNewCapacity <= oldCapacity) [[likely]] {
365 if (useNewCapacity < BUF_SIZE) [[likely]] {
366 useNewCapacity = BUF_SIZE;
369 useNewCapacity = Foundation::Containers::Support::ReserveTweaks::GetScaledUpCapacity (useNewCapacity,
sizeof (T),
370 Math::AtLeast<size_t> (BUF_SIZE, 1));
375 Assert (useNewCapacity >= newCapacity);
376 if (useNewCapacity != oldCapacity) [[unlikely]] {
377 bool oldInPlaceBuffer = oldCapacity <= BUF_SIZE;
378 bool newInPlaceBuffer = useNewCapacity <= BUF_SIZE;
379 if constexpr (is_trivially_copyable_v<T>) {
381 if (not oldInPlaceBuffer and not newInPlaceBuffer) {
383 fLiveData_ =
reinterpret_cast<T*
> (Reallocate_ (LiveDataAsAllocatedBytes_ (), SizeInBytes_ (useNewCapacity)));
384 fCapacityOfFreeStoreAllocation_ = useNewCapacity;
386 else if (oldInPlaceBuffer and newInPlaceBuffer) {
389 else if (oldInPlaceBuffer and not newInPlaceBuffer) {
391 byte* newPtr = Allocate_ (SizeInBytes_ (useNewCapacity));
393 Assert (this->begin () !=
reinterpret_cast<T*
> (newPtr));
394 Assert (
static_cast<size_t> (this->end () - this->begin ()) <= useNewCapacity);
395 uninitialized_copy (this->begin (), this->end (),
reinterpret_cast<T*
> (newPtr));
396 fLiveData_ =
reinterpret_cast<T*
> (newPtr);
397 if (not newInPlaceBuffer) {
398 fCapacityOfFreeStoreAllocation_ = useNewCapacity;
401 else if (not oldInPlaceBuffer and newInPlaceBuffer) {
403 byte* newPtr = std::begin (fInlinePreallocatedBuffer_);
405 Assert (this->begin () !=
reinterpret_cast<T*
> (newPtr));
406 Assert (
static_cast<size_t> (this->end () - this->begin ()) <= useNewCapacity);
407 uninitialized_copy (this->begin (), this->end (),
reinterpret_cast<T*
> (newPtr));
408 Deallocate_ (LiveDataAsAllocatedBytes_ ());
409 fLiveData_ =
reinterpret_cast<T*
> (newPtr);
414 if (oldInPlaceBuffer != newInPlaceBuffer or (not newInPlaceBuffer)) {
415 byte* newPtr = newInPlaceBuffer ? std::begin (fInlinePreallocatedBuffer_) : Allocate_ (SizeInBytes_ (useNewCapacity));
418 Assert (this->begin () !=
reinterpret_cast<T*
> (newPtr));
419 Assert (
static_cast<size_t> (this->end () - this->begin ()) <= useNewCapacity);
420 uninitialized_copy (this->begin (), this->end (),
reinterpret_cast<T*
> (newPtr));
423 DestroyElts_ (this->begin (), this->end ());
426 if (not oldInPlaceBuffer) {
427 Assert (not UsingInlinePreallocatedBuffer_ ());
428 Deallocate_ (LiveDataAsAllocatedBytes_ ());
431 fLiveData_ =
reinterpret_cast<T*
> (newPtr);
432 if (not newInPlaceBuffer) {
433 fCapacityOfFreeStoreAllocation_ = useNewCapacity;
438 Ensure ((useNewCapacity <= BUF_SIZE and capacity () == BUF_SIZE) or (useNewCapacity > BUF_SIZE and useNewCapacity == capacity ()));
441 template <
typename T,
size_t BUF_SIZE>
444 Ensure (fSize_ <= capacity ());
447 template <
typename T,
size_t BUF_SIZE>
450 Ensure (fSize_ <= capacity ());
453 template <
typename T,
size_t BUF_SIZE>
458 template <
typename T,
size_t BUF_SIZE>
461 Require (i < fSize_);
462 return *(fLiveData_ + i);
464 template <
typename T,
size_t BUF_SIZE>
467 Require (i < fSize_);
468 return *(fLiveData_ + i);
470 template <
typename T,
size_t BUF_SIZE>
475 template <
typename T,
size_t BUF_SIZE>
480 template <
typename T,
size_t BUF_SIZE>
481 template <ISpanOfT<T> SPAN_T>
482 inline void InlineBuffer<T, BUF_SIZE>::Insert (
size_t at,
const SPAN_T& copyFrom)
485 size_t n2Add = copyFrom.size ();
486 size_t newS = s + n2Add;
487 if (not this->HasEnoughCapacity_ (newS)) [[unlikely]] {
490 Assert (this->HasEnoughCapacity_ (newS));
491 this->fSize_ = Memory::Insert (span{this->begin (), size ()}, span{this->begin (), capacity ()}, at, copyFrom).size ();
492 Assert (this->fSize_ == newS);
494 template <
typename T,
size_t BUF_SIZE>
495 inline void InlineBuffer<T, BUF_SIZE>::Insert (
size_t at,
const T& item)
497 Insert (at, span{&item, 1});
499 template <
typename T,
size_t BUF_SIZE>
502 Insert (i - begin (), span{from, to});
504 template <
typename T,
size_t BUF_SIZE>
509 if (not this->HasEnoughCapacity_ (newS)) [[unlikely]] {
512 if constexpr (is_trivially_copyable_v<T>) {
516 uninitialized_copy (&e, &e + 1, this->begin () + s);
521 template <
typename T,
size_t BUF_SIZE>
522 template <ISpanOfT<T> SPAN_T>
526 size_t newS = s + copyFrom.size ();
527 if (not this->HasEnoughCapacity_ (newS)) [[unlikely]] {
530 Assert (this->HasEnoughCapacity_ (newS));
531 if constexpr (is_trivially_copyable_v<T>) {
532 CopySpanData (copyFrom, span{this->begin () + s, copyFrom.size ()});
535 uninitialized_copy (copyFrom.begin (), copyFrom.end (), this->begin () + s);
539 template <
typename T,
size_t BUF_SIZE>
540 template <ISpan SPAN_T>
544 size_t newS = s + copyFrom.size ();
545 if (not this->HasEnoughCapacity_ (newS)) [[unlikely]] {
548 Assert (this->HasEnoughCapacity_ (newS));
549 auto outPtr = this->begin () + s;
550 if constexpr (is_trivially_copyable_v<T>) {
551 CopySpanData (copyFrom, span{outPtr, copyFrom.size ()});
554 uninitialized_copy (copyFrom.begin (), copyFrom.end (), outPtr);
558 template <
typename T,
size_t BUF_SIZE>