From 82a8510877086671f93a94807c40c6e406477ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 3 Dec 2013 21:25:51 +0100 Subject: [PATCH] external: updated std::optional with MSVC 2013 compatibility. --- external/Optional/optional.hpp | 130 +++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 48 deletions(-) diff --git a/external/Optional/optional.hpp b/external/Optional/optional.hpp index c468ca3c7..96145069f 100644 --- a/external/Optional/optional.hpp +++ b/external/Optional/optional.hpp @@ -21,10 +21,19 @@ # define REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false # if defined __clang__ +# if (__clang_major__ > 3) || (__clang_major__ == 3) && (__clang_minor__ >= 1) +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 1 +# else +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0 +# endif # if (__clang_major__ >= 3) # define OPTIONAL_HAS_USING 1 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 1 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 1 # else # define OPTIONAL_HAS_USING 0 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0 # endif # if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) # define OPTIONAL_HAS_THIS_RVALUE_REFS 1 @@ -43,20 +52,29 @@ # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # endif # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) -# define OPTIONAL_GCC45_COMPATIBILITY 0 +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 1 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 1 # else -# define OPTIONAL_GCC45_COMPATIBILITY 1 +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0 # endif # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) -# define OPTIONAL_GCC44_COMPATIBILITY 0 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 1 # else -# define OPTIONAL_GCC44_COMPATIBILITY 1 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0 # endif +# elif defined(_MSC_VER) && _MSC_VER >= 1800 +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# define OPTIONAL_HAS_USING 1 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 1 +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0 # else # define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # define OPTIONAL_HAS_USING 0 -# define OPTIONAL_GCC45_COMPATIBILITY 0 -# define OPTIONAL_GCC44_COMPATIBILITY 0 +# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0 +# define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0 +# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0 # endif @@ -67,6 +85,8 @@ namespace std{ // leave it; our metafunctions are already defined. # elif (defined __clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3) && (__clang_minor__ >= 3)) // leave it; our metafunctions are already defined. +# elif (defined _MSC_VER) && _MSC_VER >= 1800 + // leave it; our metafunctions are already defined. # else # if OPTIONAL_HAS_USING @@ -82,7 +102,7 @@ using is_trivially_destructible = typename std::has_trivial_destructor; # else -#if !OPTIONAL_GCC45_COMPATIBILITY +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT // workaround for missing traits in GCC and CLANG template struct is_nothrow_move_constructible @@ -122,6 +142,15 @@ struct is_nothrow_move_assignable // end workaround #endif +# if (defined __GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))) + // leave it; remaining metafunctions are already defined. +# else +template +struct is_constructible +{ + static const bool value = true; // fugly hack +}; +# endif // not as good as GCC 4.4 # endif // not as good as GCC 4.7 # endif // not as good as GCC 4.8 @@ -165,6 +194,8 @@ template inline constexpr typename std::remove_reference::type&& co __assert(expr, file, line); # elif defined __GNUC__ _assert(expr, file, line); + # elif defined _MSC_VER + _CrtDbgReport(_CRT_ASSERT, file, line, expr); # else # error UNSUPPORTED COMPILER # endif @@ -172,7 +203,7 @@ template inline constexpr typename std::remove_reference::type&& co #endif -#if !OPTIONAL_GCC45_COMPATIBILITY +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT template struct has_overloaded_addressof { @@ -216,37 +247,41 @@ T* static_addressof(T& ref) template struct is_not_optional { - #if !OPTIONAL_GCC45_COMPATIBILITY - constexpr static bool value = true; + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT + constexpr #else - static const bool value = true; + const #endif + static bool value = true; }; template struct is_not_optional> { - #if !OPTIONAL_GCC45_COMPATIBILITY - constexpr static bool value = false; + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT + constexpr #else - static const bool value = false; + const #endif + static bool value = false; }; -#if !OPTIONAL_GCC45_COMPATIBILITY -constexpr struct trivial_init_t{} trivial_init{}; +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT +constexpr #else -const struct trivial_init_t{} trivial_init{}; +const #endif +struct trivial_init_t{} trivial_init{}; // 20.5.6, In-place construction -#if !OPTIONAL_GCC45_COMPATIBILITY -constexpr struct in_place_t{} in_place{}; +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT +constexpr #else -const struct in_place_t{} in_place{}; +const #endif +struct in_place_t{} in_place{}; // 20.5.7, Disengaged state indicator @@ -255,11 +290,12 @@ struct nullopt_t struct init{}; constexpr nullopt_t(init){}; }; -#if !OPTIONAL_GCC45_COMPATIBILITY -constexpr nullopt_t nullopt{nullopt_t::init{}}; +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT +constexpr #else -const nullopt_t nullopt{nullopt_t::init{}}; +const #endif +nullopt_t nullopt{nullopt_t::init{}}; // 20.5.8, class bad_optional_access @@ -270,7 +306,7 @@ public: }; -#if !OPTIONAL_GCC45_COMPATIBILITY +#if OPTIONAL_HAS_UNRESTRICTED_UNIONS template union storage_t { @@ -317,11 +353,12 @@ struct storage_t }; #endif -#if !OPTIONAL_GCC45_COMPATIBILITY -constexpr struct only_set_initialized_t{} only_set_initialized{}; +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT +constexpr #else -const struct only_set_initialized_t{} only_set_initialized{}; +const #endif +struct only_set_initialized_t{} only_set_initialized{}; template @@ -342,15 +379,13 @@ struct optional_base : init_(true), storage_(constexpr_forward(args)...) {} template >) - #endif > explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) : init_(true), storage_(il, std::forward(args)...) {} ~optional_base() { - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_UNRESTRICTED_UNIONS if (init_) storage_.value_.T::~T(); #else if (init_) storage_.value_().T::~T(); @@ -359,7 +394,7 @@ struct optional_base }; -#if !OPTIONAL_GCC45_COMPATIBILITY +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT template struct constexpr_optional_base { @@ -405,14 +440,14 @@ class optional : private OptionalBase constexpr bool initialized() const noexcept { return OptionalBase::init_; } T* dataptr() { - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_UNRESTRICTED_UNIONS return std::addressof(OptionalBase::storage_.value_); #else return std::addressof(OptionalBase::storage_.value_()); #endif } constexpr const T* dataptr() const { - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_UNRESTRICTED_UNIONS return static_addressof(OptionalBase::storage_.value_); #else return static_addressof(OptionalBase::storage_.value_()); @@ -425,14 +460,14 @@ class optional : private OptionalBase T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } # else constexpr const T& contained_val() const { - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_UNRESTRICTED_UNIONS return OptionalBase::storage_.value_; #else return OptionalBase::storage_.value_(); #endif } T& contained_val() { - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_UNRESTRICTED_UNIONS return OptionalBase::storage_.value_; #else return OptionalBase::storage_.value_(); @@ -447,7 +482,7 @@ class optional : private OptionalBase template void initialize(Args&&... args) - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(noexcept(T(std::forward(args)...))) #endif { @@ -458,7 +493,7 @@ class optional : private OptionalBase template void initialize(std::initializer_list il, Args&&... args) - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(noexcept(T(il, std::forward(args)...))) #endif { @@ -481,7 +516,7 @@ public: } optional(optional&& rhs) - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(std::is_nothrow_move_constructible::value) #endif : OptionalBase(only_set_initialized, rhs.initialized()) @@ -498,9 +533,7 @@ public: : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} template >) - #endif > explicit optional(in_place_t, std::initializer_list il, Args&&... args) : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} @@ -524,7 +557,7 @@ public: } optional& operator=(optional&& rhs) - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(std::is_nothrow_move_assignable::value && std::is_nothrow_move_constructible::value) #endif { @@ -564,7 +597,7 @@ public: // 20.5.4.4 Swap void swap(optional& rhs) - #if !OPTIONAL_GCC45_COMPATIBILITY + #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval()))) #endif { @@ -600,8 +633,9 @@ public: return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); } - #if !OPTIONAL_GCC44_COMPATIBILITY - constexpr explicit + constexpr + #if OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS + explicit #endif operator bool() const noexcept { return initialized(); } @@ -720,10 +754,10 @@ public: return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); } - #if !OPTIONAL_GCC44_COMPATIBILITY - explicit constexpr + #if OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS + explicit #endif - operator bool() const noexcept { + constexpr operator bool() const noexcept { return ref != nullptr; } @@ -1025,7 +1059,7 @@ template constexpr bool operator>=(const T& v, const optional void swap(optional& x, optional& y) -#if !OPTIONAL_GCC45_COMPATIBILITY +#if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT noexcept(noexcept(x.swap(y))) #endif {