Simplify space saving
I decided that this was a useful thing, but a full specialization is a little more work than necessary (for example, getting operator= correct).
I posted on the Boost mailing list a way to simplify the specialization task, especially when you want to specialize in some instances of a class template.
http://boost.2283326.n4.nabble.com/optional-Specializing-optional-to-save-space-td4680362.html
My current interface includes a special type of tag used to "unlock" access to certain functions. I creatively named this type optional_tag . Only optional can build optional_tag . To select a type in a space-efficient representation, it needs the following member functions:
T(optional_tag) builds an uninitialized valueinitialize(optional_tag, Args && ...) creates an object if it already existsuninitialize(optional_tag) destroys the contained objectis_initialized(optional_tag) checks if an object is in its current state
By always requiring the optional_tag parameter, we do not limit any function signatures. That is why, for example, we cannot use operator bool() as a test, because the type may require this operator for other reasons.
The advantage of this over some other possible ways to implement it is that you can make it work with any type that can naturally support this state. It does not add any requirements, such as the presence of a move constructor.
You can see the full implementation of the code in
https://bitbucket.org/davidstone/bounded_integer/src/8c5e7567f0d8b3a04cc98142060a020b58b2a00f/bounded_integer/detail/optional/optional.hpp?at=default&fileviewer=file-view-default
and for a class using specialization:
https://bitbucket.org/davidstone/bounded_integer/src/8c5e7567f0d8b3a04cc98142060a020b58b2a00f/bounded_integer/detail/class.hpp?at=default&fileviewer=file-view-default
(lines 220 to 242)
Alternative approach
This is different from my previous implementation, which requires users to specialize the class template. You can see the old version here:
https://bitbucket.org/davidstone/bounded_integer/src/2defec41add2079ba023c2c6d118ed8a274423c8/bounded_integer/detail/optional/optional.hpp
and
https://bitbucket.org/davidstone/bounded_integer/src/2defec41add2079ba023c2c6d118ed8a274423c8/bounded_integer/detail/optional/specialization.hpp
The problem with this approach is that it is simply more for the user. Instead of adding four member functions, the user must move to a new namespace and specialize in the template.
In practice, all specializations will have an in_place_t constructor, which forwards all arguments to the base type. On the other hand, the optional_tag approach can directly use base type constructors.
In the optional_storage special approach, the user is also responsible for adding the appropriate reference overloads of the value function. In the optional_tag approach, we already have a value, so we donโt need to pull it out.
optional_storage also required standardization as part of the interface of the optional two auxiliary classes, only one of which the user should specialize (and sometimes delegate his specialization to the other).
Difference between this and compact_optional
compact_optional is a way of saying, "Treat this special sentinel as an absent type, almost like NaN." This requires the user to know that the type they are working with has some kind of special guardian. An easily specialized optional is a way of saying: "My type does not need additional space to hold the current state, but this state is not a normal value." This does not require anyone to know about optimization in order to take advantage of it; everyone who uses this type gets it for free.
Future
My goal is to port this to boost :: optional, and then part of the std :: optional clause. Until then, you can always use bounded::optional , although it has several other (intentional) differences in the interface.