forked from TartanLlama/optional
Fix GCC4.9
This commit is contained in:
55
optional.hpp
55
optional.hpp
@ -39,6 +39,16 @@
|
|||||||
#define TL_OPTIONAL_NO_CONSTRR
|
#define TL_OPTIONAL_NO_CONSTRR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __GNUG__ && __GNUC__ < 5
|
||||||
|
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::has_trivial_copy_constructor<T>::value
|
||||||
|
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
|
||||||
|
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
||||||
|
#else
|
||||||
|
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::is_trivially_copy_constructible<T>::value
|
||||||
|
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
|
||||||
|
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __cplusplus > 201103L
|
#if __cplusplus > 201103L
|
||||||
#define TL_OPTIONAL_CXX14
|
#define TL_OPTIONAL_CXX14
|
||||||
#endif
|
#endif
|
||||||
@ -326,9 +336,16 @@ template <class T> struct optional_operations_base : optional_storage_base<T> {
|
|||||||
template <class Opt> void assign(Opt &&rhs) {
|
template <class Opt> void assign(Opt &&rhs) {
|
||||||
if (this->m_has_value) {
|
if (this->m_has_value) {
|
||||||
if (rhs.m_has_value) {
|
if (rhs.m_has_value) {
|
||||||
get() = std::forward<Opt>(rhs).get();
|
this->m_value = std::forward<Opt>(rhs).get();
|
||||||
|
} else {
|
||||||
|
this->m_value.~T();
|
||||||
|
this->m_has_value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rhs.m_has_value) {
|
||||||
|
construct(std::forward<Opt>(rhs).get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TL_OPTIONAL_11_CONSTEXPR T &get() & { return this->m_value; }
|
TL_OPTIONAL_11_CONSTEXPR T &get() & { return this->m_value; }
|
||||||
@ -339,7 +356,7 @@ template <class T> struct optional_operations_base : optional_storage_base<T> {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, bool = std::is_trivially_copy_constructible<T>::value>
|
template <class T, bool = IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
|
||||||
struct optional_copy_base : optional_operations_base<T> {
|
struct optional_copy_base : optional_operations_base<T> {
|
||||||
using optional_operations_base<T>::optional_operations_base;
|
using optional_operations_base<T>::optional_operations_base;
|
||||||
};
|
};
|
||||||
@ -362,11 +379,16 @@ struct optional_copy_base<T, false> : optional_operations_base<T> {
|
|||||||
optional_copy_base &operator=(optional_copy_base &&rhs) = default;
|
optional_copy_base &operator=(optional_copy_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TL_OPTIONAL_GCC49
|
||||||
template <class T, bool = std::is_trivially_move_constructible<T>::value>
|
template <class T, bool = std::is_trivially_move_constructible<T>::value>
|
||||||
struct optional_move_base : optional_copy_base<T> {
|
struct optional_move_base : optional_copy_base<T> {
|
||||||
using optional_copy_base<T>::optional_copy_base;
|
using optional_copy_base<T>::optional_copy_base;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
template <class T, bool = false>
|
||||||
|
struct optional_move_base;
|
||||||
|
#endif
|
||||||
template <class T> struct optional_move_base<T, false> : optional_copy_base<T> {
|
template <class T> struct optional_move_base<T, false> : optional_copy_base<T> {
|
||||||
using optional_copy_base<T>::optional_copy_base;
|
using optional_copy_base<T>::optional_copy_base;
|
||||||
|
|
||||||
@ -385,7 +407,7 @@ template <class T> struct optional_move_base<T, false> : optional_copy_base<T> {
|
|||||||
optional_move_base &operator=(optional_move_base &&rhs) = default;
|
optional_move_base &operator=(optional_move_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, bool = std::is_trivially_copy_constructible<T>::value>
|
template <class T, bool = IS_TRIVIALLY_COPY_ASSIGNABLE(T) && IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) && IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
||||||
struct optional_copy_assign_base : optional_move_base<T> {
|
struct optional_copy_assign_base : optional_move_base<T> {
|
||||||
using optional_move_base<T>::optional_move_base;
|
using optional_move_base<T>::optional_move_base;
|
||||||
};
|
};
|
||||||
@ -399,23 +421,25 @@ struct optional_copy_assign_base<T, false> : optional_move_base<T> {
|
|||||||
|
|
||||||
optional_copy_assign_base(optional_copy_assign_base &&rhs) = default;
|
optional_copy_assign_base(optional_copy_assign_base &&rhs) = default;
|
||||||
optional_copy_assign_base &operator=(const optional_copy_assign_base &rhs) {
|
optional_copy_assign_base &operator=(const optional_copy_assign_base &rhs) {
|
||||||
if (rhs.m_has_value) {
|
this->assign(rhs);
|
||||||
this->assign(rhs.get());
|
|
||||||
} else {
|
|
||||||
this->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
optional_copy_assign_base &
|
optional_copy_assign_base &
|
||||||
operator=(optional_copy_assign_base &&rhs) = default;
|
operator=(optional_copy_assign_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, bool = std::is_trivially_copy_constructible<T>::value>
|
|
||||||
|
#ifndef TL_OPTIONAL_GCC49
|
||||||
|
template <class T, bool = std::is_trivially_destructible<T>::value && std::is_trivially_move_constructible<T>::value && std::is_trivially_move_assignable<T>::value>
|
||||||
struct optional_move_assign_base : optional_copy_assign_base<T> {
|
struct optional_move_assign_base : optional_copy_assign_base<T> {
|
||||||
using optional_copy_assign_base<T>::optional_copy_assign_base;
|
using optional_copy_assign_base<T>::optional_copy_assign_base;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
template <class T, bool = false>
|
||||||
|
struct optional_move_assign_base;
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct optional_move_assign_base<T, false> : optional_copy_assign_base<T> {
|
struct optional_move_assign_base<T, false> : optional_copy_assign_base<T> {
|
||||||
using optional_copy_assign_base<T>::optional_copy_assign_base;
|
using optional_copy_assign_base<T>::optional_copy_assign_base;
|
||||||
|
|
||||||
optional_move_assign_base() = default;
|
optional_move_assign_base() = default;
|
||||||
@ -426,11 +450,8 @@ struct optional_move_assign_base<T, false> : optional_copy_assign_base<T> {
|
|||||||
operator=(const optional_move_assign_base &rhs) noexcept(
|
operator=(const optional_move_assign_base &rhs) noexcept(
|
||||||
std::is_nothrow_move_constructible<T>::value
|
std::is_nothrow_move_constructible<T>::value
|
||||||
&&std::is_nothrow_move_assignable<T>::value) {
|
&&std::is_nothrow_move_assignable<T>::value) {
|
||||||
if (rhs.m_has_value) {
|
this->assign(std::move(rhs));
|
||||||
this->assign(std::move(rhs.get()));
|
|
||||||
} else {
|
|
||||||
this->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
optional_move_assign_base &
|
optional_move_assign_base &
|
||||||
operator=(optional_move_assign_base &&rhs) = default;
|
operator=(optional_move_assign_base &&rhs) = default;
|
||||||
|
Reference in New Issue
Block a user