aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-07-01 16:27:49 -0700
committerChris Robinson <[email protected]>2019-07-01 16:27:49 -0700
commiteb701714334ce3ced479204e93a3ed4894a4af50 (patch)
tree62f4445782823f7a2889b57633f403464c0392b0 /common
parent143ad160518fed792f7616c2c93ab8101d130736 (diff)
Add a few more constructor and assignment operators for optional
Diffstat (limited to 'common')
-rw-r--r--common/aloptional.h38
1 files changed, 35 insertions, 3 deletions
diff --git a/common/aloptional.h b/common/aloptional.h
index 443da0b4..a4b37212 100644
--- a/common/aloptional.h
+++ b/common/aloptional.h
@@ -34,9 +34,25 @@ public:
if(mHasValue)
al::uninitialized_move_n(std::addressof(*rhs), 1, std::addressof(mValue));
}
- template<typename... Args>
- explicit optional(in_place_t, Args&& ...args)
- : mHasValue{true}, mValue{std::forward<Args>(args)...}
+ template<typename... Args, REQUIRES(std::is_constructible<T, Args...>::value)>
+ explicit optional(in_place_t, Args&& ...args) : mHasValue{true}
+ , mValue{std::forward<Args>(args)...}
+ { }
+ template<typename U, typename... Args, REQUIRES(std::is_constructible<T, std::initializer_list<U>&, Args...>::value)>
+ explicit optional(in_place_t, std::initializer_list<U> il, Args&& ...args)
+ : mHasValue{true}, mValue{il, std::forward<Args>(args)...}
+ { }
+ template<typename U=value_type, REQUIRES(std::is_constructible<T, U&&>::value &&
+ !std::is_same<typename std::decay<U>::type, in_place_t>::value &&
+ !std::is_same<typename std::decay<U>::type, optional<T>>::value &&
+ std::is_constructible<U&&, T>::value)>
+ constexpr explicit optional(U&& value) : mHasValue{true}, mValue{std::forward<U>(value)}
+ { }
+ template<typename U=value_type, REQUIRES(std::is_constructible<T, U&&>::value &&
+ !std::is_same<typename std::decay<U>::type, in_place_t>::value &&
+ !std::is_same<typename std::decay<U>::type, optional<T>>::value &&
+ !std::is_constructible<U&&, T>::value)>
+ constexpr optional(U&& value) : mHasValue{true}, mValue{std::forward<U>(value)}
{ }
~optional() { reset(); }
@@ -69,6 +85,22 @@ public:
}
return *this;
}
+ template<typename U=T, REQUIRES(std::is_constructible<T, U>::value &&
+ std::is_assignable<T&, U>::value &&
+ !std::is_same<typename std::decay<U>::type, optional<T>>::value &&
+ (!std::is_same<typename std::decay<U>::type, T>::value ||
+ !std::is_scalar<U>::value))>
+ optional& operator=(U&& rhs)
+ {
+ if(*this)
+ mValue = std::forward<U>(rhs);
+ else
+ {
+ ::new (std::addressof(mValue)) T{std::forward<U>(rhs)};
+ mHasValue = true;
+ }
+ return *this;
+ }
const T* operator->() const { return std::addressof(mValue); }
T* operator->() { return std::addressof(mValue); }