Provided by: libbobcat-dev_6.04.00-1ubuntu3_amd64 bug

NAME

       FBB::fswap - generic template fast swap function

SYNOPSIS

       #include <bobcat/fswap>

DESCRIPTION

       The  information  stored  in objects frequently needs to be swapped. A well-known example is the swapping
       operation required when implementing an overloaded assignment operator. For example, the generic form  of
       the operator assignment operator is:

           Class &operator=(Class const &other)
           {
               Class tmp(other);
               swap(tmp);
               return *this;
           }

       The  swap  functionality  merely swaps the content of the current object and another object. The standard
       std::swap function calls the class’s operator= function to swap objects. Newer implementations might  use
       move-operations  to  increase  the  speed  of  the swapping operation, but in both cases some form of the
       assignment operator must be available. Swapping,  however,  might  be  possible  when  assignment  isn’t.
       Classes  having  reference  data members usually don’t offer assignment operators but swapping might be a
       well-defined operation.

       It is well known that objects can be installed in a block of memory using placement new, using a block of
       memory the size of the object to construct the object it. This is the foundation of the template function
       FBB::fswap (fast swap). This swap function merely uses the memory occupied by objects  to  implement  the
       swapping  operation  and  it may therefore be used with classes having const data members, reference data
       members, ponters to allocated memory etc, etc. The function simply uses a spare block of memory the  size
       of the object to be swapped. It then uses memcpy(3) to swap the information contained in the two objects,
       using the spare block of memory as a placeholder.

       Classes may define data members that do not support fast swapping. If such data members  can  be  swapped
       using  either  std::swap  or  their  own  swap  member,  then overloaded versions of fswap can be used to
       fast-swap objects of such classes. Also, classes may inherit  from  base  classes  that  do  not  support
       fast-swapping,  but that either offer their own swap members or can be swapped using std::swap. For these
       cases overloaded versions of fswap are also available. The classes std::string and std::unordered_map are
       examples  of  classes  whose  objects  might  not  be  swappable  using a fast swap method. Therefore, in
       practice, classes defining members of such classes should use one of the overloaded fswap  functions  for
       swapping their objects.

NAMESPACE

       FBB
       All  constructors,  members,  operators  and manipulators, mentioned in this man-page, are defined in the
       namespace FBB.

INHERITS FROM

       -

ENUMERATION

       The enumereation SwapMode is used to specify a specific swapping-method:

       o      SWAPMEMBER is selected by default, but it can also explicitly  be  specified.  It  indicates  that
              selected  members  are  swapped  using  their  own  swap  member  function  having prototpype void
              Type::swap(Type &rhs).

       o      STDSWAP can be specified to indicates that selected members should  be  swapped  using  std::swap.
              Specific  members not supporting fast swapping can always be swapped using a specific swap-method.
              E.g., when SWAPMEMBER is selected, but a particular data member does not offer a swap-member, then
              std::swap can be specified for just that member.

SWAP FUNCTIONS

       o      fswap(Type &lhs, Type &rhs):
              This  template function swaps the content of two objects. It can be used with classes having const
              data members, reference members, pointer members or standard value-typed data members;

       o      fswap(Type &lhs, Type &rhs, member, ...):
              This function is provided with a list of member names (i.e., members of the class  Type)  that  do
              not  support  fast  swapping.  Those  members are swapped using their swap member, while all other
              members are fast-swapped. When using lists of members, the selected  members  must  be  listed  in
              their declaration order or a std::runtime_error exception is generated when the function is used.

       o      fswap<SwapMode::SWAPMEMBER>(Type &lhs, Type &rhs, member, ...):
              This  function  acts  identically  as  the previous function, but explicitly specifies its default
              swapping method.

              Each of the members specified in the list of members can be specified by  their  names,  in  which
              case  the  specified  swapping method is used. Alternatively stdswap(member) can be used, in which
              case std::swap is used for swapping member; or swapmember(member) can be used, in which case  that
              member’s swap member function is used for swapping member;

       o      fswap<SwapMode::STDSWAP>(Type &lhs, Type &rhs, member, ...):
              This  function  is  also  provided  with a list of member names that do not support fast swapping.
              Those members are swapped using std::swap. As with the previous function, members can be specified
              by their names, or stdswap(member) or swapmember(member) can be used;

       o      fswap[swapMode](&firstMember, Type &lhs, Type &rhs [, member, ...]):
              This  function’s  first  argument is the address of Type’s first data member (usually specified as
              &d_first inside Type’s own swap member). It is used when Type is derived from a  base  class  that
              itself  does  not  support fast swapping. This function may optionally be provided with a SwapMode
              template non-type argument (by default SWAPMEMBER is used), and may also be provided with  a  list
              of members (optionally using stdswap and swapmember).

