doc: added a note about configurable alignment requirements for any and poly

This commit is contained in:
Michele Caini
2021-03-22 15:14:19 +01:00
parent 44fa466618
commit a936f7cdbe
2 changed files with 39 additions and 14 deletions

View File

@@ -15,6 +15,7 @@
* [Monostate](#monostate)
* [Any as in any type](#any-as-in-any-type)
* [Small buffer optimization](#small-buffer-optimization)
* [Alignment requirement](#alignment-requirement)
* [Type support](#type-support)
* [Type info](#type-info)
* [Almost unique identifiers](#almost-unique-identifiers)
@@ -319,18 +320,41 @@ The `any` class uses a technique called _small buffer optimization_ to reduce
the number of allocations where possible.<br/>
The default reserved size for an instance of `any` is `sizeof(double[2])`.
However, this is also configurable if needed. In fact, `any` is defined as an
alias for `basic_any<Len>`, where `Len` is just the size above.<br/>
Users can easily use a custom size or define their own alias:
alias for `basic_any<Len>`, where `Len` is the size above.<br/>
Users can easily set a custom size or define their own aliases:
```cpp
using my_any = entt::basic_any<sizeof(double[4])>;
```
This feature, in addition to allowing the choice of a size that best suits the
needs of an application, also reserves the possibility of forcing dynamic
creation of objects during construction.<br/>
In fact, if the size is 0, `any` will avoid the use of any optimization, in fact
always dynamically allocating objects (except for aliasing cases).
needs of an application, also offers the possibility of forcing dynamic creation
of objects during construction.<br/>
In other terms, if the size is 0, `any` avoids the use of any optimization and
always dynamically allocates objects (except for aliasing cases).
Note that the size of the internal storage as well as the alignment requirements
are directly part of the type and therefore contribute to define different types
that won't be able to interoperate with each other.
## Alignment requirement
The alignment requirement is optional and by default the most stringent (the
largest) for any object whose size is at most equal to the one provided.<br/>
The `basic_any` class template inspects the alignment requirements in each case,
even when not provided and may decide not to use the small buffer optimization
in order to meet them.
The alignment requirement is provided as an optional second parameter following
the desired size for the internal storage:
```cpp
using my_any = entt::basic_any<sizeof(double[4]), alignof(double[4])>;
```
Note that the alignment requirements as well as the size of the internal storage
are directly part of the type and therefore contribute to define different types
that won't be able to interoperate with each other.
# Type support

View File

@@ -13,7 +13,7 @@
* [Fullfill a concept](#fullfill-a-concept)
* [Inheritance](#inheritance)
* [Static polymorphism in the wild](#static-polymorphism-in-the-wild)
* [Configurable storage size](#configurable-storage-size)
* [Storage size and alignment requirement](#storage-size-and-alignment-requirement)
<!--
@endcond TURN_OFF_DOXYGEN
-->
@@ -338,21 +338,22 @@ Therefore, where `instance.data()` will invoke the `data` member function of the
poly object, `instance->data()` will map directly to the functionality exposed
by the underlying concept.
# Configurable storage size
# Storage size and alignment requirement
Under the hood, the `poly` class template makes use of `entt::any`. Therefore,
it can take advantage of the possibility of defining at compile-time the size of
the storage suitable for the small buffer optimization.<br/>
To do this, it will be sufficient to provide the desired size as a second
template parameter:
the storage suitable for the small buffer optimization as well as the alignment
requirements:
```cpp
entt::poly<Drawable, sizeof(double[4])>
entt::basic_poly<Drawable, sizeof(double[4]), alignof(double[4])>
```
The default value is `sizeof(double[2])`, which seems like a good compromise
The default size is `sizeof(double[2])`, which seems like a good compromise
between a buffer that is too large and one unable to hold anything larger than
an integer.<br/>
an integer. The alignment requirement is optional instead and by default such
that it's the most stringent (the largest) for any object whose size is at most
equal to the one provided.<br/>
It's worth noting that providing a size of 0 (which is an accepted value in all
respects) will force the system to dynamically allocate the contained objects in
all cases.