From 4aeb5d497494eac5383610ae5dc0b70645f8ab21 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 21 Nov 2018 14:19:41 +0200 Subject: Switch to std::optional for GCC >= 7 --- libbutl/optional.mxx | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'libbutl') diff --git a/libbutl/optional.mxx b/libbutl/optional.mxx index 470c608..87ba361 100644 --- a/libbutl/optional.mxx +++ b/libbutl/optional.mxx @@ -8,10 +8,28 @@ // C includes. +// Note: Clang must come first (also defines __GNUC__). +// +// @@ Clang might be using libstdc++ without optional (feature test macro?) +// @@ Move to /ft/? +// +// Note: make sure we use butl::optional during ODB compilation (has to be +// this way until we completely switch to std::optional). +// +#if !defined(ODB_COMPILER) && \ + __cplusplus >= 201703L && \ + defined(__GNUC__) && __GNUC__ >= 7 && !defined(__clang__) +# define LIBBUTL_STD_OPTIONAL +#endif + #ifndef __cpp_lib_modules -#include // move() -#include // hash -#include // is_trivially_destructible +#ifdef LIBBUTL_STD_OPTIONAL +# include +#else +# include // move() +# include // hash +# include // is_trivially_destructible +#endif #endif // Other includes. @@ -25,6 +43,17 @@ import std.core; #include +#ifdef LIBBUTL_STD_OPTIONAL +LIBBUTL_MODEXPORT namespace butl +{ + template + using optional = std::optional; + + using std::nullopt_t; + using std::nullopt; +} +#else + LIBBUTL_MODEXPORT namespace butl { // Simple optional class template while waiting for std::optional. @@ -43,7 +72,7 @@ LIBBUTL_MODEXPORT namespace butl template struct optional_data { - struct empty {char x[sizeof(T)];}; // Note: data member important to GCC. + struct empty {}; union { @@ -86,7 +115,7 @@ LIBBUTL_MODEXPORT namespace butl template struct optional_data { - struct empty {char x[sizeof(T)];}; // Note: data member important to GCC. + struct empty {}; union { @@ -164,11 +193,11 @@ LIBBUTL_MODEXPORT namespace butl T& value () {return this->d_;} const T& value () const {return this->d_;} - T* operator-> () {return &value ();} - const T* operator-> () const {return &value ();} + T* operator-> () {return &this->d_;} + const T* operator-> () const {return &this->d_;} - T& operator* () {return value ();} - const T& operator* () const {return value ();} + T& operator* () {return this->d_;} + const T& operator* () const {return this->d_;} bool has_value () const {return this->v_;} explicit operator bool () const {return this->v_;} @@ -222,3 +251,5 @@ namespace std } #include + +#endif // !LIBBUTL_STD_OPTIONAL -- cgit v1.1