8#ifndef Sawyer_Optional_H 
    9#define Sawyer_Optional_H 
   11#include <Sawyer/Sawyer.h> 
   37    template<
class T> 
explicit Nothing(T) {}
 
   38    template<
class T> 
Nothing& operator=(T) { 
return *
this; }
 
   39    bool operator==(
const Nothing&)
 const { 
return true; }
 
   40    bool operator!=(
const Nothing&)
 const { 
return false; }
 
   41    bool operator>(
const Nothing&)
 const { 
return false; }
 
   42    bool operator>=(
const Nothing&)
 const { 
return true; }
 
   43    bool operator<(
const Nothing&)
 const { 
return false; }
 
   44    bool operator<=(
const Nothing&)
 const { 
return true; }
 
 
   55    alignas(
alignof(T)) 
unsigned char data_[
sizeof(T)]; 
 
   58    void *address() { 
return data_; }
 
   59    const void*address()
 const { 
return &data_; }
 
   61#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   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();
 
   86#ifdef SAWYER_HAVE_CEREAL 
   88    friend class cereal::access;
 
   90    template<
class Archive>
 
   91    void CEREAL_SAVE_FUNCTION_NAME(Archive &archive)
 const {
 
   92        archive(cereal::make_nvp(
"isEmpty", isEmpty_));
 
   94            archive(cereal::make_nvp(
"value", 
get()));
 
   97    template<
class Archive>
 
   98    void CEREAL_LOAD_FUNCTION_NAME(Archive &archive) {
 
  104            archive(cereal::make_nvp(
"value", 
get()));
 
  122        new (address()) 
Value(v);                    
 
 
  135        isEmpty_ = other.isEmpty_;
 
  137            const Value &otherValue = *other;
 
  138            new (address()) 
Value(otherValue);
 
 
  147            Value &thisValue = **
this;
 
 
  158            new (address()) 
Value(value);
 
  160            Value &thisValue = **
this;
 
 
  173            Value &thisValue = **
this;
 
 
  187        if (isEmpty_ && !other.isEmpty_) {
 
  188            const Value &otherValue = *other;
 
  189            new (address()) 
Value(otherValue);
 
  190        } 
else if (!isEmpty_) {
 
  191            if (other.isEmpty_) {
 
  192                Value &thisValue = **
this;
 
  195                Value &thisValue = **
this;
 
  196                const Value &otherValue = *other;
 
  197                thisValue = otherValue;
 
  200        isEmpty_ = other.isEmpty_;
 
 
  233            throw std::domain_error(
"dereferenced nothing");
 
  234        return *
reinterpret_cast<const Value*
>(address());
 
 
  238            throw std::domain_error(
"dereferenced nothing");
 
  239        return *
reinterpret_cast<Value*
>(address());
 
 
  270        return isEmpty_ ? dflt : **
this;
 
 
  273        return isEmpty_ ? dflt : **
this;
 
 
  276        return isEmpty_ ? other : *
this;
 
 
  286        return isEmpty_ ? *this : 
Optional(value);
 
 
  289        return isEmpty_ ? *this : 
Optional(value);
 
 
  292        return isEmpty_ ? *this : other;
 
 
  308        return isEmpty_ ? 
Value() : **
this;
 
 
  350        return (isEmpty_ && other.isEmpty_) || (!isEmpty_ && !other.isEmpty_ && 
get()==other.
get());
 
 
  353        return !isEmpty_ && 
get()==other;
 
 
  365    template <
typename F>
 
  377    typedef void(
Optional::*unspecified_bool)() const;
 
  378    void this_type_does_not_support_comparisons()
 const {}
 
  391    operator unspecified_bool()
 const {
 
  392        return isEmpty_ ? 0 : &Optional::this_type_does_not_support_comparisons;
 
 
 
  404template<
typename T, 
typename U>
 
  405bool operator==(
const Optional<T> &lhs, 
const U&) {
 
  406    lhs.this_type_does_not_support_comparisons();
 
  410template<
typename T, 
typename U>
 
  411bool operator!=(
const Optional<T> &lhs, 
const U&) {
 
  412    lhs.this_type_does_not_support_comparisons();
 
Holds a value or nothing.
 
Optional & operator=(const Nothing &)
Nothing assignment.
 
const Value & orElse(Value &dflt)
Obtain value or something else.
 
const Value & operator*() const
Dereference to obtain value.
 
auto fmap(F &&f) -> Optional< decltype(f(get()))>
Conditionally apply a functor f to the contents of an Optional.
 
T Value
Type of stored value.
 
const Optional & andThen(const Optional &other) const
If a value is present, return something else.
 
const Value * operator->() const
Obtain a pointer to the value.
 
Value orDefault() const
Obtain a value or a default.
 
Optional(const Value &v)
Construct from value.
 
Optional & operator=(const Value &value)
Value assignment.
 
const Optional orElse(const Optional &other) const
Obtain value or something else.
 
Optional & operator=(const Optional &other)
Optional assignment.
 
Optional(const Nothing &)
Construct from nothing.
 
Value * operator->()
Obtain a pointer to the value.
 
Optional andTHen(Value &value) const
If a value is present, return something else.
 
bool isEqual(const Nothing &) const
Compare two values.
 
Value & operator*()
Dereference to obtain value.
 
void reset()
Reset as if default-constructed.
 
bool isEmpty() const
True if this optional does not contain a value.
 
const Value & orElse(const Value &dflt) const
Obtain value or something else.
 
const Value & get() const
Dereference to obtain value.
 
bool isSome() const
True if this optional contains a value.
 
Optional()
Default constructs nothing.
 
Value & get()
Dereference to obtain value.
 
bool assignTo(U &out) const
Conditionally save a value.
 
bool isEqual(const Optional &other) const
Compare two values.
 
Optional(const Optional &other)
Copy constructor.
 
Optional andThen(const Value &value) const
If a value is present, return something else.
 
bool isEqual(const Value &other) const
Compare two values.