<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <title>Introduction of std::colony to the standard library</title>
  <style>
body {
    font-size: 12pt;
    font-family: Helvetica, Arial, sans-serif;
    font-weight: normal;
    font-style: normal;
    color: black;
    background-color: white;
    line-height: 1.2em;
    margin-left: 4em;
    margin-right: 2em;
   }

/* paragraphs */
p  {
    padding: 0;
    line-height: 1.3em;
    margin-top: 2.5em;
    margin-bottom: 1em;
    text-align: left;
   }

/* paragraphs */
table  {
    margin-top: 3.8em;
    margin-bottom: 2em;
    text-align: left;
   }
/* headings */
h1 {
    font-size: 195%;
    font-weight: bold;
    font-style: normal;
    font-variant: small-caps;
    line-height: 1.6em;
    text-align: left;
    padding: 0;
    margin-top: 3.5em;
    margin-bottom: 1.7em;
   }
h2 {
    font-size: 122%;
    font-weight: bold;
    font-style: normal;
    text-decoration: underline;
    padding: 0;
    margin-top: 4.5em;
    margin-bottom: 1.1em;
   }
h3 {
    font-size: 110%;
    font-weight: bold;
    font-style: normal;
    text-decoration: underline;
    padding: 0;
    margin-top: 4em;
    margin-bottom: 1.1em;
   }
h4 {
    font-size: 100%;
    font-weight: bold;
    font-style: normal;
    padding: 0;    
    margin-top: 4em;
    margin-bottom: 1.1em;
   }
h5 {
    font-size: 90%;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin-top: 3em;
    margin-bottom: 1em;
   }
h6 {
    font-size: 80%;
    font-weight: bold;
    font-style: normal;
    padding: 0;
    margin-top: 1em;
    margin-bottom: 1em;
   }

/* divisions */
div {
    padding: 0;
    margin-top: 0em;
    margin-bottom: 0em;
   }

          ul {
           margin: 0pt 0pt 22pt 15.7pt;
           padding: 0pt 0pt 0pt 0pt;
           list-style-type: square;
           font-size: 10.5pt;
           font-family: sans-serif;
                        }
          ol {
           margin: 12pt 0pt 8pt 15.7pt;
           padding: 0pt 0pt 0pt 0pt;
           font-size: 10.5pt;
                        }
          li {
           margin: 0pt 0pt 10.5pt 0pt;
           padding: 0pt 0pt 0pt 0pt;
           text-indent: 0pt;
           font-size: 10.5pt;
           display: list-item;
           font-family: sans-serif;
                        }

/* inline */
strong {
    font-weight: bold;
   }
sup, sub {
   vertical-align: baseline;
   position: relative;
   top: -0.4em;
   font-size: 70%;
}
sub { top: 0.4em; }
em {
    font-style: italic;
   }
code {
    font-family: Courier New, Courier, monospace;
    font-size: 90%;
    padding: 0 0 0 0em;
   }
ins {
    background-color: yellow;
    text-decoration: underline;
   }
del {
    text-decoration: line-through;
   }


                a:hover {
                  color: #4398E1;
                  }

                a:active {
                  color: #4598E1;
                  text-decoration: none;
                  }

                a:link.review {
                  color: #AAAAAF;
                  }

                a:hover.review {
                  color: #4398E1;
                  }

                a:visited.review {
                  color: #444444;
                  }

                a:active.review {
                  color: #AAAAAF;
                  text-decoration: none;
                  }</style>
  <meta http-equiv="content-type" content="text/html; charset=windows-1252">
</head>

<body>
Audience: LEWG, SG14<br>
Document number: P0447R0<br>
Date: 2016-10-16<br>
Project: Introduction of std::colony to the standard library<br>
Reply-to: Matthew Bentley &lt;mattreecebentley@gmail.com&gt;<br>


<h1>Introduction of std::colony to the standard library</h1>

<h2>I. Introduction</h2>

<p><i>This is an initial draft based on a positive response to functionality
and performance of the reference implementation. Colony has at this point been
receiving community feedback for the past 1.5 years from Boost, SG14 and individual
developers, and on the basis of support from SG14, I am seeking indication of
levels of interest for inclusion in the standard. At this stage I would also
like to ask for feedback on the existing design/interface, and suggestions
prior to proceeding to wording.</i></p>

<p>Sometimes while programming we come across situations where order is
unimportant, but where data is heavily interlinked, iterated over frequently,
and changing often. An example would be a central 'entity' class in most video
game engines. These are 'has a'-style objects rather than 'is a'-style objects,
which reference other shared resources such as sprites, sound fx and so on.
Those resources are typically located in separate containers. The 'entities'
themselves are in turn referenced by other structures such as quadtrees/octrees
(for collision detection), level structures, and the like. When iterating over
entities, one has to take into account the fact that they may be removed from
the game at any time (for example, a wall gets destroyed and therefore no
longer requires processing) and new entities inserted (for example, if a new
enemy arrives during a level). While this is happening, the inter-linkages
between entities, resource collections and superstructures like levels and
quadtrees, must stay valid. The order of the entities and resources themselves
within the containers is, typically, unimportant.</p>

<p>There are obviously many different ways of allowing objects to reference
each other under C++, but the fastest are pointers, closely followed by indexes
(for contiguous containers). Unfortunately the container which has the best
iteration performance in the standard library, vector<sup><a
href="#benchmarks">[1]</a></sup>, also loses pointer validity to elements
within it upon insertion, and also pointer/index validity upon erasure. This
leads to sophisticated and restrictive workarounds when developers attempt to
utilize vector under the above circumstances.</p>

<p>Colony is a specifically unordered-but-sortable templated data container
which allows for fast iteration and direct pointer linkage, without losing
pointer/iterator validity to non-erased/non-end() elements when insertions or
erasures occur. It is it's own abstract data type, but is most similar to a
"bag", "bucket-array" or "multiset" ADT, the central difference being the
absence of key values. On the basis of a fully-developed reference
implementation the following performance characteristics have been
established:</p>

<p>Specifically, a colony has better overall performance than any standard
library container when:</p>
<ol type="a">
  <li>Insertion order is unimportant</li>
  <li>Insertions and erasures to the container are occurring frequently in
    performance-critical code, <i><b>and/or</b></i> </li>
  <li>Pointers/iterators to non-erased/non-end() container elements must not be
    invalidated by insertion or erasure.</li>
</ol>

<p>While the benchmarks<sup><a href="#benchmarks">[1]</a></sup> referenced in
the appendix are a better tool for understanding the performance
characteristics, the comparative speed characteristics for most-commonly-used
operations in the above scenario as described are:</p>
<ul>
  <li><i>Singular (non-fill), unordered insertion</i>: better than any std::
    library container except some implementations of deque, when compared with
    insertion at the fastest location (eg. at back for std::vector, front for
    std::list). This is achieved by using a multiple-memory-block model with a
    growth factor, which removes a need for reallocation upon reaching
    capacity. Additionally this model preserves pointer validity upon
  insertion.</li>
  <li><i>Erasure (from random location)</i>: better or equal to any std::
    library container. This assumes the erasure location is found during
    iteration or via pre-existing pointers/iterators to the element. The result
    is achieved via the use of a jump-counting skipfield to indicate erasures,
    as opposed of a vector/deque's method of reallocating elements after the
    erased element. It is true regardless of whether a remove_if idiom is
    utilized with a vector in the comparison. Utilizing a skipfield also
    preserves pointer validity to non-erased elements post-erasure.</li>
  <li><i>Iteration</i>: better than any std:: library container when pointer
    validity post erasure/insertion is preserved (eg. map, multiset, list).
    Where pointer validity is unimportant, better than any std:: library
    container except deque and vector. This result is due to the largely
    contiguous element storage from the multiple-memory-block model in
    combination with utilization of the jump-counting skipfield, which does not
    utilize branching code for iteration.</li>
