aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-07-01 17:34:02 -0700
committerChris Robinson <[email protected]>2019-07-01 17:55:56 -0700
commitbc1d058d2d37bc67e93e30080e8d4d4c2be38edd (patch)
treefa55a06983d5a50073302604ace0caf34590a561
parent6bb0edf0a57bdb95c017db986f76eddbc80857e1 (diff)
Add a helper to construct the optional value
-rw-r--r--common/aloptional.h47
1 files changed, 18 insertions, 29 deletions
diff --git a/common/aloptional.h b/common/aloptional.h
index 8524a2e2..2ed882e4 100644
--- a/common/aloptional.h
+++ b/common/aloptional.h
@@ -17,23 +17,28 @@ constexpr in_place_t in_place{};
template<typename T>
class optional {
+ bool mHasValue{false};
+ union {
+ char mDummy[sizeof(T)]{};
+ T mValue;
+ };
+
+ template<typename... Args>
+ void DoConstruct(Args&& ...args)
+ {
+ ::new (std::addressof(mValue)) T{std::forward<Args>(args)...};
+ mHasValue = true;
+ }
+
public:
using value_type = T;
optional() noexcept = default;
optional(nullopt_t) noexcept { }
template<REQUIRES(std::is_copy_constructible<T>::value)>
- optional(const optional &rhs) : mHasValue{rhs.mHasValue}
- {
- if(mHasValue)
- std::uninitialized_copy_n(std::addressof(*rhs), 1, std::addressof(mValue));
- }
+ optional(const optional &rhs) { if(rhs) DoConstruct(*rhs); }
template<REQUIRES(std::is_move_constructible<T>::value)>
- optional(optional&& rhs) : mHasValue{rhs.mHasValue}
- {
- if(mHasValue)
- al::uninitialized_move_n(std::addressof(*rhs), 1, std::addressof(mValue));
- }
+ optional(optional&& rhs) { if(rhs) DoConstruct(std::move(*rhs)); }
template<typename... Args, REQUIRES(std::is_constructible<T, Args...>::value)>
explicit optional(in_place_t, Args&& ...args) : mHasValue{true}
, mValue{std::forward<Args>(args)...}
@@ -65,10 +70,7 @@ public:
else if(*this)
mValue = *rhs;
else
- {
- std::uninitialized_copy_n(std::addressof(*rhs), 1, std::addressof(mValue));
- mHasValue = true;
- }
+ DoConstruct(*rhs);
return *this;
}
template<REQUIRES(std::is_move_constructible<T>::value && std::is_move_assignable<T>::value)>
@@ -79,10 +81,7 @@ public:
else if(*this)
mValue = std::move(*rhs);
else
- {
- al::uninitialized_move_n(std::addressof(*rhs), 1, std::addressof(mValue));
- mHasValue = true;
- }
+ DoConstruct(std::move(*rhs));
return *this;
}
template<typename U=T, REQUIRES(std::is_constructible<T, U>::value &&
@@ -95,10 +94,7 @@ public:
if(*this)
mValue = std::forward<U>(rhs);
else
- {
- ::new (std::addressof(mValue)) T{std::forward<U>(rhs)};
- mHasValue = true;
- }
+ DoConstruct(std::forward<U>(rhs));
return *this;
}
@@ -130,13 +126,6 @@ public:
al::destroy_at(std::addressof(mValue));
mHasValue = false;
}
-
-private:
- bool mHasValue{false};
- union {
- char mDummy[sizeof(T)]{};
- T mValue;
- };
};
template<typename T>