AbstractStorage class new in Git master
#include <Magnum/Ui/DataLayer.h>
Base for DataLayer storage implementations.
Types derived from this class are used as non-owning proxies that allocate arbitrarily typed storage memory in DataLayer and maintain access to it.
As this class is just a proxy with the storage being elsewhere, subclasses are expected to be trivially copyable without any additional member variables — all state is meant to be placed in the storage memory itself.
Public types
-
enum (anonymous): std::
size_t { MaxInPlaceSize = Implementation::DataLayerStorageMaxInPlaceSize }
Constructors, destructors, conversion operators
- operator StorageHandle() const
- Storage handle.
- AbstractStorage(DataLayer& layer, StorageFlags flags = {}) protected explicit
- Create a single-item storage.
-
AbstractStorage(DataLayer& layer,
std::
size_t size, StorageFlags flags = {}) protected explicit - Create a 1D storage.
-
AbstractStorage(DataLayer& layer,
const Containers::
Size2D& size, StorageFlags flags = {}) protected explicit - Create a 2D storage.
-
AbstractStorage(DataLayer& layer,
const Containers::
Size3D& size, StorageFlags flags = {}) protected explicit - Create a 3D storage.
Public functions
- auto layer() const -> DataLayer&
- Data layer reference.
- auto handle() const -> StorageHandle
- Storage handle.
- auto isAllocated() const -> bool
- Whether the storage is allocated.
- auto isDirty() const -> bool
- Whether the storage is dirty.
- void setDirty() const
- Mark the storage as dirty.
- auto flags() const -> StorageFlags
- Storage flags.
-
auto size() const -> Containers::
Size3D - Storage size.
-
auto referenceCount() const -> std::
size_t - Storage reference count.
Protected functions
-
template<class T>auto createInPlace() -> T*
- Create a storage in-place.
-
void createAllocated(void* data,
std::
size_t size, void(*)(void*, std:: size_t) deleter) - Create an allocated storage.
-
template<class T>auto data() const -> T*
- Storage data.
Enum documentation
enum Magnum:: Ui:: AbstractStorage:: (anonymous): std:: size_t
| Enumerators | |
|---|---|
| MaxInPlaceSize |
Maximal size that can be stored in-place. Storages larger than this size have to be allocated. See createInPlace() and createAllocated() for more information. |
Function documentation
Magnum:: Ui:: AbstractStorage:: AbstractStorage(DataLayer& layer,
StorageFlags flags = {}) explicit protected
Create a single-item storage.
| Parameters | |
|---|---|
| layer | Data layer reference |
| flags | Storage flags |
Equivalent to calling AbstractStorage(DataLayer&, const Containers::size being {1, 1, 1}. See its documentation for a detailed description of all constraints.
Magnum:: Ui:: AbstractStorage:: AbstractStorage(DataLayer& layer,
std:: size_t size,
StorageFlags flags = {}) explicit protected
Create a 1D storage.
| Parameters | |
|---|---|
| layer | Data layer reference |
| size | Storage size |
| flags | Storage flags |
Equivalent to calling AbstractStorage(DataLayer&, const Containers::size being {1, 1, size}. See its documentation for a detailed description of all constraints.
Magnum:: Ui:: AbstractStorage:: AbstractStorage(DataLayer& layer,
const Containers:: Size2D& size,
StorageFlags flags = {}) explicit protected
Create a 2D storage.
| Parameters | |
|---|---|
| layer | Data layer reference |
| size | Storage size |
| flags | Storage flags |
Equivalent to calling AbstractStorage(DataLayer&, const Containers::size being {1, size[0], size[1]}. See its documentation for a detailed description of all constraints.
Magnum:: Ui:: AbstractStorage:: AbstractStorage(DataLayer& layer,
const Containers:: Size3D& size,
StorageFlags flags = {}) explicit protected
Create a 3D storage.
| Parameters | |
|---|---|
| layer | Data layer reference |
| size | Storage size |
| flags | Storage flags |
Allocates a new StorageHandle in a free slot in the internal DataLayer storage storage or grows the storage if there's no free slots left. Expects that there's at most 1048576 storages. The AbstractStorage instance doesn't own the storage on and thus doesn't remove it on destruction, instead either the handle() can be removed again with DataLayer::
The size is expected to not be 0 in any dimension and its product to be less or equal to 1ull << 43. The subclass is meant to subsequently call createInPlace() or createAllocated() to actually initialize the storage. Calling neither is equivalent to calling createInPlace() and not initializing the memory it returns in any way. If StorageFlag::flags, the storage has to get used by at least one data before the next call to AbstractUserInterface::
Upon creation, isDirty() const returns false. Including StorageFlag::flags causes LayerState::
StorageHandle Magnum:: Ui:: AbstractStorage:: handle() const
Storage handle.
Guaranteed to be associated with layer() and never StorageHandle::
bool Magnum:: Ui:: AbstractStorage:: isAllocated() const
Whether the storage is allocated.
Same as calling DataLayer::
bool Magnum:: Ui:: AbstractStorage:: isDirty() const
Whether the storage is dirty.
Same as calling DataLayer::
void Magnum:: Ui:: AbstractStorage:: setDirty() const
Mark the storage as dirty.
Same as calling DataLayer::
StorageFlags Magnum:: Ui:: AbstractStorage:: flags() const
Storage flags.
Same as calling DataLayer::
Containers:: Size3D Magnum:: Ui:: AbstractStorage:: size() const
Storage size.
Same as calling DataLayer::
std:: size_t Magnum:: Ui:: AbstractStorage:: referenceCount() const
Storage reference count.
Same as calling DataLayer::
template<class T>
T* Magnum:: Ui:: AbstractStorage:: createInPlace() protected
Create a storage in-place.
Contrary to what Doxygen shows, returns reference to a one-dimensional fixed-size array of elements, i.e. T(&)[MaxInPlaceSize/sizeof(T)]. There the caller is expected to initialize a storage of a size specified in the AbstractStorage() constructor. Expects that T is a trivially copyable type not larger than MaxInPlaceSize and with alignment of at most 8. If it's larger, overaligned or not trivial, use createAllocated() instead. If the in-place storage can stay being uninitialized memory, this function doesn't need to be called at all.
void Magnum:: Ui:: AbstractStorage:: createAllocated(void* data,
std:: size_t size,
void(*)(void*, std:: size_t) deleter) protected
Create an allocated storage.
| Parameters | |
|---|---|
| data | Pointer to the allocated data |
| size | Size of the allocated data in bytes |
| deleter | Deleter |
When the storage is removed, deleter gets called with data and size passed to it. The data and deleter are expected to not be nullptr, size can be zero if the deleter doesn't require it. If the type is trivially copyable, aligned to at most 8 bytes and not larger than MaxInPlaceSize, you can store it in place using createInPlace() and avoid the allocation. It's not a requirement however.
template<class T>
T* Magnum:: Ui:: AbstractStorage:: data() const protected
Storage data.
Returns a pointer to either the storage passed to createAllocated() or to the in-place storage returned by createInPlace(). It's the subclass responsibility to ensure T matches the actually stored type.
In order to have updates properly reflected to all data referencing the storage, the subclass implementation should call setDirty() if it modifies anything in the storage. There's no way for the AbstractStorage implementation to detect this on its own, especially considering the storage may be just a view on memory managed elsewhere.