</ul>

<p>As explored in the benchmarks<sup><a href="#benchmarks">[1]</a></sup> there
are some vector/deque modifications/workarounds which can outperform colony for
iteration while maintaining pointer validity, but which have slower insertion
and erasure speeds, and also typically have a cost to usability or memory
requirements. When the ratio of insertions/erasures to iterations is greater
than 1% insertions/erasures per 3600 full iterations over data, colony will
outperform these workarounds. Colony's other advantages are the freeing and
recycling of unused memory on-the-fly, and the guaranteed validity of
pointers/references to non-erased elements regardless of insertion and erasure
(which makes programming with containers of inter-related data structures much
simpler). Iterators which do not point to end() or erased elements are also
guaranteed to remain valid.</p>

<p></p>

<h2>II. Motivation and Scope</h2>

<p>While the conditions below are common across multiple domains, for the
benefit of those unfamiliar with any specific scenarios, I will present the
motivation with examples from game development. When working on game engines we
are predominantly dealing with collections of data where:</p>
<ol type="a">
  <li>Elements within data collections refer to elements within other data
    collections (through a variety of methods - indices, pointers, etc). An
    example is a game entity referring to both a texture object and collision
    blocks, as well as sound data. These references must stay valid throughout
    the course of the game/level. For this reason, any container (or use of a
    container) which causes pointer or index invalidation can create
    difficulties or necessitate workarounds.</li>
  <li>Order is unimportant for the most part. The majority of data collections
    are simply iterated over, transformed, referred to and utilized with no
    regard to order.</li>
  <li>Erasing or otherwise removing or deactivating objects occurs frequently
    in-game and in realtime (though often erasures will be implemented to occur
    at the end of a frame due to multithreading concerns). An example could be
    destroying a wall, or a game enemy. For this reason methods of erasure
    which create strong performance penalties are avoided.</li>
  <li>Creating new objects and adding them into the gameworld on-the-fly is
    also common - for example, a tree which drops leaves every so often, or a
    quadtree.</li>
  <li>We don't always know in advance how many elements there will be in a
    container at the beginning of development, or even at the beginning of a
    level during playback. Genericized game engines in particular have to adapt
    to considerably different user requirements and scopes. For this reason
    extensible containers which can expand and contract in realtime are usually
    necessary.</li>
  <li>For performance reasons, memory storage which is more-or-less contiguous
    is preferred. Lists, vectors of pointers to dynamically-allocated objects,
    and maps as implemented in the standard library are unusable.</li>
  <li>Memory wastage is avoided, and in particular, any container which
    allocates upon initialisation tends to be avoided as this can incur
    purposeless memory and performance costs.</li>
</ol>

<p>std::vector, in it's default state, does not meet these requirements due
to:</p>
<ol>
  <li>Poor (non-fill) singular insertion performance (regardless of position)
    due to the need for reallocation upon reaching capacity</li>
  <li>Poor erasure performance for large amounts of data (even with remove_if
    duration is highly variable)</li>
  <li>Insert invalidates pointers/iterators to all elements </li>
  <li>Erase invalidates pointers/iterators/indexes to all elements afer the
    erased element </li>
  <li>Requires single contiguous memory block (typically larger than cache
    lines) which increases chance of allocation failures for large amounts of
    data on insert</li>
</ol>

