1#ifndef NEFORCE_CORE_UTILITY_OPTIONAL_HPP__
2#define NEFORCE_CORE_UTILITY_OPTIONAL_HPP__
11#include <initializer_list>
17NEFORCE_BEGIN_NAMESPACE__
29struct optional_exception final : memory_exception {
30 explicit optional_exception(
const char* info =
"Access the Null Value of Optional.") noexcept :
31 memory_exception(info) {}
33 explicit optional_exception(
const exception& e) :
34 memory_exception(e) {}
36 ~optional_exception()
override =
default;
38 NEFORCE_NODISCARD
const char*
type() const noexcept
override {
return "optional_exception"; }
54struct is_optional : false_type {};
57struct is_optional<optional<T>> :
true_type {};
60NEFORCE_INLINE17
bool is_optional_v = is_optional<T>::value;
73 "optional do not contains none_t and inplace_construct_tag types.");
75 static_assert(!
is_reference_v<T>,
"optional of reference type should use optional<T&> specialization.");
81 using const_pointer =
const T*;
82 using const_reference =
const T&;
90 using convertible_from_optional =
97 using assignable_from_optional =
101 bool have_value_ =
false;
104 constexpr T* get_ptr()
noexcept {
return reinterpret_cast<T*
>(&storage_); }
105 constexpr const T* get_ptr()
const noexcept {
return reinterpret_cast<const T*
>(&storage_); }
176 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional> &&
177 negation_v<conjunction<is_scalar<T>, is_same<T, decay_t<U>>>> &&
178 is_constructible_v<T, U> && is_assignable_v<T&, U>,
184 *get_ptr() = _NEFORCE
move(temp);
197 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
198 is_convertible_v<const U&, T> && !convertible_from_optional<U>::value,
212 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
213 !is_convertible_v<const U&, T> && !convertible_from_optional<U>::value,
228 template <
typename U = T,
231 !assignable_from_optional<U>::value,
254 if (other.have_value_) {
269 if (other.have_value_) {
287 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> && is_convertible_v<U, T> &&
288 !convertible_from_optional<U>::value,
302 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> && !is_convertible_v<U, T> &&
303 !convertible_from_optional<U>::value,
318 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional> && is_constructible_v<T, U> &&
319 is_assignable_v<T&, U> && !convertible_from_optional<U>::value &&
320 !assignable_from_optional<U>::value,
326 *get_ptr() = _NEFORCE
move(*other);
342 if (other.have_value_) {
359 if (other.have_value_) {
361 *get_ptr() = _NEFORCE
move(*other);
379 template <
typename U, enable_if_t<is_constructible_v<T, U&>,
int> = 0>
393 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
427 template <
typename U,
typename... Types,
460 template <
typename U,
typename... Types,
462 NEFORCE_CONSTEXPR20
void
473 NEFORCE_CONSTEXPR20
void reset() noexcept {
484 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return have_value_; }
490 constexpr explicit operator bool() const noexcept {
return have_value_; }
497 constexpr const_reference
value() const& {
521 constexpr const value_type&&
value() const&& {
525 return _NEFORCE
move(*get_ptr());
537 return _NEFORCE
move(*get_ptr());
561 return _NEFORCE
move(*get_ptr());
570 template <
typename F, enable_if_t<is_invocable_v<F> && is_copy_constructible_v<T>,
int> = 0>
584 template <
typename F, enable_if_t<is_invocable_v<F> && is_move_constructible_v<T>,
int> = 0>
587 return _NEFORCE
move(*
this);
598 template <
typename F>
612 template <
typename F>
626 template <
typename F>
640 template <
typename F>
654 template <
typename F>
668 template <
typename F>
682 template <
typename F>
696 template <
typename F>
708 constexpr const_pointer
operator->() const noexcept {
return get_ptr(); }
714 constexpr pointer
operator->() noexcept {
return get_ptr(); }
720 constexpr const_reference
operator*() const& noexcept {
return *get_ptr(); }
726 constexpr reference
operator*() &
noexcept {
return *get_ptr(); }
732 constexpr const value_type&&
operator*() const&& noexcept {
return _NEFORCE
move(*get_ptr()); }
738 constexpr value_type&&
operator*() &&
noexcept {
return _NEFORCE
move(*get_ptr()); }
746 if (have_value_ != rhs.have_value_) {
750 return *get_ptr() == *rhs.get_ptr();
761 if (!have_value_ || !rhs.have_value_) {
764 return *get_ptr() < *rhs.get_ptr();
768 constexpr bool operator!=(none_t )
const noexcept {
return have_value_; }
769 constexpr bool operator>(none_t )
const noexcept {
return have_value_; }
770 constexpr bool operator<(none_t )
const noexcept {
return false; }
771 constexpr bool operator>=(none_t )
const noexcept {
return true; }
772 constexpr bool operator<=(none_t )
const noexcept {
return !have_value_; }
774 friend constexpr bool operator==(none_t ,
const optional& rhs)
noexcept {
return !rhs.have_value_; }
775 friend constexpr bool operator!=(none_t ,
const optional& rhs)
noexcept {
return rhs.have_value_; }
776 friend constexpr bool operator>(none_t ,
const optional& )
noexcept {
return false; }
777 friend constexpr bool operator<(none_t ,
const optional& rhs)
noexcept {
return rhs.have_value_; }
778 friend constexpr bool operator>=(none_t ,
const optional& rhs)
noexcept {
return !rhs.have_value_; }
779 friend constexpr bool operator<=(none_t ,
const optional& )
noexcept {
return true; }
785 NEFORCE_NODISCARD
constexpr size_t to_hash() const noexcept {
798 if (have_value_ && other.have_value_) {
799 _NEFORCE
swap(*
this, other);
800 }
else if (have_value_) {
801 other.emplace(_NEFORCE
move(**
this));
803 }
else if (other.have_value_) {
834 template <
typename U>
856 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
865 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
874 template <typename U, enable_if_t<convertible_from_optional_ref<U>::value,
int> = 0>
905 template <
typename U = T, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
917 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
955 template <
typename... Types>
969 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
981 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
990 NEFORCE_CONSTEXPR20
void reset() noexcept { ptr_ =
nullptr; }
995 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return ptr_ !=
nullptr; }
1001 constexpr explicit operator bool() const noexcept {
return ptr_ !=
nullptr; }
1009 if (ptr_ ==
nullptr) {
1021 if (ptr_ ==
nullptr) {
1033 if (ptr_ ==
nullptr) {
1045 if (ptr_ ==
nullptr) {
1056 template <
typename U>
1069 template <
typename U>
1072 return _NEFORCE
move(*ptr_);
1083 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1097 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1100 return _NEFORCE
move(*
this);
1111 template <
typename F>
1125 template <
typename F>
1139 template <
typename F>
1153 template <
typename F>
1167 template <
typename F>
1181 template <
typename F>
1195 template <
typename F>
1209 template <
typename F>
1233 constexpr const T&
operator*() const& noexcept {
return *ptr_; }
1245 constexpr const T&&
operator*() const&& noexcept {
return *ptr_; }
1259 if (ptr_ ==
nullptr || rhs.ptr_ ==
nullptr) {
1260 return ptr_ == rhs.ptr_;
1262 return *ptr_ == *rhs.ptr_;
1270 constexpr bool less_than(
const optional& rhs)
const noexcept {
return ptr_ && rhs.ptr_ && *ptr_ < *rhs.ptr_; }
1272 constexpr bool operator==(
none_t )
const noexcept {
return ptr_ ==
nullptr; }
1273 constexpr bool operator!=(none_t )
const noexcept {
return ptr_ !=
nullptr; }
1274 constexpr bool operator>(none_t )
const noexcept {
return ptr_ !=
nullptr; }
1275 constexpr bool operator<(none_t )
const noexcept {
return false; }
1276 constexpr bool operator>=(none_t )
const noexcept {
return true; }
1277 constexpr bool operator<=(none_t )
const noexcept {
return ptr_ ==
nullptr; }
1279 friend constexpr bool operator==(none_t ,
const optional& rhs)
noexcept {
return rhs.ptr_ ==
nullptr; }
1280 friend constexpr bool operator!=(none_t ,
const optional& rhs)
noexcept {
return rhs.ptr_ !=
nullptr; }
1281 friend constexpr bool operator>(none_t ,
const optional& )
noexcept {
return false; }
1282 friend constexpr bool operator<(none_t ,
const optional& rhs)
noexcept {
return rhs.ptr_ !=
nullptr; }
1283 friend constexpr bool operator>=(none_t ,
const optional& rhs)
noexcept {
return rhs.ptr_ ==
nullptr; }
1284 friend constexpr bool operator<=(none_t ,
const optional& )
noexcept {
return true; }
1290 NEFORCE_NODISCARD
constexpr size_t to_hash() const noexcept {
1301#ifdef NEFORCE_STANDARD_17
1302template <
typename T>
1303optional(T) -> optional<T>;
1314template <
typename T,
typename... Args, enable_if_t<is_constructible_v<T, Args...>,
int> = 0>
1328template <
typename T,
typename U,
typename... Args>
1329constexpr enable_if_t<is_constructible_v<T, std::initializer_list<U>&, Args...>, optional<T>>
1343template <
typename T>
1345 return static_cast<const T&
>(
static_cast<const optional<T>&
>(opt).
value());
1355template <
typename T>
1367template <
typename T>
1369 return static_cast<const T&&
>(
static_cast<const optional<T>&&
>(opt).
value());
1379template <
typename T>
1386NEFORCE_END_NAMESPACE__
const T * const_pointer
常量指针类型
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
constexpr void swap(optional &other) noexcept
交换两个可选值
constexpr optional(const _NEFORCE optional< U & > &other) noexcept
从引用可选值隐式转换复制构造
constexpr T * operator->() noexcept
箭头运算符
constexpr optional or_else(F &&f) &&
右值否则操作
constexpr optional(T &value) noexcept
从引用构造
constexpr T & value() &
获取左值引用
constexpr optional(U &value) noexcept
从可转换引用隐式转换构造
constexpr optional(none_t n=none) noexcept
默认构造函数
constexpr optional & operator=(const optional< U & > &other)
从引用可选值赋值(重新绑定)
constexpr auto transform(F &&f) &&-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
右值转换操作
constexpr optional & operator=(const optional &other) noexcept=default
复制赋值运算符
constexpr optional(optional &&other) noexcept
移动构造函数
constexpr auto transform(F &&f) const &-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
常量左值转换操作
constexpr decltype(auto) and_then(F &&f) const &&
常量右值然后操作
constexpr T & operator*() &noexcept
左值解引用运算符
constexpr const T * operator->() const noexcept
常量箭头运算符
constexpr T && value() &&
获取右值引用
constexpr T & emplace(U &value) noexcept
隐式转换原位构造引用
constexpr auto transform(F &&f) const &&-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
常量右值转换操作
constexpr decltype(auto) and_then(F &&f) const &
常量左值然后操作
constexpr bool equal_to(const optional &rhs) const noexcept
等于比较运算符
constexpr T && operator*() &&noexcept
右值解引用运算符
constexpr bool less_than(const optional &rhs) const noexcept
小于比较运算符
constexpr auto transform(F &&f) &-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
左值转换操作
constexpr const T & operator*() const &noexcept
常量左值解引用运算符
constexpr optional or_else(F &&f) const &
常量左值否则操作
constexpr T value_or(U &&value) &&
取出存储的引用的移动值
constexpr decltype(auto) and_then(F &&f) &
左值然后操作
const T & const_reference
常量引用类型
constexpr const T & value() const &
获取常量左值引用
constexpr T value_or(U &&value) const &
取出存储的引用的拷贝值
constexpr const T && value() const &&
获取常量右值引用
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr optional & operator=(none_t n) noexcept
空值赋值运算符
constexpr const T && operator*() const &&noexcept
常量右值解引用运算符
constexpr void reset() noexcept
重置引用
constexpr optional(const optional &other) noexcept=default
复制构造函数
constexpr optional & operator=(optional &&other) noexcept
移动赋值运算符
constexpr bool has_value() const noexcept
检查是否持有引用
constexpr optional & operator=(U &value)
从引用赋值(重新绑定)
optional & operator=(const optional &other)
复制赋值运算符
constexpr auto transform(F &&f) const &&-> optional< remove_cvref_t< decltype(f(_NEFORCE move(*get_ptr())))> >
右值转换操作
constexpr ~optional() noexcept
析构函数
constexpr const_reference value() const &
取出存储的值
optional & operator=(optional &&other) noexcept
移动赋值运算符
constexpr const_pointer operator->() const noexcept
常量箭头运算符
constexpr optional(inplace_construct_tag, Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造
constexpr optional(U &&value) noexcept(is_nothrow_constructible_v< T, U >)
从值隐式转换构造
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 value_type && operator*() &&noexcept
右值解引用运算符
constexpr optional(const optional< U > &other) noexcept(is_nothrow_constructible_v< T, const U & >)
从可选值隐式转换复制构造
constexpr optional(optional< U > &&other) noexcept(is_nothrow_constructible_v< T, U >)
从可选值隐式转换移动构造
constexpr value_type && value() &&
取出存储的值
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
optional(const optional &other)
复制构造函数
constexpr reference operator*() &noexcept
左值解引用运算符
constexpr auto transform(F &&f) &-> optional< remove_cvref_t< decltype(f(*get_ptr()))> >
左值转换操作
constexpr decltype(auto) and_then(F &&f) const &
常量左值然后操作
constexpr reference value() &
取出存储的值
constexpr optional & operator=(const optional< U & > &other)
从引用可选值赋值
constexpr optional(none_t n=none) noexcept
从空值构造
constexpr void emplace(Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造值
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 >)
取出存储的值的移出值
constexpr bool has_value() const noexcept
检查是否包含值
constexpr optional(const optional< U & > &other)
从引用可选值赋值
constexpr const value_type && operator*() const &&noexcept
常量右值解引用运算符
constexpr optional & operator=(none_t n) noexcept
空值赋值运算符
constexpr optional(T &&value) noexcept(is_nothrow_move_constructible_v< T >)
从值移动构造
constexpr void reset() noexcept
重置可选值为空
constexpr decltype(auto) and_then(F &&f) const &&
常量右值然后操作
constexpr optional(const T &value) noexcept(is_nothrow_copy_constructible_v< T >)
从值拷贝构造
constexpr bool equal_to(const optional &rhs) const noexcept
等于比较运算符
constexpr optional or_else(F &&f) &&
右值否则操作
constexpr pointer operator->() noexcept
箭头运算符
constexpr optional or_else(F &&f) const &
常量左值否则操作
constexpr value_type value_or(value_type value) const &noexcept(is_nothrow_copy_constructible_v< value_type >)
取出存储的值的拷贝值
constexpr bool less_than(const optional &rhs) const noexcept
小于比较运算符
optional(optional &&other) noexcept
移动构造函数
constexpr optional & operator=(const optional< U > &other) noexcept(is_nothrow_constructible_v< T, const U & > &&is_nothrow_assignable_v< T &, const U & >)
从可选值复制赋值
constexpr optional & operator=(optional< U > &&other) noexcept(is_nothrow_constructible_v< T, U > &&is_nothrow_assignable_v< T &, U >)
从可选值移动赋值
constexpr optional & operator=(U &&value) noexcept(is_nothrow_constructible_v< T, U > &&is_nothrow_assignable_v< T &, U >)
从值赋值
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr void swap(optional &other) noexcept(is_nothrow_move_constructible_v< T > &&is_nothrow_swappable_v< T >)
交换两个可选值
constexpr void emplace(std::initializer_list< U > ilist, Types &&... args) noexcept(is_nothrow_constructible_v< T, std::initializer_list< U > &, Types... >)
使用初始化列表原位构造值
constexpr const value_type && value() const &&
取出存储的值
constexpr auto transform(F &&f) &&-> optional< remove_cvref_t< decltype(f(_NEFORCE move(*get_ptr())))> >
常量右值转换操作
constexpr const_reference operator*() const &noexcept
常量左值解引用运算符
typename aligned_storage< Len, Align >::type aligned_storage_t
aligned_storage的便捷别名
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
constexpr bool is_reference_v
is_reference的便捷变量模板
constexpr bool is_object_v
is_object的便捷变量模板
constexpr bool is_array_v
is_array的便捷变量模板
constexpr bool is_convertible_v
is_convertible的便捷变量模板
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
constexpr size_t FNV_OFFSET_BASIS
FNV哈希算法的偏移基础值
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr none_t none
默认空表示
constexpr optional< T > make_optional(Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
原位构造可选值
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr bool is_assignable_v
is_assignable的便捷变量模板
constexpr bool is_constructible_v
is_constructible的便捷变量模板
constexpr bool is_nothrow_assignable_v
is_nothrow_assignable的便捷变量模板
constexpr bool is_nothrow_constructible_v
is_nothrow_constructible的便捷变量模板
constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
constexpr bool is_any_of_v
is_any_of的便捷变量模板
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
bool_constant< true > true_type
表示true的类型
const char * type() const noexcept override
获取异常类型