8 #ifndef Sawyer_Optional_H
9 #define Sawyer_Optional_H
11 #include <Sawyer/Sawyer.h>
12 #include <boost/serialization/access.hpp>
13 #include <boost/serialization/nvp.hpp>
14 #include <boost/serialization/split_member.hpp>
15 #include <boost/type_traits/aligned_storage.hpp>
16 #include <boost/type_traits/type_with_alignment.hpp>
34 bool operator==(
const Nothing&)
const {
return true; }
35 bool operator!=(
const Nothing&)
const {
return false; }
36 bool operator>(
const Nothing&)
const {
return false; }
37 bool operator>=(
const Nothing&)
const {
return true; }
38 bool operator<(
const Nothing&)
const {
return false; }
39 bool operator<=(
const Nothing&)
const {
return true; }
52 union SAWYER_MAY_ALIAS MayAlias {
53 unsigned char data_[
sizeof(T)];
54 BOOST_DEDUCED_TYPENAME boost::type_with_alignment<boost::alignment_of<T>::value >::type aligner_;
59 void *address() {
return &mayAlias_; }
60 const void*address()
const {
return &mayAlias_; }
63 friend class boost::serialization::access;
66 void save(S &s,
const unsigned )
const {
67 s <<BOOST_SERIALIZATION_NVP(isEmpty_);
69 s <<boost::serialization::make_nvp(
"value",
get());
73 void load(S &s,
const unsigned ) {
76 s >>boost::serialization::make_nvp(
"isEmpty_", skip);
79 s >>boost::serialization::make_nvp(
"value",
get());
83 BOOST_SERIALIZATION_SPLIT_MEMBER();
98 new (address())
Value(v);
111 isEmpty_ = other.isEmpty_;
113 const Value &otherValue = *other;
114 new (address())
Value(otherValue);
123 Value &thisValue = **
this;
134 new (address())
Value(value);
136 Value &thisValue = **
this;
149 Value &thisValue = **
this;
163 if (isEmpty_ && !other.isEmpty_) {
164 const Value &otherValue = *other;
165 new (address())
Value(otherValue);
166 }
else if (!isEmpty_) {
167 if (other.isEmpty_) {
168 Value &thisValue = **
this;
171 Value &thisValue = **
this;
172 const Value &otherValue = *other;
173 thisValue = otherValue;
176 isEmpty_ = other.isEmpty_;
199 throw std::domain_error(
"dereferenced nothing");
200 return *
reinterpret_cast<const Value*
>(address());
204 throw std::domain_error(
"dereferenced nothing");
205 return *
reinterpret_cast<Value*
>(address());
236 return isEmpty_ ? dflt : **
this;
239 return isEmpty_ ? dflt : **
this;
242 return isEmpty_ ? other : *
this;
258 return isEmpty_ ?
Value() : **
this;
300 return (isEmpty_ && other.isEmpty_) || (!isEmpty_ && !other.isEmpty_ &&
get()==other.
get());
303 return !isEmpty_ &&
get()==other;
313 typedef void(
Optional::*unspecified_bool)()
const;
314 void this_type_does_not_support_comparisons()
const {}
327 operator unspecified_bool()
const {
328 return isEmpty_ ? 0 : &Optional::this_type_does_not_support_comparisons;
340 template<
typename T,
typename U>
341 bool operator==(
const Optional<T> &lhs,
const U &rhs) {
342 lhs.this_type_does_not_support_comparisons();
346 template<
typename T,
typename U>
347 bool operator!=(
const Optional<T> &lhs,
const U &rhs) {
348 lhs.this_type_does_not_support_comparisons();
bool isEqual(const Optional &other) const
Compare two values.
const Value & operator*() const
Dereference to obtain value.
Holds a value or nothing.
const Optional orElse(const Optional &other) const
Obtain value or something else.
bool isEqual(const Nothing &) const
Compare two values.
Value & operator*()
Dereference to obtain value.
Value * operator->()
Obtain a pointer to the value.
T Value
Type of stored value.
Optional & operator=(const Optional &other)
Optional assignment.
Optional(const Optional &other)
Copy constructor.
bool isEqual(const Value &other) const
Compare two values.
Optional & operator=(const Value &value)
Value assignment.
Optional(const Nothing &)
Construct from nothing.
Value orDefault() const
Obtain a value or a default.
Optional & operator=(const Nothing &)
Nothing assignment.
Optional()
Default constructs nothing.
const Value & orElse(const Value &dflt) const
Obtain value or something else.
const Value & orElse(Value &dflt)
Obtain value or something else.
Name space for the entire library.
const Value * operator->() const
Obtain a pointer to the value.
void reset()
Reset as if default-constructed.
const Value & get() const
Dereference to obtain value.
Optional(const Value &v)
Construct from value.
bool assignTo(U &out) const
Conditionally save a value.
Value & get()
Dereference to obtain value.