FastLED 3.10.8
Loading...
Searching...
No Matches

◆ swap_impl()

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

Swap contents with another vector_basic.

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

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

References vector_basic(), element_ptr(), fl::FL_NO_EXCEPT, isInline(), mArray, mCapacity, mElementSize, fl::memcpy(), mOps, mResource, mSize, trivial_copy(), trivial_swap(), and uninitialized_move_n_impl().

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

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