1#ifndef MSTL_CORE_UTILITY_OPTIONAL_HPP__
2#define MSTL_CORE_UTILITY_OPTIONAL_HPP__
15#include <initializer_list>
52 "optional do not contains none_t and inplace_construct_tag types.");
53 static_assert(is_object_v<T> && !is_array_v<T>,
"optional only contains non-array object types.");
54 static_assert(!is_reference_v<T>,
"optional of reference type should use optional<T&> specialization.");
84 bool have_value_ =
false;
87 constexpr T* get_ptr()
noexcept {
88 return reinterpret_cast<T*
>(&storage_);
90 constexpr const T* get_ptr()
const noexcept {
91 return reinterpret_cast<const T*
>(&storage_);
94 template <
typename... Args>
95 void construct_value(Args&&... args) {
100 void destroy_value()
noexcept {
132 is_valid_optional<U>::value && !is_same_v<remove_cvref_t<U>,
optional> &&
133 is_constructible_v<T, U> && is_convertible_v<U, T>,
int
136 : have_value_(true) {
146 is_valid_optional<U>::value && !is_same_v<remove_cvref_t<U>,
optional> &&
147 is_constructible_v<T, U> && !is_convertible_v<U, T>,
int
150 : have_value_(true) {
160 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional>
161 && negation_v<conjunction<is_scalar<T>, is_same<T, decay_t<U>>>>
162 && is_constructible_v<T, U> && is_assignable_v<T&, U>,
int> = 0>
164 noexcept(is_nothrow_constructible_v<T, U> && is_nothrow_assignable_v<T&, U>) {
180 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
181 is_convertible_v<const U&, T> && convertible_from_optional<U>::value,
int> = 0>
194 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
195 !is_convertible_v<const U&, T> && convertible_from_optional<U>::value,
int> = 0>
209 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional>
210 && is_constructible_v<T, const U&> && is_assignable_v<T&, const U&>
211 && !convertible_from_optional<U>::value && !assignable_from_optional<U>::value,
int> = 0>
213 noexcept(is_nothrow_constructible_v<T, const U&> && is_nothrow_assignable_v<T&, const U&>) {
233 if (other.have_value_) {
246 if (other.have_value_) {
264 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> &&
265 is_convertible_v<U, T> && convertible_from_optional<U>::value,
int> = 0>
278 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> &&
279 !is_convertible_v<U, T> && convertible_from_optional<U>::value,
int> = 0>
293 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional>
294 && is_constructible_v<T, U> && is_assignable_v<T&, U>
295 && !convertible_from_optional<U>::value && !assignable_from_optional<U>::value,
int> = 0>
297 noexcept(is_nothrow_constructible_v<T, U> && is_nothrow_assignable_v<T&, U>) {
317 if (other.have_value_) {
330 if (
this != &other) {
331 if (other.have_value_) {
352 template <
typename U, enable_if_t<is_constructible_v<T, U&>,
int> = 0>
366 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
386 template <
typename ...Types,
enable_if_t<is_constructible_v<T, Types...>,
int> = 0>
388 noexcept(is_nothrow_constructible_v<T, Types...>)
389 : have_value_(true) {
402 noexcept(is_nothrow_constructible_v<T, std::initializer_list<U>&, Types...>)
403 : have_value_(true) {
419 template <
typename... Types,
enable_if_t<is_constructible_v<T, Types...>,
int> = 0>
420 MSTL_CONSTEXPR20
void emplace(Types&&... args)
421 noexcept(is_nothrow_constructible_v<T, Types...>) {
434 template <
typename U,
typename... Types,
436 MSTL_CONSTEXPR20
void emplace(std::initializer_list<U> ilist, Types&&... args)
437 noexcept(is_nothrow_constructible_v<T, std::initializer_list<U>&, Types...>) {
446 MSTL_CONSTEXPR20
void reset() noexcept {
454 MSTL_NODISCARD
constexpr bool has_value() const noexcept {
462 constexpr explicit operator bool() const noexcept {
471 constexpr const_reference
value() const & {
495 constexpr const value_type&&
value() const && {
520 noexcept(is_nothrow_copy_constructible_v<value_type>) {
533 noexcept(is_nothrow_move_constructible_v<value_type>) {
547 is_invocable_v<F> && is_copy_constructible_v<T>,
int> = 0>
562 is_invocable_v<F> && is_move_constructible_v<T>,
int> = 0>
576 template <
typename F>
590 template <
typename F>
604 template <
typename F>
605 constexpr decltype(
auto)
and_then(F&& f)
const && {
618 template <
typename F>
632 template <
typename F>
646 template <
typename F>
660 template <
typename F>
674 template <
typename F>
686 constexpr const_pointer operator ->() const noexcept {
return get_ptr(); }
692 constexpr pointer operator ->() noexcept {
return get_ptr(); }
698 constexpr const_reference
operator *() const & noexcept {
return *get_ptr(); }
704 constexpr reference
operator *() &
noexcept {
return *get_ptr(); }
724 if (have_value_ != rhs.have_value_) {
728 return *get_ptr() == *rhs.get_ptr();
739 if (!have_value_ || !rhs.have_value_) {
742 return *get_ptr() < *rhs.get_ptr();
753 return !rhs.have_value_;
756 return rhs.have_value_;
762 return rhs.have_value_;
765 return !rhs.have_value_;
784 noexcept(is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>) {
786 if (have_value_ && other.have_value_) {
788 }
else if (have_value_) {
791 }
else if (other.have_value_) {
809 static_assert(is_object_v<T> && !is_array_v<T>,
"optional<T&> requires T to be an object type.");
821 template <
typename U>
844 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
852 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
861 convertible_from_optional_ref<U>::value,
int> = 0>
870 !convertible_from_optional_ref<U>::value && is_constructible_v<T&, U&>,
int> = 0>
891 template <
typename U = T, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
907 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
952 template <
typename... Types>
968 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
980 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
989 MSTL_CONSTEXPR20
void reset() noexcept { ptr_ =
nullptr; }
994 MSTL_NODISCARD
constexpr bool has_value() const noexcept {
return ptr_ !=
nullptr; }
1000 constexpr explicit operator bool() const noexcept {
return ptr_ !=
nullptr; }
1055 template <
typename U>
1057 if (ptr_)
return *ptr_;
1066 template <
typename U>
1078 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1080 if (ptr_)
return *
this;
1090 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1102 template <
typename F>
1114 template <
typename F>
1126 template <
typename F>
1138 template <
typename F>
1150 template <
typename F>
1162 template <
typename F>
1174 template <
typename F>
1186 template <
typename F>
1208 constexpr const T&
operator *() const & noexcept {
return *ptr_; }
1220 constexpr const T&&
operator *() const && noexcept {
return *ptr_; }
1234 if (ptr_ ==
nullptr || rhs.ptr_ ==
nullptr) {
1235 return ptr_ == rhs.ptr_;
1237 return *ptr_ == *rhs.ptr_;
1246 return ptr_ && rhs.ptr_ && *ptr_ < *rhs.ptr_;
1251 constexpr bool operator >(
none_t)
const noexcept {
return ptr_ !=
nullptr; }
1257 return rhs.ptr_ ==
nullptr;
1260 return rhs.ptr_ !=
nullptr;
1266 return rhs.ptr_ !=
nullptr;
1269 return rhs.ptr_ ==
nullptr;
1292#ifdef MSTL_SUPPORT_DEDUCTION_GUIDES__
1293template <
typename T>
1304template <
typename T, enable_if_t<is_constructible_v<decay_t<T>, T>,
int> = 0>
1306noexcept(is_nothrow_constructible_v<optional<decay_t<T>>, T>) {
1317template <
typename T,
typename... Args,
enable_if_t<is_constructible_v<T, Args...>,
int> = 0>
1319noexcept(is_nothrow_constructible_v<T, Args...>) {
1332template <
typename T,
typename U,
typename... Args>
1335noexcept(is_nothrow_constructible_v<T, std::initializer_list<U>&, Args...>) {
1345template <
typename T>
1353template <
typename T>
1364template <
typename T>
1366 return static_cast<const T&
>(
static_cast<const optional<T>&
>(opt).
value());
1376template <
typename T>
1388template <
typename T>
1390 return static_cast<const T&&
>(
static_cast<const optional<T>&&
>(opt).
value());
1400template <
typename T>
const T & const_reference
常量引用类型
constexpr optional(const _MSTL optional< U & > &other) noexcept
从引用可选值隐式转换复制构造
MSTL_CONSTEXPR20 void swap(optional &other) noexcept
交换两个可选值
constexpr T value_or(U &&value) &&
取出存储的引用的移动值
constexpr auto transform(F &&f) const &&-> _MSTL optional< remove_cvref_t< decltype(f(*ptr_))> >
常量右值转换操作
constexpr size_t to_hash() const noexcept
计算哈希值
MSTL_NODISCARD constexpr bool has_value() const noexcept
检查是否持有引用
constexpr optional(U &value) noexcept
从可转换引用隐式转换构造
constexpr T value_or(U &&value) const &
取出存储的引用的拷贝值
MSTL_CONSTEXPR20 void reset() noexcept
重置引用
constexpr auto transform(F &&f) &-> _MSTL optional< remove_cvref_t< decltype(f(*ptr_))> >
左值转换操作
constexpr T & value() &
获取左值引用
constexpr optional(optional &&other) noexcept
移动构造函数
constexpr optional(T &value) noexcept
从引用构造
constexpr const T && value() const &&
获取常量右值引用
constexpr auto transform(F &&f) const &-> _MSTL optional< remove_cvref_t< decltype(f(*ptr_))> >
常量左值转换操作
constexpr optional(const optional &other) noexcept=default
复制构造函数
constexpr const T & value() const &
获取常量左值引用
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
const T * const_pointer
常量指针类型
constexpr auto transform(F &&f) &&-> _MSTL optional< remove_cvref_t< decltype(f(*ptr_))> >
右值转换操作
constexpr optional(none_t n=none) noexcept
默认构造函数
constexpr optional or_else(F &&f) &&
右值否则操作
constexpr T && value() &&
获取右值引用
constexpr decltype(auto) and_then(F &&f) const &
常量左值然后操作
MSTL_CONSTEXPR20 T & emplace(U &value) noexcept
隐式转换原位构造引用
constexpr decltype(auto) and_then(F &&f) &
左值然后操作
constexpr decltype(auto) and_then(F &&f) const &&
常量右值然后操作
constexpr optional or_else(F &&f) const &
常量左值否则操作
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
constexpr value_type value_or(value_type value) const &noexcept(is_nothrow_copy_constructible_v< value_type >)
取出存储的值的拷贝值
constexpr auto transform(F &&f) &-> optional< remove_cvref_t< decltype(f(*get_ptr()))> >
左值转换操作
constexpr auto transform(F &&f) &&-> optional< remove_cvref_t< decltype(f(_MSTL move(*get_ptr())))> >
常量右值转换操作
constexpr decltype(auto) and_then(F &&f) const &
常量左值然后操作
constexpr optional(const optional< U & > &other)
从引用可选值赋值
MSTL_CONSTEXPR20 void emplace(Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造值
constexpr optional(U &&value) noexcept(is_nothrow_constructible_v< T, U >)
从值隐式转换构造
optional(const optional &other)
复制构造函数
constexpr optional(optional< U > &&other) noexcept(is_nothrow_constructible_v< T, U >)
从可选值隐式转换移动构造
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr optional(const optional< U > &other) noexcept(is_nothrow_constructible_v< T, const U & >)
从可选值隐式转换复制构造
MSTL_CONSTEXPR20 void swap(optional &other) noexcept(is_nothrow_move_constructible_v< T > &&is_nothrow_swappable_v< T >)
交换两个可选值
constexpr auto transform(F &&f) const &-> optional< remove_cvref_t< decltype(f(*get_ptr()))> >
常量左值转换操作
constexpr value_type value_or(value_type value) &&noexcept(is_nothrow_move_constructible_v< value_type >)
取出存储的值的移出值
MSTL_CONSTEXPR20 ~optional() noexcept
析构函数
MSTL_CONSTEXPR20 optional & operator=(none_t n) noexcept
空值赋值运算符
constexpr optional or_else(F &&f) const &
常量左值否则操作
MSTL_NODISCARD constexpr bool has_value() const noexcept
检查是否包含值
constexpr value_type && value() &&
取出存储的值
MSTL_CONSTEXPR20 void emplace(std::initializer_list< U > ilist, Types &&... args) noexcept(is_nothrow_constructible_v< T, std::initializer_list< U > &, Types... >)
使用初始化列表原位构造值
constexpr const_pointer operator->() const noexcept
常量箭头运算符
constexpr optional or_else(F &&f) &&
右值否则操作
constexpr optional(inplace_construct_tag, Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造
constexpr decltype(auto) and_then(F &&f) &
左值然后操作
constexpr optional(inplace_construct_tag, std::initializer_list< U > ilist, Types &&...args) noexcept(is_nothrow_constructible_v< T, std::initializer_list< U > &, Types... >)
使用初始化列表原位构造
constexpr decltype(auto) and_then(F &&f) const &&
常量右值然后操作
constexpr optional(none_t n=none) noexcept
从空值构造
constexpr const_reference value() const &
取出存储的值
constexpr auto transform(F &&f) const &&-> optional< remove_cvref_t< decltype(f(_MSTL move(*get_ptr())))> >
右值转换操作
constexpr const value_type && value() const &&
取出存储的值
constexpr reference value() &
取出存储的值
MSTL_CONSTEXPR20 void reset() noexcept
重置可选值为空
optional(optional &&other) noexcept
移动构造函数
typename aligned_storage< Len, Align >::type aligned_storage_t
aligned_storage的便捷别名
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr duration< _INNER __common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
#define MSTL_ERROR_BUILD_FINAL_CLASS(THIS, BASE, INFO)
构建最终异常类宏
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
MSTL_CONSTEXPR20 enable_if_t< is_constructible_v< T, Args... >, void * > construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
MSTL_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
#define _MSTL
全局命名空间MSTL前缀
#define _CONSTANTS
constants命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL_INLINE17 constexpr none_t none
默认空表示
MSTL_NODISCARD constexpr bool operator<=(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于等于比较运算符
MSTL_NODISCARD constexpr bool operator>=(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
大于等于比较运算符
MSTL_NODISCARD constexpr bool operator>(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
大于比较运算符
MSTL_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
constexpr optional< decay_t< T > > make_optional(T &&value) noexcept(is_nothrow_constructible_v< optional< decay_t< T > >, T >)
从值创建可选值
constexpr const T & get(const optional< T > &opt)
获取可选值中的值
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名