// file : butl/optional -*- C++ -*- // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BUTL_OPTIONAL #define BUTL_OPTIONAL #include <utility> // move() namespace butl { // Simple optional class template while waiting for std::optional. // struct nullopt_t {constexpr nullopt_t (int) {}}; constexpr nullopt_t nullopt = 1; template <typename T> class optional { public: typedef T value_type; optional (): null_ (true) {} optional (nullopt_t): null_ (true) {} optional (const T& v): value_ (v), null_ (false) {} optional (T&& v): value_ (std::move (v)), null_ (false) {} optional& operator= (nullopt_t) {value_ = T (); null_ = true; return *this;} optional& operator= (const T& v) {value_ = v; null_ = false; return *this;} optional& operator= (T&& v) {value_ = std::move (v); null_ = false; return *this;} T& value () {return value_;} const T& value () const {return value_;} T* operator-> () {return &value_;} const T* operator-> () const {return &value_;} T& operator* () {return value_;} const T& operator* () const {return value_;} explicit operator bool () const {return !null_;} private: T value_; bool null_; }; template <typename T> inline auto operator== (const optional<T>& x, const optional<T>& y) -> decltype (*x == *y) { return static_cast<bool> (x) == static_cast<bool> (y) && (!x || *x == *y); } template <typename T> inline auto operator!= (const optional<T>& x, const optional<T>& y) -> decltype (x == y) { return !(x == y); } } #endif // BUTL_OPTIONAL