Boost logo

Boost :

Subject: Re: [boost] [optional] Specializing optional to save space
From: David Stone (david_at_[hidden])
Date: 2015-10-03 15:49:36


I have a new version that was inspired by Agustín K-ballo Bergé in the
compact_optional thread.

My new interface involves a special tag type used to 'unlock' access to
particular functions. I have creatively named this type optional_tag. Only
optional can construct an optional_tag. For a type to opt-in to a
space-efficient representation, it needs the following member functions:

* T(optional_tag) constructs an uninitialized value
* initialize(optional_tag, T && ...) constructs an object when there may be
one in existence already
* uninitialize(optional_tag) destroys the contained object
* is_initialized(optional_tag) checks whether the object is currently in an
initialized state

By always requiring the optional_tag parameter, we do not limit any
function signatures. This is why, for instance, we cannot use operator
bool() as the test, because the type may want that operator for other
reasons.

An advantage of this over some other possible methods of implementing it is
that you can make it work with any type that can naturally support such a
state. It does not add any requirements such as having a move constructor.

You can see a full code implementation of the idea at

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 the specialization:

https://bitbucket.org/davidstone/bounded_integer/src/8c5e7567f0d8b3a04cc98142060a020b58b2a00f/bounded_integer/detail/class.hpp?at=default&fileviewer=file-view-default

(lines 220 through 242)

The problem with my previous approach is that it is simply more work for
the user. Rather than adding four member functions, the user must go into a
new namespace and specialize a template.

In practice, all specializations would have an in_place_t constructor that
forwards all arguments to the underlying type. The optional_tag approach,
on the other hand, can just use the underlying type's constructors directly.

In my old approach, the user also has the responsibility of adding proper
reference-qualified overloads of a value function. In the optional_tag
approach, we already have the value so we do not have to pull it out.

My old approach also required standardizing as part of the interface of
optional two helper classes, only one of which the user is supposed to
specialize (and sometimes delegate their specialization to the other).


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk