The markable lib was created for this sole purpose:
Markable 1.0.0
An alternative to boost::optional<T>
which does not store an additional bool
flag, but encodes the 'empty' state inside T
using a special indicated value.
Usage
Do you want to store a possibly missing int
? Can you spare value -1
?
You can use it like this:
using namespace ak_toolkit;
typedef markable<mark_int<int, -1>> opt_int;
opt_int oi;
opt_int o2 (2);
assert (!oi.has_value());
assert (o2.has_value());
assert (o2.value() == 2);
static_assert (sizeof(opt_int) == sizeof(int), "");
Do you want to store a possibly missing std::string
, where 'missing'
!= 'empty'? Can you spare some string values that contain a null
character inside, like std::string("\0\0", 2)
? This is how you do
it:
struct string_marked_value // a policy which defines the representaioion of the
: ak_toolkit::markable_type<std::string> // 'marked' (special) std::string value
{
static std::string marked_value() { // create the marked value
return std::string("\0\0", 2);
}
static bool is_marked_value(const std::string& v) { // test if a given value is considered marked
return v.compare(0, v.npos, "\0\0", 2) == 0;
}
};
typedef ak_toolkit::markable<string_marked_value> opt_str;
opt_str os, oE(std::string(""));
assert (!os.has_value());
assert (oE.has_value());
assert (oE.value() == "");
static_assert (sizeof(opt_str) == sizeof(std::string), "");
Albeit not a Boost library, markable is licensed under Boost Software License, Version 1.0., and is even referred to from the Performance Considerations section of Boosts own optional type:
Performance considerations
[...]
Controlling the size
[...] Therefore, if the size of the objects is critical for your
application (e.g., because you want to utilize your CPU cache in
order to gain performance) and you have determined you are willing to
trade the code clarity, it is recommended that you simply go with
type int
and use some 'magic value' to represent not-an-int, or
use something like markable
library.
The background and thought process of the lib is explained in the following blog post from the lib's author: