From c09cd7512491cee1e82c1ad8128ce9fd4bc3f79b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Sep 2017 23:32:28 +0200 Subject: Initial modularization with both Clang and VC hacks Note: gave up on VC about half way though. --- libbutl/optional.mxx | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 libbutl/optional.mxx (limited to 'libbutl/optional.mxx') diff --git a/libbutl/optional.mxx b/libbutl/optional.mxx new file mode 100644 index 0000000..4478f84 --- /dev/null +++ b/libbutl/optional.mxx @@ -0,0 +1,113 @@ +// file : libbutl/optional.mxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef __cpp_modules +#pragma once +#endif + +// C includes. + +#ifndef __cpp_lib_modules +#include // move() +#include // hash +#endif + +// Other includes. + +#ifdef __cpp_modules +export module butl.optional; +#ifdef __cpp_lib_modules +import std.core; +#endif +#endif + +#include + +LIBBUTL_MODEXPORT namespace butl +{ + // Simple optional class template while waiting for std::optional. + // + struct nullopt_t {constexpr explicit nullopt_t (int) {}}; +#if defined(__cpp_modules) && defined(__clang__) //@@ MOD Clang duplicate sym. + inline +#endif + const/*expr*/ nullopt_t nullopt (1); //@@ MOD VC multiple defs. + + 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); + } + }; +} -- cgit v1.1