FastLED 3.9.15
Loading...
Searching...
No Matches

◆ swap_impl()

void fl::vector_basic::swap_impl ( vector_basic & other)

Swap contents with another vector_basic.

Definition at line 360 of file basic_vector.cpp.hpp.

360 {
361 // Swap all members. This works correctly even with inline buffers
362 // because we swap the offset too, and the inline data stays in place.
363 // HOWEVER: if either vector uses inline storage, we need to handle
364 // it carefully since inline buffers can't be swapped by pointer.
365
366 bool this_inline = isInline();
367 bool other_inline = other.isInline();
368
369 if (!this_inline && !other_inline) {
370 // Both on heap: just swap pointers and metadata
371 void* tmp_array = mArray;
372 mArray = other.mArray;
373 other.mArray = tmp_array;
374
375 fl::size tmp_cap = mCapacity;
376 mCapacity = other.mCapacity;
377 other.mCapacity = tmp_cap;
378 } else if (this_inline && other_inline) {
379 // Both inline: swap element data in-place
380 fl::size max_size = mSize > other.mSize ? mSize : other.mSize;
381 for (fl::size i = 0; i < max_size; ++i) {
382 if (i < mSize && i < other.mSize) {
383 if (mOps) {
384 mOps->swap_elements(element_ptr(i), other.element_ptr(i));
385 } else {
386 trivial_swap(element_ptr(i), other.element_ptr(i));
387 }
388 } else if (i < mSize) {
389 // Move this[i] to other[i], destroy this[i]
390 if (mOps) {
391 mOps->move_construct(other.element_ptr(i), element_ptr(i));
392 mOps->destroy(element_ptr(i));
393 } else {
394 fl::memcpy(other.element_ptr(i), element_ptr(i), mElementSize);
395 }
396 } else {
397 // Move other[i] to this[i], destroy other[i]
398 if (mOps) {
399 mOps->move_construct(element_ptr(i), other.element_ptr(i));
400 mOps->destroy(other.element_ptr(i));
401 } else {
402 fl::memcpy(element_ptr(i), other.element_ptr(i), mElementSize);
403 }
404 }
405 }
406 } else if (this_inline) {
407 // this is inline, other is on heap
408 // Move this's inline data to a temp, take other's heap pointer,
409 // move temp data to other's inline buffer
410 void* other_array = other.mArray;
411 fl::size other_cap = other.mCapacity;
412
413 // Move this's elements to other's inline buffer
414 if (other.hasInlineBuffer() && mSize <= other.mInlineCapacity) {
415 other.mArray = other.inlineBufferPtr();
416 other.mCapacity = other.mInlineCapacity;
417 if (mOps) {
418 mOps->uninitialized_move_n(other.mArray, mArray, mSize);
419 mOps->destroy_n(mArray, mSize);
420 } else {
421 if (mSize > 0) trivial_copy(other.mArray, mArray, mSize);
422 }
423 } else {
424 // Other has no inline buffer or data doesn't fit - allocate heap
425 other.mArray = other.mResource->allocate(mSize * mElementSize);
426 other.mCapacity = mSize;
427 if (mOps) {
428 mOps->uninitialized_move_n(other.mArray, mArray, mSize);
429 mOps->destroy_n(mArray, mSize);
430 } else {
431 if (mSize > 0) trivial_copy(other.mArray, mArray, mSize);
432 }
433 }
434
435 // This takes other's heap pointer
436 mArray = other_array;
437 mCapacity = other_cap;
438 } else {
439 // other is inline, this is on heap - mirror of above
440 other.swap_impl(*this);
441 return;
442 }
443
444 // Swap sizes
445 fl::size tmp_size = mSize;
446 mSize = other.mSize;
447 other.mSize = tmp_size;
448
449 // Swap resources
450 memory_resource* tmp_res = mResource;
451 mResource = other.mResource;
452 other.mResource = tmp_res;
453}
const vector_element_ops * mOps
bool isInline() const FL_NOEXCEPT
Is data currently in the inline buffer?
fl::size mElementSize
memory_resource * mResource
void trivial_swap(void *a, void *b) const FL_NOEXCEPT
void trivial_copy(void *dst, const void *src, fl::size count) const FL_NOEXCEPT
void * element_ptr(fl::size index) FL_NOEXCEPT
Pointer to element at index (byte arithmetic).
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT

References vector_basic(), fl::memory_resource::allocate(), element_ptr(), hasInlineBuffer(), inlineBufferPtr(), isInline(), mArray, mCapacity, mElementSize, fl::memcpy(), mInlineCapacity, mOps, mResource, mSize, swap_impl(), trivial_copy(), and trivial_swap().

Referenced by fl::vector< fl::i16 >::swap(), fl::vector< fl::i16 >::swap(), and swap_impl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: