13 template<
typename BaseType>
15 using Storage =
typename std::aligned_storage<sizeof(BaseType), std::alignment_of<BaseType>::value>::type;
31 new(&m_storage) BaseType(*src);
37 new(&m_storage) BaseType(std::move(*src));
41 template<
typename U = BaseType,
typename =
42 typename std::enable_if<
43 std::is_constructible<BaseType, U &&>::value &&
44 !(std::is_same<typename std::decay<U>::type,
self_type>::value)
47 Optional(U &&value) : m_valid(
true) {
48 new(&m_storage) BaseType(std::forward<U>(value));
51 template<
typename... Args,
typename =
typename std::enable_if<std::is_constructible<BaseType, Args...>::value>::type>
53 new(&m_storage) BaseType(std::forward<Args>(args)...);
56 Optional &operator=(Optional &&src) noexcept {
59 **
this = std::move(*src);
61 new(&m_storage) BaseType(std::move(*src));
65 reinterpret_cast<BaseType *
>(&m_storage)->~BaseType();
72 Optional &operator=(
const Optional &src) {
77 new(&m_storage) BaseType(*src);
81 reinterpret_cast<BaseType *
>(&m_storage)->~BaseType();
88 template<
typename U = BaseType,
typename =
89 typename std::enable_if<
90 !std::is_same<typename std::decay<U>::type,
self_type>::value &&
91 std::is_constructible<BaseType, U>::value &&
92 std::is_assignable<BaseType &, U>::value
94 Optional &operator=(U &&value) {
96 **
this = std::forward<U>(value);
98 new(&m_storage) BaseType(std::forward<U>(value));
107 (**this).BaseType::~BaseType();
112 constexpr
explicit operator bool()
const {
116 constexpr
bool has_value()
const {
120 constexpr
bool valid()
const {
124 BaseType &operator*() &{
126 return *
reinterpret_cast<BaseType *
>(&m_storage);
129 const BaseType &operator*()
const &{
131 return *
reinterpret_cast<const BaseType *
>(&m_storage);
134 BaseType &&operator*() &&{
136 return std::move(*reinterpret_cast<BaseType *>(&m_storage));
139 const BaseType &&operator*()
const &&{
141 return std::move(*reinterpret_cast<BaseType *>(&m_storage));
144 BaseType *operator->() {
146 return reinterpret_cast<BaseType *
>(&m_storage);
149 const BaseType *operator->()
const {
151 return reinterpret_cast<const BaseType *
>(&m_storage);
156 throw std::logic_error(
"bad_optional_access");
162 const BaseType &value()
const {
164 throw std::logic_error(
"bad_optional_access");
171 BaseType value_or(U &&default_value) &&{
172 return has_value() ? std::move(**
this) :
static_cast<BaseType
>(std::forward<U>(default_value));
176 const BaseType value_or(U &&default_value)
const &{
177 return has_value() ? **
this :
static_cast<BaseType
>(std::forward<U>(default_value));
180 template<
typename... Args>
181 BaseType &emplace(Args &&... args) {
184 new(&m_storage) BaseType(std::forward<Args>(args)...);
196 template<
typename T,
typename... Args>
197 Optional<T> make_optional(Args &&... args) {
198 return Optional<T>(In_place_t{}, std::forward<Args>(args)...);
Definition: Optional.h:14