C++ the good parts — std::swap

User-Defined Trivial Types are more or less simple structs (or classes) with no methods or constructors, made by you. Refresher starts here.

To analyze moving and swapping of such types we will use

Let’s start by moving an instance of the above.

Class Data Containment

The above layout is trivial among other things because the above Capsule instance contains all of its data.  Basically, it has no pointers to elsewhere. It is one self-contained memory block.

That is important for swap or move. Basically, the compiler is swapping memory blocks when dealing with standard layout.

The above is indeed swapped.   The compiler can do this (on its own) because each instance above is in its own memory block; the situation is laid out as two memory blocks.

Quick recap. Here is the visualization of the swap( A, B ) operation. Two values swapping.

Values swapping

Please note: Temporary is local to the swap function. Again, please remember: By C++ standard, B value is moved from. And left in this curious “undefined” state. Do not use it as it is moved from.

That’s it. Done. Let’s go out and have some fun?! Well … not yet.  What comes is:

Native Pointers are not Fundamental Types

I will ask again: you are clear on the C++ type system right? In particular, you are now sure where do native pointers fit in. Good, but why does this matter now?

std::move applied to values has full effect. But,  after the move operation native pointers are left as they are. Pointers are:

  1. Not fundamental types
  2. Just memory addresses

std::move on a native pointer has no effect.

What exactly happens if you move from the pointer?

Basically, nothing happens. You have two pointers pointing to the same memory address with the single value inside

Two same pointers

std::iter_swap

Let’s now swap two pointers.  In C++ lingo pointers are iterators. There is std::iter_swap for swapping two pointers, aka iterators. What do you expect will happen?

Follow the above through debugger. Surprise?  The result is the same as if we have swapped two values not pointers, two instances of capsule.  This is not a surprise if you peek into the synopsis of  the std::iter_swap :

It simply dereferences the pointers and calls the std::swap on two instances.

The outcome for pointers (aka iterators) of both trivial types and fundamental types is:  pointers have not changed, and the values are. It is as simple as that.

But that simplicity yields complexity when dealing with the next type category.

Swapping Non-Trivial User-Defined Types

(please go to next page)