Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
A raw memory block with proper alignment and array access.
This is a building block for custom containers and memory management schemes. Regular containers in C++ always ensure invocation of any object's constructors and destructors – which is a boon and prevents a lot of consistency problems. When constructing custom management schemes however, this automatic initialisation can be problematic; some objects require constructor arguments, preventing mass initialisation; and initialising a large memory block has considerable cost, which may be wasted it the intended usage is to plant objects into that space later, on demand. The std::vector::reserve(size) function can often be used to circumvent those problems — yet unfortunately std::vector has the hard requirement on the content objects to be at least movable to support automatic storage growth.
A traditional workaround is to exploit a programming trick relying on a forced cast: Storage is declared as char[]
without initialiser; since char
is a primitive type, C++ will not default-initialise the storage then for sake of plain-old-C compatibility. A special accessor function will then force-cast into the desired target type. However well established, this practice is riddled with various problems
const
data fields are placed into such a buffer, the compiler may perform constant folding based on the current/initial object values and thus fail to propagate changes due to other object instances being placed into storage.Attempts were made to codify this kind of usage properly into the standard; these turned out to be problematic however and were deprecated again. Starting with C++17, fortunately there is now a way to express this kind of raw unprotected access through standard conformant ways and marked clearly to prevent overly zealous optimisation. Since the typical use is for allocating a series of storage slots with a well defined target type, this implementation relies on std::array as »front-end« for access.
T
and size are given as template parametersstd::byte
to express its very purposestd::launder
to prevent optimisationDefinition in file uninitialised-storage.hpp.
#include <cstddef>
#include <utility>
#include <array>
#include <new>
Classes | |
class | UninitialisedDynBlock< T > |
Managed uninitialised Heap-allocated storage with array like access. More... | |
class | UninitialisedStorage< T, cnt > |
Block of raw uninitialised storage with array like access. More... | |
Namespaces | |
lib | |
Implementation namespace for support and library code. | |