EXAMPLE

       #include <iostream>

       #include "../fswap"

       using namespace FBB;

           // Demo class, members d_v3 and d_v4 cannot be memcpy-fast swapped
           //
       class Demo
       {
           size_t d_v1;
           size_t d_v2;
           std::string d_v3;
           std::string d_v4;
           size_t d_v5;

           public:
               Demo(size_t value = 0);
               void show(char const *msg);
               void swap(Demo &rhs);
       };

       Demo::Demo(size_t value)
       :
           d_v1(value),
           d_v2(value + 1),
           d_v3(std::to_string(value + 2)),
           d_v4(std::to_string(value + 3)),
           d_v5(value + 4)
       {}

           // fast-swap 2 objects, except for d_v3 and d_v4, which are
           // swapped by either std::swap or their own .swap() members
           //
       void Demo::swap(Demo &rhs)
       {
                               // This is OK, after commenting out the
       //  fswap(*this, rhs);  // string members

                               // specifying members that should be swapped
                               // using std::swap. These members MUST be
                               // specified in their class declaration order
           fswap(*this, rhs, d_v3, d_v4);
       //  fswap(*this, rhs, d_v4, d_v3);  // this won’t work...

                                   // same, explicitly requesting the
                                   // swap-mode
       //  fswap<SwapMode::SWAPMEMBER>(*this, rhs, d_v3, d_v4);

                                   // explicitly requesting another
                                   // swap-mode
       //  fswap<SwapMode::STDSWAP>(*this, rhs, d_v3, d_v4);

                                   // default, starting at a begin-member
                                   // NOTE: the example does NOT swap d_v1
       //  fswap(&d_v2, *this, rhs, d_v3, d_v4);

                                   // use fastswap, but start at the
                                   // member d_v1 (use this for derived
                                   // classes whose base class do not
                                   // support fast swapping.
                                   // Before using this example comment
                                   // out the class’s std::string members
       //  fswap(&d_v1, *this, rhs, d_v3);

                                   // same, explicitly requesting the
                                   // swap method, swapping all
       //  fswap<SwapMode::SWAPMEMBER>(&d_v1, *this, rhs, d_v3, d_v4);

                                   // explicitly requesting another
                                   // swap-mode
       //  fswap<SwapMode::STDSWAP>(&d_v1, *this, rhs, d_v3, d_v4);

                                   // use stdswap by default, but not
                                   // for d_v4, for which .swap() is
                                   // used
       //  fswap(&d_v1, *this, rhs, d_v3, swapmember(d_v4));

                                    // same
       //  fswap<SwapMode::STDSWAP>(&d_v1, *this, rhs, d_v3,
       //                                              swapmember(d_v4));

                                    // explicitly requesting the already
                                    // default swap method is OK
       //  fswap(&d_v1, *this, rhs, swapmember(d_v3), stdswap(d_v4));

       }

       void Demo::show(char const *msg)
       {
           std::cout << msg << ". " << d_v1 <<
                           ", " << d_v2 <<
                           ", " << d_v3 <<
                           ", " << d_v4 <<
                           ", " << d_v5 <<
                           ’\n’;
       }

       using namespace std;

       int main()
       {
           Demo d1(10);
           Demo d2(20);

           d1.show("This is d1:");
           d2.show("This is d2:");

           cout << "swapping...\n";
           d1.swap(d2);

           d1.show("This is d1:");
           d2.show("This is d2:");

       }

FILES

       bobcat/fswap - defines the class interface

SEE ALSO

       bobcat(7), memcpy(3)

BUGS

       The  fswap  functions  should  not be applied mechanically to swap objects of classes having pointer data
       members defining, e.g., a linked list. Consider a list of four objects like:

           A -> B -> C -> D

       fast-swapping B and C would result in the following corrupted list:

                      +------+
                      |      |
           A -> C -+  +-> B -+   +-> D
                   |             |
                   +-------------+

       However, classes implementing a data structure like a linked-list might still benefit from fast  swapping
       operations: by implementing their own swap member they could first use fast swapping to swap the objects,
       followed by another fast swap to unswap their `next’ pointers.

       The fswap function should also not be used for  objects  defining  (back-)pointers  to  their  own  data.
       Consider the following objects using pointers to data and (back-)pointers to the original objects:

           Before fswapping:
               A                                  B
              +--------+   +-----------+         +--------+   +-----------+
              |        |   |           |         |        |   |           |
            +--> *Aimp------> *A (back)--+     +--> *Bimp------> *B (back)--+
            | |        |   |           | |     | |        |   |           | |
            +--**Aimp  |   +-----------+ |     +--**Bimp  |   +-----------+ |
              +--------+ <---------------+       +--------+ <---------------+

           After fswapping:
                            +-------------------------------+
                         +--|-------------------------------|-+
           +-------------|--|-----------------+             | |
           |   A         |  v                 |   B         | v
           |  +--------+ | +-----------+      |  +--------+ | +-----------+
           |  |        | | |           |      |  |        | | |           |
         +-----> *Bimp---+ |  *A (back)--+    +---> *Aimp---+ |  *B (back)--+
         | |  |        |   |           | |       |        |   |           | |
         | +---**Bimp  |   +-----------+ |    +---**Aimp  |   +-----------+ |
         |    +--------+ <---------------+    |  +--------+ <---------------+
         +------------------------------------+

       After  the swap **Bimp should point to Bimp’s address (now at A), but in fact it points to Aimp’s address
       (now at B). Likewise, the back pointers still point at  their  original  objects  rather  than  at  their
       swapped objects.

       All stream classes define such pointers and can therefore not be swapped using fswap.

       The  bottom line being that fswap should only be used for self-defined classes for which it can be proven
       that fast-swapping does not corrupt the values of its pointer data.

BOBCAT PROJECT FILES

       o      https://fbb-git.gitlab.io/bobcat/: gitlab project page;

       o      bobcat_6.04.00-x.dsc: detached signature;

       o      bobcat_6.04.00-x.tar.gz: source archive;

       o      bobcat_6.04.00-x_i386.changes: change log;

       o      libbobcat1_6.04.00-x_*.deb: debian package containing the libraries;

       o      libbobcat1-dev_6.04.00-x_*.deb: debian package containing the libraries, headers and manual pages;

BOBCAT

       Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.

COPYRIGHT

       This is free software, distributed under the terms of the GNU General Public License (GPL).

AUTHOR

       Frank B. Brokken (f.b.brokken@rug.nl).