Browse Source

external: updated std::optional with MSVC 2013 compatibility.

Vladimír Vondruš 13 years ago
parent
commit
82a8510877
  1. 130
      external/Optional/optional.hpp

130
external/Optional/optional.hpp vendored

@ -21,10 +21,19 @@
# define REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false # define REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
# if defined __clang__ # 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) # if (__clang_major__ >= 3)
# define OPTIONAL_HAS_USING 1 # define OPTIONAL_HAS_USING 1
# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 1
# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 1
# else # else
# define OPTIONAL_HAS_USING 0 # define OPTIONAL_HAS_USING 0
# define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0
# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0
# endif # endif
# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) # if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 # define OPTIONAL_HAS_THIS_RVALUE_REFS 1
@ -43,20 +52,29 @@
# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # define OPTIONAL_HAS_THIS_RVALUE_REFS 0
# endif # endif
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) # 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 # else
# define OPTIONAL_GCC45_COMPATIBILITY 1 # define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0
# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0
# endif # endif
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))
# define OPTIONAL_GCC44_COMPATIBILITY 0 # define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 1
# else # else
# define OPTIONAL_GCC44_COMPATIBILITY 1 # define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0
# endif # 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 # else
# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 # define OPTIONAL_HAS_THIS_RVALUE_REFS 0
# define OPTIONAL_HAS_USING 0 # define OPTIONAL_HAS_USING 0
# define OPTIONAL_GCC45_COMPATIBILITY 0 # define OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS 0
# define OPTIONAL_GCC44_COMPATIBILITY 0 # define OPTIONAL_HAS_CONSTEXPR_NOEXCEPT 0
# define OPTIONAL_HAS_UNRESTRICTED_UNIONS 0
# endif # endif
@ -67,6 +85,8 @@ namespace std{
// leave it; our metafunctions are already defined. // leave it; our metafunctions are already defined.
# elif (defined __clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3) && (__clang_minor__ >= 3)) # elif (defined __clang__) && ((__clang_major__ > 3) || (__clang_major__ == 3) && (__clang_minor__ >= 3))
// leave it; our metafunctions are already defined. // leave it; our metafunctions are already defined.
# elif (defined _MSC_VER) && _MSC_VER >= 1800
// leave it; our metafunctions are already defined.
# else # else
# if OPTIONAL_HAS_USING # if OPTIONAL_HAS_USING
@ -82,7 +102,7 @@ using is_trivially_destructible = typename std::has_trivial_destructor<T>;
# else # else
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
// workaround for missing traits in GCC and CLANG // workaround for missing traits in GCC and CLANG
template <class T> template <class T>
struct is_nothrow_move_constructible struct is_nothrow_move_constructible
@ -122,6 +142,15 @@ struct is_nothrow_move_assignable
// end workaround // end workaround
#endif #endif
# if (defined __GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))
// leave it; remaining metafunctions are already defined.
# else
template<class, class>
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.7
# endif // not as good as GCC 4.8 # endif // not as good as GCC 4.8
@ -165,6 +194,8 @@ template <class T> inline constexpr typename std::remove_reference<T>::type&& co
__assert(expr, file, line); __assert(expr, file, line);
# elif defined __GNUC__ # elif defined __GNUC__
_assert(expr, file, line); _assert(expr, file, line);
# elif defined _MSC_VER
_CrtDbgReport(_CRT_ASSERT, file, line, expr);
# else # else
# error UNSUPPORTED COMPILER # error UNSUPPORTED COMPILER
# endif # endif
@ -172,7 +203,7 @@ template <class T> inline constexpr typename std::remove_reference<T>::type&& co
#endif #endif
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
template <typename T> template <typename T>
struct has_overloaded_addressof struct has_overloaded_addressof
{ {
@ -216,37 +247,41 @@ T* static_addressof(T& ref)
template <class U> template <class U>
struct is_not_optional struct is_not_optional
{ {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr static bool value = true; constexpr
#else #else
static const bool value = true; const
#endif #endif
static bool value = true;
}; };
template <class T> template <class T>
struct is_not_optional<optional<T>> struct is_not_optional<optional<T>>
{ {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr static bool value = false; constexpr
#else #else
static const bool value = false; const
#endif #endif
static bool value = false;
}; };
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr struct trivial_init_t{} trivial_init{}; constexpr
#else #else
const struct trivial_init_t{} trivial_init{}; const
#endif #endif
struct trivial_init_t{} trivial_init{};
// 20.5.6, In-place construction // 20.5.6, In-place construction
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr struct in_place_t{} in_place{}; constexpr
#else #else
const struct in_place_t{} in_place{}; const
#endif #endif
struct in_place_t{} in_place{};
// 20.5.7, Disengaged state indicator // 20.5.7, Disengaged state indicator
@ -255,11 +290,12 @@ struct nullopt_t
struct init{}; struct init{};
constexpr nullopt_t(init){}; constexpr nullopt_t(init){};
}; };
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr nullopt_t nullopt{nullopt_t::init{}}; constexpr
#else #else
const nullopt_t nullopt{nullopt_t::init{}}; const
#endif #endif
nullopt_t nullopt{nullopt_t::init{}};
// 20.5.8, class bad_optional_access // 20.5.8, class bad_optional_access
@ -270,7 +306,7 @@ public:
}; };
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
template <class T> template <class T>
union storage_t union storage_t
{ {
@ -317,11 +353,12 @@ struct storage_t
}; };
#endif #endif
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
constexpr struct only_set_initialized_t{} only_set_initialized{}; constexpr
#else #else
const struct only_set_initialized_t{} only_set_initialized{}; const
#endif #endif
struct only_set_initialized_t{} only_set_initialized{};
template <class T> template <class T>
@ -342,15 +379,13 @@ struct optional_base
: init_(true), storage_(constexpr_forward<Args>(args)...) {} : init_(true), storage_(constexpr_forward<Args>(args)...) {}
template <class U, class... Args template <class U, class... Args
#if !OPTIONAL_GCC44_COMPATIBILITY
, REQUIRES(is_constructible<T, std::initializer_list<U>>) , REQUIRES(is_constructible<T, std::initializer_list<U>>)
#endif
> >
explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args) explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
: init_(true), storage_(il, std::forward<Args>(args)...) {} : init_(true), storage_(il, std::forward<Args>(args)...) {}
~optional_base() { ~optional_base() {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
if (init_) storage_.value_.T::~T(); if (init_) storage_.value_.T::~T();
#else #else
if (init_) storage_.value_().T::~T(); if (init_) storage_.value_().T::~T();
@ -359,7 +394,7 @@ struct optional_base
}; };
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
template <class T> template <class T>
struct constexpr_optional_base struct constexpr_optional_base
{ {
@ -405,14 +440,14 @@ class optional : private OptionalBase<T>
constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; } constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
T* dataptr() { T* dataptr() {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
return std::addressof(OptionalBase<T>::storage_.value_); return std::addressof(OptionalBase<T>::storage_.value_);
#else #else
return std::addressof(OptionalBase<T>::storage_.value_()); return std::addressof(OptionalBase<T>::storage_.value_());
#endif #endif
} }
constexpr const T* dataptr() const { constexpr const T* dataptr() const {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
return static_addressof(OptionalBase<T>::storage_.value_); return static_addressof(OptionalBase<T>::storage_.value_);
#else #else
return static_addressof(OptionalBase<T>::storage_.value_()); return static_addressof(OptionalBase<T>::storage_.value_());
@ -425,14 +460,14 @@ class optional : private OptionalBase<T>
T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); } T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
# else # else
constexpr const T& contained_val() const { constexpr const T& contained_val() const {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
return OptionalBase<T>::storage_.value_; return OptionalBase<T>::storage_.value_;
#else #else
return OptionalBase<T>::storage_.value_(); return OptionalBase<T>::storage_.value_();
#endif #endif
} }
T& contained_val() { T& contained_val() {
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_UNRESTRICTED_UNIONS
return OptionalBase<T>::storage_.value_; return OptionalBase<T>::storage_.value_;
#else #else
return OptionalBase<T>::storage_.value_(); return OptionalBase<T>::storage_.value_();
@ -447,7 +482,7 @@ class optional : private OptionalBase<T>
template <class... Args> template <class... Args>
void initialize(Args&&... args) void initialize(Args&&... args)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(noexcept(T(std::forward<Args>(args)...))) noexcept(noexcept(T(std::forward<Args>(args)...)))
#endif #endif
{ {
@ -458,7 +493,7 @@ class optional : private OptionalBase<T>
template <class U, class... Args> template <class U, class... Args>
void initialize(std::initializer_list<U> il, Args&&... args) void initialize(std::initializer_list<U> il, Args&&... args)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(noexcept(T(il, std::forward<Args>(args)...))) noexcept(noexcept(T(il, std::forward<Args>(args)...)))
#endif #endif
{ {
@ -481,7 +516,7 @@ public:
} }
optional(optional&& rhs) optional(optional&& rhs)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(std::is_nothrow_move_constructible<T>::value) noexcept(std::is_nothrow_move_constructible<T>::value)
#endif #endif
: OptionalBase<T>(only_set_initialized, rhs.initialized()) : OptionalBase<T>(only_set_initialized, rhs.initialized())
@ -498,9 +533,7 @@ public:
: OptionalBase<T>(in_place_t{}, constexpr_forward<Args>(args)...) {} : OptionalBase<T>(in_place_t{}, constexpr_forward<Args>(args)...) {}
template <class U, class... Args template <class U, class... Args
#if !OPTIONAL_GCC44_COMPATIBILITY
, REQUIRES(is_constructible<T, std::initializer_list<U>>) , REQUIRES(is_constructible<T, std::initializer_list<U>>)
#endif
> >
explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args) explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args)
: OptionalBase<T>(in_place_t{}, il, constexpr_forward<Args>(args)...) {} : OptionalBase<T>(in_place_t{}, il, constexpr_forward<Args>(args)...) {}
@ -524,7 +557,7 @@ public:
} }
optional& operator=(optional&& rhs) optional& operator=(optional&& rhs)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value) noexcept(std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value)
#endif #endif
{ {
@ -564,7 +597,7 @@ public:
// 20.5.4.4 Swap // 20.5.4.4 Swap
void swap(optional<T>& rhs) void swap(optional<T>& rhs)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>()))) noexcept(is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>())))
#endif #endif
{ {
@ -600,8 +633,9 @@ public:
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
} }
#if !OPTIONAL_GCC44_COMPATIBILITY constexpr
constexpr explicit #if OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS
explicit
#endif #endif
operator bool() const noexcept { return initialized(); } operator bool() const noexcept { return initialized(); }
@ -720,10 +754,10 @@ public:
return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
} }
#if !OPTIONAL_GCC44_COMPATIBILITY #if OPTIONAL_HAS_EXPLICIT_CONVERSION_OPS
explicit constexpr explicit
#endif #endif
operator bool() const noexcept { constexpr operator bool() const noexcept {
return ref != nullptr; return ref != nullptr;
} }
@ -1025,7 +1059,7 @@ template <class T> constexpr bool operator>=(const T& v, const optional<const T&
// 20.5.12 Specialized algorithms // 20.5.12 Specialized algorithms
template <class T> template <class T>
void swap(optional<T>& x, optional<T>& y) void swap(optional<T>& x, optional<T>& y)
#if !OPTIONAL_GCC45_COMPATIBILITY #if OPTIONAL_HAS_CONSTEXPR_NOEXCEPT
noexcept(noexcept(x.swap(y))) noexcept(noexcept(x.swap(y)))
#endif #endif
{ {

Loading…
Cancel
Save