![]() |
Lumiera 0.pre.04~rc.1
»edit your freedom«
|
Builder to create and populate instances of the lib::Several container. More...
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<I> 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.notably, lib::AllocationCluster has the ability to dynamically adapt an allocation, but only if this happens to be currently the last allocation handed out; it can thus be arranged even for an unknown number of non-copyable objects to be emplaced when creating the suitable operational conditions. A key point to note is the fact that the container does not capture and store the actual data types persistently. Thus, the above rules must be applied in a way to always ensure safe handling of the contained data. Typically, the first element actually added will »prime« the container for a certain usage style, and after that, some other usage patterns may be rejected.
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/meta/trait.hpp"#include "lib/util.hpp"#include <functional>#include <cstring>#include <utility>#include <vector>Namespaces | |
| namespace | lib |
| Implementation namespace for support and library code. | |
| namespace | lib::anonymous_namespace{several-builder.hpp} |
| namespace | lib::allo |
Typedefs | |
| template<class I , class E > | |
| using | HeapOwn = AllocationPolicy< I, E, std::allocator > |
| Default configuration to use heap memory for lib::Several. | |
Classes | |
| class | ElementFactory< I, ALO > |
Generic factory to manage objects within an ArrayBucket<I> storage, delegating to a custom allocator ALO for memory handling. More... | |
| struct | AllocationPolicy< I, E, ALO > |
| Policy Mix-In used to adapt to the ElementFactory and Allocator. More... | |
| class | SeveralBuilder< I, E, POL > |
Builder to create and populate a lib::Several<I>. 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... | |
| struct | SetupSeveral< ALO, ALO< X > >::Policy< I, E > |
Functions | |
| template<typename TY > | |
| constexpr size_t | reqSiz () |
| Helper to determine the »spread« required to hold elements of type TY in memory with proper alignment. | |
| constexpr size_t | 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. | |
| template<typename X > | |
| SeveralBuilder< X > | makeSeveral (std::initializer_list< X > ili) |
Variables | |
| const uint | INITIAL_ELM_CNT = 10 |
number of storage slots to open initially; starting with an over-allocation similar to std::vector | |
| struct lib::allo::SetupSeveral< ALO > |
| Class Members | ||
|---|---|---|
| typedef AllocationPolicy< I, E, ALO > | Policy | |
Collaboration diagram for SetupSeveral< ALO >:| struct lib::allo::SetupSeveral< ALO, ALO< X > > |
Collaboration diagram for SetupSeveral< ALO, ALO< X > >: