Files CCore/inc/Swap.h CCore/src/Swap.cpp
Swap is not just a set of functions and classes, but a fundamental idiom. Swapping means an exchanging object states as the one operation. Objects of a Small Data Types can be copied efficiently. In fact, it is a generalized definition of the such kind of types. Efficiency can be defined in another terms as the O(1)-nothrow property. But for many types (actually, for most of them) copying is either not logically possible, or not efficient, because requires duplication of a large state, and that is time and space expensive and can fail. So instead of copying we should use moving or swapping whenever possible. For example, to return a result from a function:
void func(T &ret) { T result; .... // result is built, took some resources Swap(result,ret); // result -> ret, ret -> result // null state result is destroyed } void other_func() { .... T obj; // null state, no resource taken func(obj); .... }
Swap is derivable: if the state is a composition of states and each of them is swappable, then the whole state is swappable:
struct S
{
A a;
B b;
C c;
// swap objects
void objSwap(S &obj) // efficient combination of efficient parts
{
Swap(a,obj.a);
Swap(b,obj.b);
Swap(c,obj.c);
}
};
But what the most important, Resource Host Types are swappable.
class H : NoCopy
{
private:
ResourceHandle h; // Small Data Type
public:
H() { SetNull(h); }
H(A a,B b,C c) { h=New(a,b,c); }
~H() { Delete(h); }
// swap objects
void objSwap(S &obj) // efficient
{
Swap(h,obj.h);
}
};
That is the main cause why Swap is applicable to the wide range of types.
template <class T> void CopySwap(T &a,T &b) noexcept; template <class T> void MoveSwap(T &a,T &b) noexcept; template <class T> void Swap(T &a,T &b) noexcept;
Well, you already known how to use Swap (see the code above). Here is some implementation details. The function Swap() uses the method objSwap() of the destined type to perform the operation. So to make a class swappable just define this method in the class. If a type is not a class type or the class has no this method, Swap() uses MoveSwap() or CopySwap() to do the job. If the type has the move constructor and the move assign operator, then MoveSwap() is used. It is assumed, that move operations do not throw. If the moving is not available CopySwap() is used. In such case the type must be copyable. Again, it is assumed, that copy operations do not throw. Otherwise a warning is emitted.
/* NullBySwap() */ template <class T> void NullBySwap(T &obj) { T temp{}; Swap(temp,obj); } /* MoveBySwap() */ template <class T> void MoveBySwap(T &dst,T &src) { Swap(dst,src); NullBySwap(src); }
These two helper functions uses Swap() to nullify and move objects. The object must be swappable and admit the default constructor.