Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
Builder to create and populate instances of the lib::Several container.
For mere usage, inclusion of several.hpp should be sufficient, since the container front-end is generic and intends to hide most details of allocation and element placement. It is an array-like container, but may hold subclass elements, while exposing only a reference to the interface type.
The front-end container lib::Several<I> is actually just a smart-ptr referring to the actual data storage, which resides within an array bucket. Typically the latter is placed into memory managed by a custom allocator, most notably lib::AllocationCluster. However, by default, the ArrayBucket will be placed into heap memory. All further meta information is also maintained alongside this data allocation, including a deleter function to invoke all element destructors and de-allocate the bucket itself. Neither the type of the actual elements, nor the type of the allocator is revealed.
Since the actual data elements can (optionally) be of a different type than the exposed interface type I, additional storage and spacing is required in the element array. The field ArrayBucket<I>::spread defines this spacing and thus the offset used for subscript access. The actual data storage starts immediately behind the ArrayBucket, which thus acts as a metadata header. This arrangement requires a sufficiently sized raw memory allocation to place the ArrayBucket and the actual data into. Moreover, the allocation code in ElementFactory::create() is responsible to ensure proper alignment of the data storage, especially when the payload data type has alignment requirements beyond alignof(void*)
, which is typically used by the standard heap allocator; additional headroom is added proactively in this case, to be able to shift the storage buffer ahead to the next alignment boundary.
The ability to emplace a mixture of data types into the storage exposed through the lib::Several front-end creates some complexities related to element handling. The implementation uses generic rules and criteria based approach to decide on a case by case base if some given data content is still acceptable. This allows for rather tricky low-level usages, but has the downside to detect errors only at runtime — which in this case is ameliorated by the limitation that elements must be provided completely up-front, through the SeveralBuilder.
<type_traits>
libraryreserve()
from the builder API)std::memmove()
in this case.Definition in file several-builder.hpp.
#include "lib/error.hpp"
#include "lib/several.hpp"
#include "include/limits.hpp"
#include "lib/iter-explorer.hpp"
#include "lib/format-string.hpp"
#include "lib/util.hpp"
#include <type_traits>
#include <functional>
#include <cstring>
#include <utility>
#include <vector>
Classes | |
struct | AllocationPolicy< I, E, ALO > |
Policy Mix-In used to adapt to the ElementFactory and Allocator. More... | |
class | ElementFactory< I, ALO > |
Generic factory to manage objects within an ArrayBucket storage, delegating to a custom allocator ALO for memory handling. More... | |
struct | SetupSeveral< ALO, ALO< X > >::Policy< I, E > |
struct | SetupSeveral< ALO, ARGS > |
Extension point: how to configure the SeveralBuilder to use an allocator ALO, initialised by ARGS. More... | |
struct | SetupSeveral< ALO > |
Specialisation: use a monostate allocator type ALO. More... | |
struct | SetupSeveral< ALO, ALO< X > > |
Specialisation: store a C++ standard allocator instance, which can be used to allocate objects of type X. More... | |
class | SeveralBuilder< I, E, POL > |
Builder to create and populate a lib::Several<I>. More... | |
Typedefs | |
template<class I , class E > | |
using | HeapOwn = AllocationPolicy< I, E, std::allocator > |
Default configuration to use heap memory for lib::Several. | |
Functions | |
size_t constexpr | alignRes (size_t alignment) |
determine size of a reserve buffer to place with proper alignment | |
template<typename I , typename E = I> | |
SeveralBuilder< I, E > | makeSeveral () |
Entrance Point: start building a lib::Several instance. More... | |
template<typename X > | |
SeveralBuilder< X > | makeSeveral (std::initializer_list< X > ili) |
template<typename TY > | |
size_t constexpr | reqSiz () |
Helper to determine the »spread« required to hold elements of type TY in memory with proper alignment. | |
Variables | |
const uint | INITIAL_ELM_CNT = 10 |
number of storage slots to open initially; starting with an over-allocation similar to std::vector | |
Namespaces | |
lib | |
Implementation namespace for support and library code. | |