<p>To meet these requirements, game developers tend to either (a) develop their
own custom containers for given scenarios or (b) develop workarounds for the
problems of vector. These workarounds are many and varied, but the most common
are probably:</p>
<ol>
  <li>Using a boolean flag (or similar) to indicate the inactivity of an object
    (as opposed to actually erasing from the vector). When erasing, one simply
    adjusts the boolean flag, and when iterating, items with the adjusted
    boolean flag are skipped. External elements refer to elements within the
    container via indexes rather than pointers (which can be invalidated upon
    insertion).<br>
    <br>
    Advantages: Fast erasure.<br>
    Disadvantages: Slow to iterate due to branching. </li>
  <li>Utilizing a vector of data with a secondary vector of indexes. When
    erasing, the erasure occurs in the vector of indexes, not the vector of
    data, and when iterating, one iterates over the vector of indexes, then
    accessing the data from the vector of data via the index. <br>
    <br>
    Advantages: Faster iteration.<br>
    Disadvantages: Erasure still incurs some reallocation cost, can increase
    jitter. </li>
  <li>Combining a swap-and-pop mechanism with some form of dereferenced lookup
    system to enable contiguous element iteration (sometimes known as a 'packed
    array', various other names: <a href="http://bitsquid.blogspot.ca/2011/09/managing-decoupling-part-4-id-lookup.html">http://bitsquid.blogspot.ca/2011/09/managing-decoupling-part-4-id-lookup.html</a>).
    In this case when erasing we swap the back element of the vector with the
    element being erased, then pop the (swapped) back element. When iterating
    over the data we simply iterate through the vector of elements. To maintain
    valid external references to elements, which may be swapped at any time, we
    must also maintain a vector of indexes (or similar) and update the index
    numbers which correspond with the element being erased and the element
    being moved. In addition external objects referring to elements within the
    container must store a pointer to the index for the element in question.
    There are many varied alternatives to this method. The method is more
    useful when the container's data is mostly being iterated over, with fewer
    external references to the individual elements.<br>
    <br>
    Advantages: Iteration is at standard vector speed.<br>
    Disadvantages: Erase could be slow if objects are large and/or
    non-trivially copyable, making swap cost thereby large. All references to
    elements incur additional costs due to the dereferencing system. </li>
</ol>

<p>All three techniques have the disadvantage of slow singular insertions, and
the first two will also continually expand memory usage when erasing and
inserting over periods of time. The third deals better with this scenario as it
swaps from the back rather than leaving gaps in the elements vector, however it
will not free memory if the number of elements expands then contracts. It will
also suffer in performance if elements within the container are heavily
referred to by external objects/elements in performance-critical situations, or
if the elements are large and/or swap/copy is non-trivial in other ways.</p>

<p>Colony is an attempt to bring a more generic solution to this situation. It
has the advantage of good iteration speed, a similar erasure speed to the
boolean technique described above, and a singular insertion speed which is much
faster than a vector's, similar to a good deque implementation's. It never
causes pointer invalidation to non-erased elements during erasure or insertion
and the memory locations of erased elements are either reused by subsequent
insertions or released on-the-fly when the encapsulating memory block becomes
empty of elements.</p>

<h2>III. Impact On the Standard</h2>

<p>This is a pure library addition, no changes are necessary to the standard
asides from the introduction of the colony container. <br>
The reference implementation of colony is available here as plf::colony: <a
href="http://www.plflib.org/colony.htm#download">http://www.plflib.org/colony.htm</a></p>

<h2>IV. Design Decisions</h2>

<p>The key technical features of a colony are as follows:</p>
<ul>
  <li>Unordered non-associative data container</li>
  <li>Never invalidates pointers to non-erased elements</li>
  <li>Reuses or frees memory from erased elements (memory is freed if memory
    block becomes empty, see below)</li>
  <li>In the context of general game data requirements (as described in section
    III), should be faster than any unmodified standard library container</li>
  <li>Iterators to non-erased elements guaranteed to stay valid unless iterator
    == end()</li>
</ul>

<p>The full list of abstract requirements to support these features are as
follows:</p>
<ul>
  <li>Must use multiple memory-blocks as this prevents element reallocation on
    insertion</li>
  <li>Blocks must be freed once empty</li>
  <li>Blocks must be removable with low performance cost and without pointers
    to elements being invalidated</li>
  <li>Must have a mechanism for reusing erased element locations upon
  insertion</li>
  <li>Erased elements are recorded in a skipfield, skipped over during
    iteration - prevents element reallocation on erasure</li>
  <li>Skipfield design must allow for O(1) ++ and -- iteration</li>
</ul>

<p>To summarise and simplify we can say there are three necessary aspects to
colony to make it function as it does, and which define any implementation:</p>
<ol>
  <li>A multiple-memory-block based allocation pattern which allows for the
    fast removal of memory blocks when they become empty of elements
    (regardless of their location within the series of blocks), without element
    pointer invalidation.</li>
  <li>A skipfield to enable the skipping over of erased elements during
    iteration, which should not necessitate the use of branching code during
    iteration for performance reasons.</li>
  <li>A mechanism for reusing erased element locations upon subsequent
    insertions.</li>
</ol>

<p>In the case of the reference implementation I utilized a chained-group
allocation pattern (<a
href="http://www.plflib.org/chained_group_allocation_pattern.htm">http://www.plflib.org/chained_group_allocation_pattern.htm</a>)
for the memory blocks; which is a doubly-linked intrusive list of nodes
containing (a) memory blocks, (b) memory block metadata and (c)
skipfields. The metadata in question includes information necessary for an iterator to iterate over colony elements, such as the last insertion point within the memory block, and other information useful to specific functions such as the total number of active elements in the node. This 'linked-list'-style pattern removes the possibility of
non-O(1) operations when freeing empty memory blocks from the colony structure;
as compared to a vector of pointers to memory blocks. A vector of pointers to
memory blocks may however enable faster insertions while increasing
implementation complexity. Comparitive benchmarks would be necessary to
establish the overall optimal approach.</p>

<p>For the skipfield a boolean skipfield cannot be used:</p>
<ul>
  <li>++ iteration is O(random), iterators require O(1) operations </li>
  <li>Any boolean skipfeld creates branching code in the iterator </li>
  <li>Dependent on CPU branch prediction for performance </li>
  <li>Iterator code complexity increases</li>
  <li>Waste of 7 bits (and 254 states) per element if aiming for speed
    (byte-level addressing- bool or char) rather than storage size (bitfeld -
    slower)</li>
</ul>

<p>Instead the reference implementation utilizes the jump-counting skipfield
pattern (full reference paper available here: <a
href="http://www.plflib.org/the_jump_counting_skipfield_pattern.pdf">http://www.plflib.org/the_jump_counting_skipfield_pattern.pdf</a>),
a numeric pattern I developed which allows for O(1) time complexity iterator
operations and performs better during iteration due to a lack of branching
code. It accomplishes this by storing and modifying (during insertion and
erasure) numbers corresponding to the number of elements in a run of erased
elements, and simply adding them to the current iterator position during
iteration instead of checking their state. This avoids the looping branching
code necessary for iteration with, for example, a boolean skipfield.</p>

<h6>Iteration performance of vector with boolean skipfield vs colony with
boolean skipfield vs colony with jump-counting skipfield (GCC5):</h6>
<a
href="http://www.plflib.org/tests/gcc/colony/jump_counting/jump_counting_comparison_iteration_25.png"><img
alt="test result graph" height="25%" width="25%"
src="http://www.plflib.org/tests/gcc/colony/jump_counting/jump_counting_comparison_iteration_25.png"></a> 

<p>For the erased location re-use mechanism, the reference implementation uses
a stripped-down custom internal stack class based on plf::stack (<a
href="http://www.plflib.org/stack.htm">http://www.plflib.org/stack.htm</a> - outperforms
all other std:: containers in a stack context and across compilers). plf::stack uses
the same chained-group memory allocation pattern as plf::colony ie. it is made
up of a linked chain of 'groups', structs containing a memory block and
metadata, with a growth factor of 2 for the memory blocks. When capacity of the
current memory block is reached, a new group is created and linked to the
current memory block.</p>

<h6>Time to push all elements + read-and-pop all elements, plf::stack vs
std::stack (std::deque) vs std::vector (GCC5):</h6>
<a
href="http://www.plflib.org/tests/gcc/stack/small_struct_total_time.png"><img
alt="test result graph" width="25%" height="25%"
src="http://www.plflib.org/tests/gcc/stack/small_struct_total_time.png"></a> 

<p>An alternative route of using a "free list" (explanation: <a
href="http://bitsquid.blogspot.ca/2011/09/managing-decoupling-part-4-id-lookup.html">http://bitsquid.blogspot.ca/2011/09/managing-decoupling-part-4-id-lookup.html</a>)
of erased elements for the re-use mechanism has been explored and the following
issues identified:</p>
<ol>
  <li>A colony element could be smaller in size than a pointer and thus a union
    with such would dramatically increase the amount of wasted space in
    circumstances with low numbers of erasures - moreso if the pointer type
    supplied by the allocator happens to be non-trivial.</li>
  <li>Given that a free list will jump between colony groups a lot,
    consolidating a free list after removing empty groups from a colony would
    typically result in a very slow operation filled with cache misses. In the
    context of jitter-sensitive domains such as game development this is
    unacceptable.</li>
</ol>

<h2>V. Technical Specifications</h2>

<p>Colony meets the requirements of the C++ <a
href="http://en.cppreference.com/w/cpp/concept/Container">Container</a>, <a
href="http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer">AllocatorAwareContainer</a>,
and <a
href="http://en.cppreference.com/w/cpp/concept/ReversibleContainer">ReversibleContainer</a>
concepts.</p>

<p>For the most part the syntax and semantics of colony functions are very
similar to all std:: c++ libraries. Formal description is as follows:</p>
<code>template &lt;class T, class Allocator = std::allocator&lt;T&gt;, typename
Skipfield_Type = unsigned short&gt; class colony</code> 

<p><code><b>T</b></code> - the element type. In general T must meet the
requirements of <a
href="http://en.cppreference.com/w/cpp/concept/Erasable">Erasable</a>, <a
href="http://en.cppreference.com/w/cpp/concept/CopyAssignable">CopyAssignable</a>
and <a
href="http://en.cppreference.com/w/cpp/concept/CopyConstructible">CopyConstructible</a>.<br>
However, if emplace is utilized to insert elements into the colony, and no
functions which involve copying or moving are utilized, T is only required to
meet the requirements of <a
href="http://en.cppreference.com/w/cpp/concept/Erasable">Erasable</a>. If
move-insert is utilized instead of emplace, T must also meet the requirements
of <a
href="http://en.cppreference.com/w/cpp/concept/MoveConstructible">MoveConstructible</a>
 .<br>
<br>
<code><b>Allocator</b></code> - an allocator that is used to acquire memory to
store the elements. The type must meet the requirements of <a
href="http://en.cppreference.com/w/cpp/concept/Allocator">Allocator</a>. The
behavior is undefined if <code>Allocator::value_type</code> is not the same as
T.<br>
<br>
<code><b>Skipfield_Type</b></code> - an unsigned integer type. This type is
used to create the skipfield and the maximum size of element memory blocks is
constrained by it's bit-depth due to the nature of a jump-counting skipfield.
For example, <code>unsigned short</code> on most platforms is 16-bit and
therefore constrains the size of individual memory blocks to a maximum of 65535
elements. <code>unsigned short</code> has been found to be the optimal type for
performance based on benchmarking. However there may be some memory-constrained
situations where element block allocations of more than 255 elements at a time
would not be desirable. In these situations, <code>unsigned char</code> may be
used for the skipfield instead, resulting in some additional memory usage
saving for the skipfield itself. It is unlikely for there to be any
circumstances which benefit from a skipfield bit-depth greater than
<code>unsigned short</code>. If <code>Skipfield_Type</code> is not an unsigned
integer type, behaviour is undefined. </p>

<h4>Basic example of usage</h4>

<div
style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;">
<pre style="margin: 0; line-height: 125%"><code><span style="color: #557799">#include &lt;iostream&gt;</span>
<span style="color: #557799">#include "plf_colony.h"</span>

<span style="color: #333399; font-weight: bold">int</span> <span style="color: #0066BB; font-weight: bold">main</span>(<span style="color: #333399; font-weight: bold">int</span> argc, <span style="color: #333399; font-weight: bold">char</span> <span style="color: #333333">**</span>argv)
{
  plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span><span style="color: #333333">&gt;</span> i_colony;

  <span style="color: #888888">// Insert 100 ints:</span>
  <span style="color: #008800; font-weight: bold">for</span> (<span style="color: #333399; font-weight: bold">int</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>; i <span style="color: #333333">!=</span> <span style="color: #0000DD; font-weight: bold">100</span>; <span style="color: #333333">++</span>i)
  {
    i_colony.insert(i);
  }

  <span style="color: #888888">// Erase half of them:</span>
  <span style="color: #008800; font-weight: bold">for</span> (plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span><span style="color: #333333">&gt;::</span>iterator it <span style="color: #333333">=</span> i_colony.begin(); it <span style="color: #333333">!=</span> i_colony.end(); <span style="color: #333333">++</span>it)
  {
    it <span style="color: #333333">=</span> i_colony.erase(it);
  }

  <span style="color: #888888">// Total the remaining ints:</span>
  <span style="color: #333399; font-weight: bold">int</span> total <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>;

  <span style="color: #008800; font-weight: bold">for</span> (plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span><span style="color: #333333">&gt;::</span>iterator it <span style="color: #333333">=</span> i_colony.begin(); it <span style="color: #333333">!=</span> i_colony.end(); <span style="color: #333333">++</span>it)
  {
    total <span style="color: #333333">+=</span> <span style="color: #333333">*</span>it;
  }

  std<span style="color: #333333">::</span>cout <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">"Total: "</span> <span style="color: #333333">&lt;&lt;</span> total <span style="color: #333333">&lt;&lt;</span> std<span style="color: #333333">::</span>endl;
  std<span style="color: #333333">::</span>cin.get();
  <span style="color: #008800; font-weight: bold">return</span> <span style="color: #0000DD; font-weight: bold">0</span>;
} </code></pre>
</div>

<h4>Example demonstrating pointer stability</h4>

<div
style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;">
<pre style="margin: 0; line-height: 125%"><code><span style="color: #557799">#include &lt;iostream&gt;</span>
<span style="color: #557799">#include "plf_colony.h"</span>

<span style="color: #333399; font-weight: bold">int</span> <span style="color: #0066BB; font-weight: bold">main</span>(<span style="color: #333399; font-weight: bold">int</span> argc, <span style="color: #333399; font-weight: bold">char</span> <span style="color: #333333">**</span>argv)
{
  plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span><span style="color: #333333">&gt;</span> i_colony;
  plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span><span style="color: #333333">&gt;::</span>iterator it;
  plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span> <span style="color: #333333">*&gt;</span> p_colony;
  plf<span style="color: #333333">::</span>colony<span style="color: #333333">&lt;</span><span style="color: #333399; font-weight: bold">int</span> <span style="color: #333333">*&gt;::</span>iterator p_it;

  <span style="color: #888888">// Insert 100 ints to i_colony and pointers to those ints to p_colony:</span>
  <span style="color: #008800; font-weight: bold">for</span> (<span style="color: #333399; font-weight: bold">int</span> i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>; i <span style="color: #333333">!=</span> <span style="color: #0000DD; font-weight: bold">100</span>; <span style="color: #333333">++</span>i)
  {
    it <span style="color: #333333">=</span> i_colony.insert(i);
    p_colony.insert(<span style="color: #333333">&amp;</span>(<span style="color: #333333">*</span>it));
  }

  <span style="color: #888888">// Erase half of the ints:</span>
  <span style="color: #008800; font-weight: bold">for</span> (it <span style="color: #333333">=</span> i_colony.begin(); it <span style="color: #333333">!=</span> i_colony.end(); <span style="color: #333333">++</span>it)
  {
    it <span style="color: #333333">=</span> i_colony.erase(it);
  }

  <span style="color: #888888">// Erase half of the int pointers:</span>
  <span style="color: #008800; font-weight: bold">for</span> (p_it <span style="color: #333333">=</span> p_colony.begin(); p_it <span style="color: #333333">!=</span> p_colony.end(); <span style="color: #333333">++</span>p_it)
  {
    p_it <span style="color: #333333">=</span> p_colony.erase(p_it);
  }

  <span style="color: #888888">// Total the remaining ints via the pointer colony (pointers will still be valid even after insertions and erasures):</span>
  <span style="color: #333399; font-weight: bold">int</span> total <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>;

  <span style="color: #008800; font-weight: bold">for</span> (p_it <span style="color: #333333">=</span> p_colony.begin(); p_it <span style="color: #333333">!=</span> p_colony.end(); <span style="color: #333333">++</span>p_it)
  {
    total <span style="color: #333333">+=</span> <span style="color: #333333">*</span>(<span style="color: #333333">*</span>p_it);
  }

  std<span style="color: #333333">::</span>cout <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">"Total: "</span> <span style="color: #333333">&lt;&lt;</span> total <span style="color: #333333">&lt;&lt;</span> std<span style="color: #333333">::</span>endl;
  
  <span style="color: #008800; font-weight: bold">if</span> (total <span style="color: #333333">==</span> <span style="color: #0000DD; font-weight: bold">2500</span>)
  {
    std<span style="color: #333333">::</span>cout <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">"Pointers still valid!"</span> <span style="color: #333333">&lt;&lt;</span> std<span style="color: #333333">::</span>endl;
  }
  
  std<span style="color: #333333">::</span>cin.get();
  <span style="color: #008800; font-weight: bold">return</span> <span style="color: #0000DD; font-weight: bold">0</span>;
} </code></pre>
</div>

<h4>Iterator Invalidation</h4>

<table border="1">
  <tbody>
    <tr>
      <td>All read-only operations, swap, std::swap</td>
      <td>Never</td>
    </tr>
    <tr>
      <td>clear, reinitialize, operator = </td>
      <td>Always</td>
    </tr>
    <tr>
      <td>reserve, shrink_to_fit</td>
      <td>Only if capacity is changed</td>
    </tr>
    <tr>
      <td>change_group_sizes, change_minimum_group_size,
        change_maximum_group_size</td>
      <td>Only if supplied minimum group size is larger than smallest group in
        colony, or supplied maximum group size is smaller than largest group in
        colony.</td>
    </tr>
    <tr>
      <td>erase</td>
      <td>Only for the erased element</td>
    </tr>
    <tr>
      <td>insert, emplace</td>
      <td>If an iterator is == end() it may be invalidated by a subsequent
        insert/emplace in some cases. Otherwise no.</td>
    </tr>
  </tbody>
</table>

<h4>Member types</h4>

<table border="1">
  <tbody>
    <tr>
      <td><b>Member type</b></td>
      <td><b>Definition</b></td>
    </tr>
    <tr>
      <td><code>value_type</code></td>
      <td><code>T</code></td>
    </tr>
    <tr>
      <td><code>allocator_type</code></td>
      <td><code>Allocator</code></td>
    </tr>
    <tr>
      <td><code>size_type</code></td>
      <td><code>Allocator::size_type (pre-c++11)<br>
        std::allocator_traits&lt;Allocator&gt;::size_type
      (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>difference_type</code></td>
      <td><code>Allocator::difference_type (pre-c++11)<br>
        std::allocator_traits&lt;Allocator&gt;::difference_type
        (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>reference</code></td>
      <td><code>Allocator::reference (pre-c++11)<br>
        value_type &amp; (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>const_reference</code></td>
      <td><code>Allocator::const_reference (pre-c++11)<br>
        const value_type &amp; (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>pointer</code></td>
      <td><code>Allocator::pointer (pre-c++11)<br>
        value_type &amp; (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>const_pointer</code></td>
      <td><code>Allocator::const_pointer (pre-c++11)<br>
        std::allocator_traits&lt;Allocator&gt;::const_pointer
        (post-c++11)</code></td>
    </tr>
    <tr>
      <td><code>iterator</code></td>
      <td><code>BidirectionalIterator</code></td>
    </tr>
    <tr>
      <td><code>const_iterator</code></td>
      <td><code>Constant BidirectionalIterator</code></td>
    </tr>
    <tr>
      <td><code>reverse_iterator</code></td>
      <td><code>BidirectionalIterator</code></td>
    </tr>
    <tr>
      <td><code>const_reverse_iterator</code></td>
      <td><code>Constant BidirectionalIterator</code></td>
    </tr>
  </tbody>
</table>

<p>Iterators for a colony cannot be random access because any +, -, += and -=
operators would be non-O(1), due to the need to iterate over a skipfield.
However member overloads for the standard library functions advance(), next(),
prev() and distance() are available in the reference implementation. These are
significantly faster than O(n) in most cases.</p>

<h3>Constructors</h3>

<table border="1">
  <tbody>
    <tr>
      <td>default</td>
      <td><code>explicit colony(const allocator_type &amp;alloc =
        allocator_type())</code></td>
    </tr>
    <tr>
      <td>fill</td>
      <td><code>explicit colony(const size_type n, const unsigned short
        min_group_size = 8, const unsigned short max_group_size =
        std::numeric_limits&lt;Skipfield_type&gt;::max(), const allocator_type
        &amp;alloc = allocator_type())<br>
        explicit colony(const size_type n, const value_type &amp;element, const
        unsigned short min_group_size = 8, const unsigned short max_group_size
        = std::numeric_limits&lt;Skipfield_type&gt;::max(), const
        allocator_type &amp;alloc = allocator_type()) </code></td>
    </tr>
    <tr>
      <td>range</td>
      <td><code>template&lt;typename InputIterator&gt; colony(const
        InputIterator &amp;first, const InputIterator &amp;last, const unsigned
        short min_group_size = 8, const unsigned short max_group_size =
        std::numeric_limits&lt;Skipfield_type&gt;::max(), const allocator_type
        &amp;alloc = allocator_type())<br>
        </code></td>
    </tr>
    <tr>
      <td>copy</td>
      <td><code>colony(const colony &amp;source)</code></td>
    </tr>
    <tr>
      <td>move</td>
      <td><code>colony(colony &amp;&amp;source) noexcept <font size="2">(C++11
        and upwards)</font></code></td>
    </tr>
    <tr>
      <td>initializer list</td>
      <td><code>colony(const std::initializer_list&lt;value_type&gt;
        &amp;element_list, const unsigned short min_group_size = 8, const
        unsigned short max_group_size =
        std::numeric_limits&lt;Skipfield_type&gt;::max(), const allocator_type
        &amp;alloc = allocator_type()) </code></td>
    </tr>
  </tbody>
</table>

<h3>Member functions</h3>

<h4>Insert</h4>

<table border="1">
  <tbody>
    <tr>
      <td>single element</td>
      <td><code>iterator insert (const value_type &amp;val)</code></td>
    </tr>
    <tr>
      <td>fill</td>
      <td><code>iterator insert (const size_type n, const value_type
        &amp;val)</code></td>
    </tr>
    <tr>
      <td>range</td>
      <td><code>template &lt;class InputIterator&gt; iterator insert (const
        InputIterator &amp;first, const InputIterator &amp;last)</code></td>
    </tr>
    <tr>
      <td>move</td>
      <td><code>iterator insert (value_type&amp;&amp; val) <font
        size="2">(C++11 and upwards)</font></code></td>
    </tr>
    <tr>
      <td>initializer list</td>
      <td><code>iterator insert (const std::initializer_list&lt;value_type&gt;
        &amp;il)</code></td>
    </tr>
  </tbody>
</table>
<ul>
  <li><code>iterator insert(const value_type &amp;element)</code> 
    <p>Inserts the element supplied to the colony, using the object's
    copy-constructor. Will insert the element into a previously erased element
    slot if one exists, otherwise will insert to back of colony. Returns
    iterator to location of inserted element. Example:</p>
    <code style="color: brown">plf::colony&lt;unsigned int&gt; i_colony;<br>
    i_colony.insert(23);</code> </li>
  <li><code>iterator insert (const size_type n, const value_type
    &amp;val)</code> 
    <p>Inserts <code>n</code> copies of <code>val</code> into the colony. Will
    insert the element into a previously erased element slot if one exists,
    otherwise will insert to back of colony. Returns iterator to location of
    first inserted element. Example:</p>
    <code style="color: brown">plf::colony&lt;unsigned int&gt; i_colony;<br>
    i_colony.insert(10, 3);</code> </li>
  <li><code>template &lt;class InputIterator&gt; iterator insert (const
    InputIterator &amp;first, const InputIterator &amp;last)</code> 
    <p>Inserts a series of <code>value_type</code> elements from an external
    source into a colony holding the same <code>value_type</code> (eg. int,
    float, a particular class, etcetera). Stops inserting once it reaches
    <code>last</code>. Example:</p>
    <code style="color: brown">// Insert all contents of colony2 into
    colony1:<br>
    colony1.insert(colony2.begin(), colony2.end());</code> </li>
  <li><code>iterator insert(value_type &amp;&amp;element) <b>C++11 and
    upwards</b></code> 
    <p>Moves the element supplied to the colony, using the object's
    move-constructor. Will insert the element in a previously erased element
    slot if one exists, otherwise will insert to back of colony. Returns
    iterator to location of inserted element. Example:</p>
    <p><code style="color: brown">std::string string1 = "Some text";<br>
    <br>
    plf::colony&lt;std::string&gt; data_colony;<br>
    data_colony.insert(std::move(string1));</code></p>
  </li>
  <li><code>iterator insert (const std::initializer_list&lt;value_type&gt;
    &amp;il)</code> 
    <p>Moves the element supplied to the colony, using the object's
    move-constructor. Will insert the element in a previously erased element
    slot if one exists, otherwise will insert to back of colony. Returns
    iterator to location of inserted element. Example:</p>
    <p><code style="color: brown">std::initializer_list&lt;int&gt; some_ints =
    {4, 3, 2, 5};<br>
    <br>
    plf::colony&lt;int&gt; i_colony;<br>
    i_colony.insert(some_ints);</code></p>
  </li>
</ul>

<h4>Erase</h4>

<table border="1">
  <tbody>
    <tr>
      <td>single element</td>
      <td><code>iterator erase(const iterator &amp;it)</code></td>
    </tr>
    <tr>
      <td>range</td>
      <td><code>void erase(const iterator &amp;first, const iterator
        &amp;last)</code></td>
    </tr>
  </tbody>
</table>
<ul>
  <li><code>iterator erase(const iterator &amp;it)</code> 
    <p>Removes the element pointed to by the supplied iterator, from the
    colony. Returns an iterator pointing to the next non-erased element in the
    colony (or to end() if no more elements are available). This must return an
    iterator because if a colony group becomes entirely empty, it will be
    removed from the colony, invalidating the existing iterator. Attempting to
    erase a previously-erased element results in undefined behaviour (this is
    checked for via an assert in debug mode). Example:</p>
    <code style="color: brown">plf::colony&lt;unsigned int&gt;
    data_colony(50);<br>
    plf::colony&lt;unsigned int&gt;::iterator an_iterator;<br>
    an_iterator = data_colony.insert(23);<br>
    an_iterator = data_colony.erase(an_iterator);</code> </li>
  <li><code>void erase(const iterator &amp;first, const iterator
    &amp;last)</code> 
    <p>Erases all contents of a given colony from <code>first</code> to the
    element before the <code>last</code> iterator. Example:</p>
    <code style="color: brown">plf::colony&lt;int&gt; iterator1 =
    colony1.begin();<br>
    colony1.advance(iterator1, 10);<br>
    plf::colony&lt;int&gt; iterator2 = colony1.begin();<br>
    colony1.advance(iterator2, 20);<br>
    colony1.erase(iterator1, iterator2);</code> </li>
</ul>

<h4>Other functions</h4>
<ul>
  <li><code>iterator emplace(Arguments ...parameters) <b>C++11 and
    upwards</b></code> 
    <p>Constructs new element directly within colony. Will insert the element
    in a previously erased element slot if one exists, otherwise will insert to
    back of colony. Returns iterator to location of inserted element.
    "...parameters" are whatever parameters are required by the object's
    constructor. Example:</p>
    <p><code style="color: brown">class simple_class<br>
    {<br>
    private:<br>
    int number;<br>
    public:<br>
    simple_class(int a_number): number (a_number) {};<br>
    };<br>
    <br>
    plf::colony&lt;simple_class&gt; simple_classes;<br>
    simple_classes.emplace(45); </code> </p>
  </li>
  <li><code>bool empty()</code> 
    <p>Returns a boolean indicating whether the colony is currently empty of
    elements.<br>
    Example: <code style="color: brown">if (object_colony.empty())
    return;</code></p>
  </li>
  <li><code>size_type size()</code> 
    <p>Returns total number of elements currently stored in container.<br>
    Example: <code style="color: brown">std::cout &lt;&lt; i_colony.size()
    &lt;&lt; std::endl;</code></p>
  </li>
  <li><code>size_type max_size()</code> 
    <p>Returns the maximum number of elements that the allocator can store in
    the container. This is an approximation as it does attempt to measure the
    memory overhead of the container's internal memory structures. It is not
    possible to measure the latter because a copy operation may change the
    number of groups utilized for the same amount of elements, if the maximum
    or minimum group sizes are different in the source container.<br>
    Example: <code style="color: brown">std::cout &lt;&lt; i_colony.max_size()
    &lt;&lt; std::endl;</code></p>
  </li>
  <li><code>size_type capacity()</code> 
    <p>Returns total number of elements currently able to be stored in
    container without expansion.<br>
    Example: <code style="color: brown">std::cout &lt;&lt; i_colony.capacity()
    &lt;&lt; std::endl;</code></p>
  </li>
  <li><code>void shrink_to_fit()</code> 
    <p>Reduces container capacity to the amount necessary to store all
    currently stored elements. If the total number of elements is larger than
    the maximum group size, the resultant capacity will be equal to
    <code>((total_elements / max_group_size) + 1) * max_group_size</code>
    (rounding down at division). Invalidates all pointers, iterators and
    references to elements within the container.<br>
    Example: <code style="color: brown">i_colony.shrink_to_fit();</code></p>
  </li>
  <li><code>void reserve(unsigned short reserve_amount)</code> 
    <p>Preallocates memory space sufficient to store the number of elements
    indicated by <code>reserve_amount</code>. The maximum size for this number
    is limited to the maximum group size of the colony and will be truncated if
    necessary. The default maximum group size is 65535 on the majority of
    platforms.<br>
    Example: <code style="color: brown">i_colony.reserve(15);</code></p>
  </li>
  <li><code>void clear()</code> 
    <p>Empties the colony and removes all elements and groups.<br>
    Example: <code style="color: brown">object_colony.clear();</code></p>
  </li>
  <li><code>void change_group_sizes(const unsigned short min_group_size, const
    unsigned short max_group_size)</code> 
    <p>Changes the minimum and maximum internal group sizes, in terms of number
    of elements stored per group. If the colony is not empty and either
    min_group_size is larger than the smallest group in the colony, or
    max_group_size is smaller than the largest group in the colony, the colony
    will be internally copy-constructed into a new colony which uses the new
    group sizes, invalidating all pointers/iterators/references.<br>
    Example: <code style="color: brown">object_colony.change_group_sizes(1000,
    10000);</code></p>
  </li>
  <li><code>void change_minimum_group_size(const unsigned short
    min_group_size)</code> 
    <p>Changes the minimum internal group size only, in terms of minimum number
    of elements stored per group. If the colony is not empty and min_group_size
    is larger than the smallest group in the colony, the colony will be
    internally copy-constructed into a new colony which uses the new minimum
    group size, invalidating all pointers/iterators/references.<br>
    Example: <code
    style="color: brown">object_colony.change_minimum_group_size(100);</code></p>
  </li>
  <li><code>void change_maximum_group_size(const unsigned short
    min_group_size)</code> 
    <p>Changes the maximum internal group size only, in terms of maximum number
    of elements stored per group. If the colony is not empty and either
    max_group_size is smaller than the largest group in the colony, the colony
    will be internally copy-constructed into a new colony which uses the new
    maximum group size, invalidating all pointers/iterators/references.<br>
    Example: <code
    style="color: brown">object_colony.change_maximum_group_size(1000);</code></p>
  </li>
  <li><code>void reinitialize(const unsigned short min_group_size, const
    unsigned short max_group_size)</code> 
    <p>Semantics of function are the same as "clear();
    change_group_sizes(min_group_size, max_group_size);", but without the
    copy-construction code of the change_group_sizes() function - this means it
    can be used with element types which are non-copy-constructible, unlike
    change_group_sizes().<br>
    Example: <code style="color: brown">object_colony.reinitialize(1000,
    10000);</code></p>
  </li>
  <li><code>void swap(colony &amp;source)</code> 
    <p>Swaps the colony's contents with that of <code>source</code>.<br>
    Example: <code
    style="color: brown">object_colony.swap(other_colony);</code></p>
  </li>
  <li><code>friend void swap(colony &amp;A, source &amp;B)</code> 
    <p>External friend function, swaps the colony A's contents with that of
    colony B (assumes both stacks have same element type).<br>
    Example: <code style="color: brown">swap(object_colony,
    other_colony);</code></p>
  </li>
  <li><code>colony &amp; operator = (const colony &amp;source)</code> 
    <p>Copy the elements from another colony to this colony, clearing this
    colony of existing elements first.<br>
    Example: <code style="color: brown">// Manually swap data_colony1 and
    data_colony2 in C++03<br>
    data_colony3 = data_colony1;<br>
    data_colony1 = data_colony2;<br>
    data_colony2 = data_colony3;</code></p>
  </li>
  <li><code>colony &amp; operator = (const colony &amp;&amp;source) <b>C++11
    only</b></code> 
    <p>Move the elements from another colony to this colony, clearing this
    colony of existing elements first. Source colony becomes invalid but can be
    safely destructed without undefined behaviour.<br>
    Example: <code style="color: brown">// Manually swap data_colony1 and
    data_colony2 in C++11<br>
    data_colony3 = std::move(data_colony1);<br>
    data_colony1 = std::move(data_colony2);<br>
    data_colony2 = std::move(data_colony3);</code></p>
  </li>
  <li><code>bool operator == (const colony &amp;source)</code> 
    <p>Compare contents of another colony to this colony. Returns a boolean as
    to whether they are equal.<br>
    Example: <code style="color: brown">if (object_colony == object_colony2)
    return;</code></p>
  </li>
  <li><code>bool operator != (const colony &amp;source)</code> 
    <p>Compare contents of another colony to this colony. Returns a boolean as
    to whether they are not equal.<br>
    Example: <code style="color: brown">if (object_colony != object_colony2)
    return;</code></p>
  </li>
  <li><code>iterator begin(), iterator end(), const_iterator cbegin(),
    const_iterator cend()</code> 
    <p>Return iterators pointing to, respectively, the first element of the
    colony and the element one-past the end of the colony (as per standard STL
    guidelines).</p>
  </li>
  <li><code>reverse_iterator rbegin(), reverse_iterator rend(),
    const_reverse_iterator cbegin(), const_reverse_iterator cend()</code> 
    <p>Return reverse iterators pointing to, respectively, the last element of
    the colony and the element one-before the first element of the colony (as
    per standard STL guidelines).</p>
  </li>
  <li><code>iterator get_iterator_from_pointer(const element_pointer_type
    the_pointer) <b>(slow)</b></code> 
    <p>Getting a pointer from an iterator is simple - simply dereference it
    then grab the address ie. <code>"&amp;(*the_iterator);"</code>. Getting an
    iterator from a pointer is typically not so simple. This function enables
    the user to do exactly that. This is expected to be useful in the use-case
    where external containers are storing pointers to colony elements instead
    of iterators (as iterators have 3 times the size of an element pointer) and
    the program wants to erase the element being pointed to or possibly change
    the element being pointed to. Converting a pointer to an iterator using
    this method and then erasing, is about 20% slower on average than erasing
    when you already have the iterator. This is less dramatic than it sounds,
    as it is still faster than all std:: container erasure times except
    std::list, which it is roughly equal to. However this is generally a
    slower, lookup-based operation. If the lookup doesn't find a non-erased
    element based on that pointer, it returns <code>end()</code>. Otherwise it
    returns an iterator pointing to the element in question. Example:</p>
    <p><code style="color: brown">plf::colony&lt;a_struct&gt; data_colony;<br>
    plf::colony&lt;a_struct&gt;::iterator an_iterator;<br>
    a_struct struct_instance;<br>
    an_iterator = data_colony.insert(struct_instance);<br>
    a_struct *struct_pointer = &amp;(*an_iterator);<br>
    iterator another_iterator =
    data_colony.get_iterator_from_pointer(struct_pointer);<br>
    if (an_iterator == another_iterator) std::cout &lt;&lt; "Iterator is
    correct" &lt;&lt; std::endl;</code> </p>
  </li>
  <li><code>size_type get_index_from_iterator(const iterator/const_iterator
    &amp;the_iterator) <b>(slow)</b></code> 
    <p>While colony is a container with unordered insertion (and is therefore
    unordered), it still has a (transitory) order which changes frequently upon
    erasure and insertion. <i>Temporary</i> index numbers are therefore
    obtainable. These can be useful, for example, when creating a save file in
    a computer game, where certain elements in a container may need to be
    re-linked to other elements in other container upon reloading the save
    file. Example:</p>
    <p><code style="color: brown">plf::colony&lt;a_struct&gt; data_colony;<br>
    plf::colony&lt;a_struct&gt;::iterator an_iterator;<br>
    a_struct struct_instance;<br>
    data_colony.insert(struct_instance);<br>
    data_colony.insert(struct_instance);<br>
    an_iterator = data_colony.insert(struct_instance);<br>
    unsigned int index = data_colony.get_index_from_iterator(an_iterator);<br>
    if (index == 2) std::cout &lt;&lt; "Index is correct" &lt;&lt;
    std::endl;</code> </p>
  </li>
  <li><code>size_type get_index_from_reverse_iterator(const
    reverse_iterator/const_reverse_iterator &amp;the_iterator)
    <b>(slow)</b></code> 
    <p>The same as get_index_from_iterator, but for reverse_iterators and
    const_reverse_iterators. Index is from front of colony (same as iterator),
    not back of colony. Example:</p>
    <p><code style="color: brown">plf::colony&lt;a_struct&gt; data_colony;<br>
    plf::colony&lt;a_struct&gt;::reverse_iterator r_iterator;<br>
    a_struct struct_instance;<br>
    data_colony.insert(struct_instance);<br>
    data_colony.insert(struct_instance);<br>
    r_iterator = data_colony.rend();<br>
    unsigned int index =
    data_colony.get_index_from_reverse_iterator(r_iterator);<br>
    if (index == 1) std::cout &lt;&lt; "Index is correct" &lt;&lt;
    std::endl;</code> </p>
  </li>
  <li><code>iterator get_iterator_from_index(const size_type index)
    <b>(slow)</b></code> 
    <p>As described above, there may be situations where obtaining iterators to
    specific elements based on an index can be useful, for example, when
    reloading save files. This function is basically a shorthand to avoid
    typing <code>"iterator it = colony.begin(); colony.advance(it,
    50);"</code>. Example:</p>
    <p><code style="color: brown">plf::colony&lt;a_struct&gt; data_colony;<br>
    plf::colony&lt;a_struct&gt;::iterator an_iterator;<br>
    a_struct struct_instance;<br>
    data_colony.insert(struct_instance);<br>
    data_colony.insert(struct_instance);<br>
    iterator an_iterator = data_colony.insert(struct_instance);<br>
    iterator another_iterator = data_colony.get_iterator_from_index(2);<br>
    if (an_iterator == another_iterator) std::cout &lt;&lt; "Iterator is
    correct" &lt;&lt; std::endl;</code> </p>
  </li>
</ul>
<!-- <h3>Non-member functions</h3> -->
<ul>
  <li><code>template &lt;iterator_type&gt; void advance(iterator_type iterator,
    distance_type distance)</code> 
    <p>Increments/decrements the iterator supplied by the positive or negative
    amount indicated by <i>distance</i>. Speed of incrementation will almost
    always be faster than using the ++ operator on the iterator for increments
    greater than 1. In some cases it may approximate O(1). The iterator_type
    can be an iterator, const_iterator, reverse_iterator or
    const_reverse_iterator.<br>
    Example: <code style="color: brown">colony&lt;int&gt;::iterator it =
    i_colony.begin();<br>
    i_colony.advance(it, 20); </code></p>
  </li>
  <li><code>template &lt;iterator_type&gt; iterator_type next(const
    iterator_type &amp;iterator, distance_type distance)</code> 
    <p>Creates a copy of the iterator supplied, then increments/decrements this
    iterator by the positive or negative amount indicated by
    <i>distance</i>.<br>
    Example: <code style="color: brown">colony&lt;int&gt;::iterator it =
    i_colony.next(i_colony.begin(), 20);</code></p>
  </li>
  <li><code>template &lt;iterator_type&gt; iterator_type prev(const
    iterator_type &amp;iterator, distance_type distance)</code> 
    <p>Creates a copy of the iterator supplied, then decrements/increments this
    iterator by the positive or negative amount indicated by
    <i>distance</i>.<br>
    Example: <code style="color: brown">colony&lt;int&gt;::iterator it2 =
    i_colony.prev(i_colony.end(), 20);</code></p>
  </li>
  <li><code>template &lt;iterator_type&gt; difference_type distance(const
    iterator_type &amp;first, const iterator_type &amp;last)</code> 
    <p>Measures the distance between two iterators, returning the result, which
    will be negative if the second iterator supplied is before the first
    iterator supplied in terms of it's location in the colony.<br>
    Example: <code style="color: brown">colony&lt;int&gt;::iterator it =
    i_colony.next(i_colony.begin(), 20);<br>
    colony&lt;int&gt;::iterator it2 = i_colony.prev(i_colony.end(), 20);<br>
    std::cout "Distance: " i_colony.distance(it, it2) std::endl;</code></p>
  </li>
</ul>

<p>The full implementation details for the main three aspects of the reference
implementation are too large to be included in this document, but are available
externally below:<br>
<br>
Details on the chained-group allocation pattern are here: <a
href="http://www.plflib.org/chained_group_allocation_pattern.htm">http://www.plflib.org/chained_group_allocation_pattern.htm</a>.<br>
The 8900-word paper on the jump-counting skipfield pattern is available here:
<a
href="http://www.plflib.org/the_jump_counting_skipfield_pattern.pdf">http://www.plflib.org/the_jump_counting_skipfield_pattern.pdf</a>,
and benchmarks versus boolean skipfields are presented here: <a
href="http://www.plflib.org/skipfield_comparison.htm">http://www.plflib.org/skipfield_comparison.htm</a>.<br>
Lastly, plf::stack (on which the reference implementation's internal reduced
stack implementation is based) is explained in detail here: <a
href="http://www.plflib.org/stack.htm">http://www.plflib.org/stack.htm</a>.</p>

<p>Further details on colony's reference implementation can be found here: <a
href="http://www.plflib.org/colony.htm">http://www.plflib.org/colony.htm</a>,
including a FAQ.<br>
The reference implementation of colony is available to download here: <a
href="http://www.plflib.org/colony.htm#download">http://www.plflib.org/colony.htm#download</a>
or via the github repository: <a
href="https://github.com/mattreecebentley/plf_colony">https://github.com/mattreecebentley/plf_colony</a>.</p>

<h2>VI. Acknowledgements</h2>

<p>Thanks to Glen Fernandes and Ion Gaztanaga for restructuring advice, Robert
Ramey for documentation advice, various Boost and SG14 members for support,
suggestions and bug reports including Sean Middleditch, Patrice Roy and Guy
Davidson. And that jerk from Lionhead for annoying me enough to force me to
finally implement the jump-counting skipfield pattern. Lastly, thanks to Jon
Blow for initial advice and Mike Acton for some positive influence.</p>

<h2>VII. References</h2>

<h3><a id="#benchmarks"></a>plf::colony benchmarks</h3>

<p>As the benchmarks currently need to be updated prior to Issaquah to
reflect the performance updates to the reference implementation over the
past six months, only links can be provided at this stage:<br>
Benchmarks for GCC can be found here: <a
href="http://www.plflib.org/colony.htm#benchmarks">http://www.plflib.org/colony.htm#benchmarks</a>,
while benchmarks for MSVC can be found here: <a
href="http://www.plflib.org/colony_benchmark_msvc_results.htm">http://www.plflib.org/colony_benchmark_msvc_results.htm</a></p>

<h3>Cppcon 2016 Talk</h3>

<p>An explanatory talk about Colony and the various approaches
involved was given at Cppcon 2016 in Bellevue, Seattle:<br>
<iframe width="560" height="315"
src="https://www.youtube.com/embed/wBER1R8YyGY" frameborder="0">
</iframe>
</p>

<p>Note that the benchmarks presented in this lecture do not reflect
current colony performance, which has improved considerably since.</p>

<p>The slides for the talk are available <a
href="http://www.mediafire.com/download/xf8zk9c16efsp66/Colonies%2C+performance+and+why+you+should+Care+-+cppcon+2016.pdf">here</a>.
</p>
</body>
</html>
