trivially-copyable optional<T> for trivial T

This commit is contained in:
Andrzej Krzemienski
2017-10-28 16:51:13 +02:00
parent e95f9fc254
commit 2d2c3c3f6f
9 changed files with 826 additions and 21 deletions

View File

@@ -1,7 +1,7 @@

[section Performance considerations]
Technical details aside, the memory layout of `optional<T>` is more-less this:
Technical details aside, the memory layout of `optional<T>` for a generic `T` is more-less this:
template <typename T>
class optional
@@ -9,8 +9,33 @@ Technical details aside, the memory layout of `optional<T>` is more-less this:
bool _initialized;
std::aligned_storage_t<sizeof(t), alignof(T)> _storage;
};
Lifetime of the `T` inside `_storage` is manually controlled with placement-`new`s and pseudo-destructor calls. However, for trivial `T`s we use a different way of storage, by simply holding a `T`:
But for the purpose of this analysis, considering memory layouts, we can think of it as:
template <typename T>
class optional
{
bool _initialized;
T _storage;
};
We call it a ['direct] storage. This makes `optional<T>` a trivially-copyable type for trivial `T`s. This only works for compilers that support defaulted functions and type traits. On compilers without defaulted functions we still use the direct storage, but `optional<T>` is no longer recognized as trivially-copyable. On compilers that do not fully support type traits, we still use the direct storage for scalar types, but we leave the programmer a way of customizing her type, so that it is reconized by `optional` as trivial, by specializing type trait `boost::opitonal_config::is_type_trivial`:
struct X // not trivial
{
X() {}
};
namespace boost { namespace optional_config {
template <> struct is_type_trivial<X> : boost::true_type {};
}}
[heading Controlling the size]
For the purpose of the followin analysis, considering memory layouts, we can think of it as:
template <typename T>
class optional