From 61377c582e0f2675baa5f5e6e30a35d1a4164b33 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 1 May 2017 16:08:43 +0300 Subject: Add hxx extension for headers and lib prefix for library dir --- libbutl/optional.hxx | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 libbutl/optional.hxx (limited to 'libbutl/optional.hxx') diff --git a/libbutl/optional.hxx b/libbutl/optional.hxx new file mode 100644 index 0000000..c1bc582 --- /dev/null +++ b/libbutl/optional.hxx @@ -0,0 +1,96 @@ +// file : libbutl/optional.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBUTL_OPTIONAL_HXX +#define LIBBUTL_OPTIONAL_HXX + +#include // move() +#include // hash + +namespace butl +{ + // Simple optional class template while waiting for std::optional. + // + struct nullopt_t {constexpr explicit nullopt_t (int) {}}; + constexpr const nullopt_t nullopt (1); + + template + class optional + { + public: + typedef T value_type; + + constexpr optional (): value_ (), null_ (true) {} // VC14 needs value_(). + constexpr optional (nullopt_t): value_ (), null_ (true) {} + constexpr optional (const T& v): value_ (v), null_ (false) {} + constexpr 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_;} + + bool has_value () const {return !null_;} + explicit operator bool () const {return !null_;} + + private: + T value_; + bool null_; + }; + + template + inline auto + operator== (const optional& x, const optional& y) -> decltype (*x == *y) + { + return static_cast (x) == static_cast (y) && (!x || *x == *y); + } + + template + inline auto + operator!= (const optional& x, const optional& y) -> decltype (x == y) + { + return !(x == y); + } + + template + inline auto + operator< (const optional& x, const optional& y) -> decltype (*x < *y) + { + bool px (x), py (y); + return px < py || (px && py && *x < *y); + } + + template + inline auto + operator> (const optional& x, const optional& y) -> decltype (*x > *y) + { + return y < x; + } +} + +namespace std +{ + template + struct hash>: hash + { + using argument_type = butl::optional; + + size_t + operator() (const butl::optional& o) const + noexcept (noexcept (hash {} (*o))) + { + return o ? hash::operator() (*o) : static_cast (-3333); + } + }; +} + +#endif // LIBBUTL_OPTIONAL_HXX -- cgit v1.1