diff --git a/external/Optional/optional.hpp b/external/Optional/optional.hpp index 97c3e20b0..aca993222 100644 --- a/external/Optional/optional.hpp +++ b/external/Optional/optional.hpp @@ -38,9 +38,21 @@ # else # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # endif +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) +# define OPTIONAL_GCC45_COMPATIBILITY 0 +# else +# define OPTIONAL_GCC45_COMPATIBILITY 1 +# endif +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) +# define OPTIONAL_GCC44_COMPATIBILITY 0 +# else +# define OPTIONAL_GCC44_COMPATIBILITY 1 +# endif # else # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # define OPTIONAL_HAS_USING 0 +# define OPTIONAL_GCC45_COMPATIBILITY 0 +# define OPTIONAL_GCC44_COMPATIBILITY 0 # endif @@ -66,6 +78,7 @@ using is_trivially_destructible = typename std::has_trivial_destructor; # else +#if !OPTIONAL_GCC45_COMPATIBILITY // workaround for missing traits in GCC and CLANG template struct is_nothrow_move_constructible @@ -103,6 +116,7 @@ struct is_nothrow_move_assignable constexpr static bool value = has_nothrow_move_assign::value>::value; }; // end workaround +#endif # endif // not as good as GCC 4.7 @@ -152,6 +166,7 @@ template inline constexpr typename std::remove_reference::type&& co #endif +#if !OPTIONAL_GCC45_COMPATIBILITY template struct has_overloaded_addressof { @@ -177,19 +192,39 @@ T* static_addressof(T& ref) { return std::addressof(ref); } +#else +template +T* addressof(T& ref) +{ + return reinterpret_cast(&const_cast(reinterpret_cast(ref))); +} +template +T* static_addressof(T& ref) +{ + return addressof(ref); +} +#endif template struct is_not_optional { + #if !OPTIONAL_GCC45_COMPATIBILITY constexpr static bool value = true; + #else + static const bool value = true; + #endif }; template struct is_not_optional> { + #if !OPTIONAL_GCC45_COMPATIBILITY constexpr static bool value = false; + #else + static const bool value = false; + #endif }; @@ -217,6 +252,7 @@ public: }; +#if !OPTIONAL_GCC45_COMPATIBILITY template union storage_t { @@ -245,7 +281,23 @@ union constexpr_storage_t ~constexpr_storage_t() = default; }; +#else +template +struct storage_t +{ + unsigned char storage_[sizeof(T)]; + T& value_() { return *reinterpret_cast(storage_); } + const T& value_() const { return *reinterpret_cast(storage_); } + + storage_t( trivial_init_t ): storage_() {} + + template storage_t( Args&&... args ) { + new(storage_) T(forward(args)...); + } + ~storage_t(){} +}; +#endif constexpr struct only_set_initialized_t{} only_set_initialized{}; @@ -267,14 +319,25 @@ struct optional_base template explicit optional_base(in_place_t, Args&&... args) : init_(true), storage_(constexpr_forward(args)...) {} - template >)> + template >) + #endif + > explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) : init_(true), storage_(il, std::forward(args)...) {} - ~optional_base() { if (init_) storage_.value_.T::~T(); } + ~optional_base() { + #if !OPTIONAL_GCC45_COMPATIBILITY + if (init_) storage_.value_.T::~T(); + #else + if (init_) storage_.value_().T::~T(); + #endif + } }; +#if !OPTIONAL_GCC45_COMPATIBILITY template struct constexpr_optional_base { @@ -298,6 +361,7 @@ struct constexpr_optional_base ~constexpr_optional_base() = default; }; +#endif # if OPTIONAL_HAS_USING template @@ -318,16 +382,40 @@ class optional : private OptionalBase constexpr bool initialized() const noexcept { return OptionalBase::init_; } - T* dataptr() { return std::addressof(OptionalBase::storage_.value_); } - constexpr const T* dataptr() const { return static_addressof(OptionalBase::storage_.value_); } + T* dataptr() { + #if !OPTIONAL_GCC45_COMPATIBILITY + return std::addressof(OptionalBase::storage_.value_); + #else + return std::addressof(OptionalBase::storage_.value_()); + #endif + } + constexpr const T* dataptr() const { + #if !OPTIONAL_GCC45_COMPATIBILITY + return static_addressof(OptionalBase::storage_.value_); + #else + return static_addressof(OptionalBase::storage_.value_()); + #endif + } # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; } T& contained_val() & { return OptionalBase::storage_.value_; } T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } # else - constexpr const T& contained_val() const { return OptionalBase::storage_.value_; } - T& contained_val() { return OptionalBase::storage_.value_; } + constexpr const T& contained_val() const { + #if !OPTIONAL_GCC45_COMPATIBILITY + return OptionalBase::storage_.value_; + #else + return OptionalBase::storage_.value_(); + #endif + } + T& contained_val() { + #if !OPTIONAL_GCC45_COMPATIBILITY + return OptionalBase::storage_.value_; + #else + return OptionalBase::storage_.value_(); + #endif + } # endif void clear() noexcept { @@ -336,7 +424,10 @@ class optional : private OptionalBase } template - void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) + void initialize(Args&&... args) + #if !OPTIONAL_GCC45_COMPATIBILITY + noexcept(noexcept(T(std::forward(args)...))) + #endif { assert(!OptionalBase::init_); new (dataptr()) T(std::forward(args)...); @@ -344,7 +435,10 @@ class optional : private OptionalBase } template - void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...))) + void initialize(std::initializer_list il, Args&&... args) + #if !OPTIONAL_GCC45_COMPATIBILITY + noexcept(noexcept(T(il, std::forward(args)...))) + #endif { assert(!OptionalBase::init_); new (dataptr()) T(il, std::forward(args)...); @@ -364,7 +458,10 @@ public: if (rhs.initialized()) new (dataptr()) T(*rhs); } - optional(optional&& rhs) noexcept(std::is_nothrow_move_constructible::value) + optional(optional&& rhs) + #if !OPTIONAL_GCC45_COMPATIBILITY + noexcept(std::is_nothrow_move_constructible::value) + #endif : OptionalBase(only_set_initialized, rhs.initialized()) { if (rhs.initialized()) new (dataptr()) T(std::move(*rhs)); @@ -378,7 +475,11 @@ public: constexpr explicit optional(in_place_t, Args&&... args) : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} - template >)> + template >) + #endif + > explicit optional(in_place_t, std::initializer_list il, Args&&... args) : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} @@ -401,7 +502,9 @@ public: } optional& operator=(optional&& rhs) + #if !OPTIONAL_GCC45_COMPATIBILITY noexcept(std::is_nothrow_move_assignable::value && std::is_nothrow_move_constructible::value) + #endif { if (initialized() == true && rhs.initialized() == false) clear(); else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs)); @@ -438,7 +541,10 @@ public: } // 20.5.4.4 Swap - void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval()))) + void swap(optional& rhs) + #if !OPTIONAL_GCC45_COMPATIBILITY + noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval()))) + #endif { if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); } else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); } @@ -472,7 +578,10 @@ public: return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); } - constexpr explicit operator bool() const noexcept { return initialized(); } + #if !OPTIONAL_GCC44_COMPATIBILITY + constexpr explicit + #endif + operator bool() const noexcept { return initialized(); } # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 @@ -589,7 +698,10 @@ public: return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); } - explicit constexpr operator bool() const noexcept { + #if !OPTIONAL_GCC44_COMPATIBILITY + explicit constexpr + #endif + operator bool() const noexcept { return ref != nullptr; } @@ -890,7 +1002,10 @@ template constexpr bool operator>=(const T& v, const optional -void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))) +void swap(optional& x, optional& y) +#if !OPTIONAL_GCC45_COMPATIBILITY +noexcept(noexcept(x.swap(y))) +#endif { x.swap(y); }