aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/optional.mxx49
1 files changed, 40 insertions, 9 deletions
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 <utility> // move()
-#include <functional> // hash
-#include <type_traits> // is_trivially_destructible
+#ifdef LIBBUTL_STD_OPTIONAL
+# include <optional>
+#else
+# include <utility> // move()
+# include <functional> // hash
+# include <type_traits> // is_trivially_destructible
+#endif
#endif
// Other includes.
@@ -25,6 +43,17 @@ import std.core;
#include <libbutl/export.hxx>
+#ifdef LIBBUTL_STD_OPTIONAL
+LIBBUTL_MODEXPORT namespace butl
+{
+ template <typename T>
+ using optional = std::optional<T>;
+
+ 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 <typename T>
struct optional_data<T, false>
{
- struct empty {char x[sizeof(T)];}; // Note: data member important to GCC.
+ struct empty {};
union
{
@@ -86,7 +115,7 @@ LIBBUTL_MODEXPORT namespace butl
template <typename T>
struct optional_data<T, true>
{
- 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 <libbutl/optional.ixx>
+
+#endif // !LIBBUTL_STD_OPTIONAL