1#ifndef NEFORCE_CORE_UTILITY_OPTIONAL_HPP__
2#define NEFORCE_CORE_UTILITY_OPTIONAL_HPP__
11#include <initializer_list>
16NEFORCE_BEGIN_NAMESPACE__
28struct optional_exception final : memory_exception {
29 explicit optional_exception(
const char* info =
"Access the Null Value of Optional.",
const char*
type = static_type,
30 const int code = 0) noexcept :
31 memory_exception(info,
type,
code) {}
33 explicit optional_exception(
const exception& e) :
34 memory_exception(e) {}
36 ~optional_exception()
override =
default;
37 static constexpr auto static_type =
"optional_exception";
72 "optional do not contains none_t and inplace_construct_tag types.");
74 static_assert(!
is_reference_v<T>,
"optional of reference type should use optional<T&> specialization.");
80 using const_pointer =
const T*;
81 using const_reference =
const T&;
89 using convertible_from_optional =
96 using assignable_from_optional =
100 bool have_value_ =
false;
103 constexpr T* get_ptr()
noexcept {
return reinterpret_cast<T*
>(&storage_); }
104 constexpr const T* get_ptr()
const noexcept {
return reinterpret_cast<const T*
>(&storage_); }
175 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional> &&
176 negation_v<conjunction<is_scalar<T>, is_same<T, decay_t<U>>>> &&
177 is_constructible_v<T, U> && is_assignable_v<T&, U>,
183 *get_ptr() = _NEFORCE
move(temp);
196 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
197 is_convertible_v<const U&, T> && convertible_from_optional<U>::value,
211 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, const U&> &&
212 !is_convertible_v<const U&, T> && convertible_from_optional<U>::value,
227 template <
typename U = T,
256 if (other.have_value_) {
271 if (other.have_value_) {
289 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> && is_convertible_v<U, T> &&
290 convertible_from_optional<U>::value,
304 template <
typename U, enable_if_t<!is_same_v<T, U> && is_constructible_v<T, U> && !is_convertible_v<U, T> &&
305 convertible_from_optional<U>::value,
320 template <
typename U = T, enable_if_t<!is_same_v<remove_cvref_t<U>, optional> && is_constructible_v<T, U> &&
321 is_assignable_v<T&, U> && !convertible_from_optional<U>::value &&
322 !assignable_from_optional<U>::value,
331 *get_ptr() = _NEFORCE
move(*other);
347 if (other.have_value_) {
364 if (other.have_value_) {
366 *get_ptr() = _NEFORCE
move(*other);
384 template <
typename U, enable_if_t<is_constructible_v<T, U&>,
int> = 0>
398 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
432 template <
typename U,
typename... Types,
464 template <
typename U,
typename... Types,
466 NEFORCE_CONSTEXPR20
void
477 NEFORCE_CONSTEXPR20
void reset() noexcept {
488 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return have_value_; }
494 constexpr explicit operator bool() const noexcept {
return have_value_; }
501 constexpr const_reference
value() const& {
525 constexpr const value_type&&
value() const&& {
529 return _NEFORCE
move(*get_ptr());
541 return _NEFORCE
move(*get_ptr());
565 return _NEFORCE
move(*get_ptr());
574 template <
typename F, enable_if_t<is_invocable_v<F> && is_copy_constructible_v<T>,
int> = 0>
588 template <
typename F, enable_if_t<is_invocable_v<F> && is_move_constructible_v<T>,
int> = 0>
591 return _NEFORCE
move(*
this);
602 template <
typename F>
616 template <
typename F>
630 template <
typename F>
644 template <
typename F>
658 template <
typename F>
672 template <
typename F>
686 template <
typename F>
700 template <
typename F>
712 constexpr const_pointer
operator->() const noexcept {
return get_ptr(); }
718 constexpr pointer
operator->() noexcept {
return get_ptr(); }
724 constexpr const_reference
operator*() const& noexcept {
return *get_ptr(); }
730 constexpr reference
operator*() &
noexcept {
return *get_ptr(); }
736 constexpr const value_type&&
operator*() const&& noexcept {
return _NEFORCE
move(*get_ptr()); }
742 constexpr value_type&&
operator*() &&
noexcept {
return _NEFORCE
move(*get_ptr()); }
750 if (have_value_ != rhs.have_value_) {
754 return *get_ptr() == *rhs.get_ptr();
765 if (!have_value_ || !rhs.have_value_) {
768 return *get_ptr() < *rhs.get_ptr();
772 constexpr bool operator!=(none_t)
const noexcept {
return have_value_; }
773 constexpr bool operator>(none_t)
const noexcept {
return have_value_; }
774 constexpr bool operator<(none_t)
const noexcept {
return false; }
775 constexpr bool operator>=(none_t)
const noexcept {
return true; }
776 constexpr bool operator<=(none_t)
const noexcept {
return !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& rhs)
noexcept {
return rhs.have_value_; }
780 friend constexpr bool operator>(none_t,
const optional&)
noexcept {
return false; }
781 friend constexpr bool operator<(none_t,
const optional& rhs)
noexcept {
return rhs.have_value_; }
782 friend constexpr bool operator>=(none_t,
const optional& rhs)
noexcept {
return !rhs.have_value_; }
783 friend constexpr bool operator<=(none_t,
const optional&)
noexcept {
return true; }
790 return have_value_ ?
hash<T>()(*get_ptr()) : constants::FNV_OFFSET_BASIS;
802 if (have_value_ && other.have_value_) {
803 _NEFORCE
swap(*
this, other);
804 }
else if (have_value_) {
805 other.emplace(_NEFORCE
move(**
this));
807 }
else if (other.have_value_) {
838 template <
typename U>
860 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
869 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
878 template <typename U, enable_if_t<convertible_from_optional_ref<U>::value,
int> = 0>
909 template <
typename U = T, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
925 template <
typename U, enable_if_t<is_assignable_v<T&, U&>,
int> = 0>
971 template <
typename... Types>
985 template <
typename U, enable_if_t<is_convertible_v<U&, T&>,
int> = 0>
997 template <
typename U, enable_if_t<!is_convertible_v<U&, T&> && is_constructible_v<T&, U&>,
int> = 0>
1006 NEFORCE_CONSTEXPR20
void reset() noexcept { ptr_ =
nullptr; }
1011 NEFORCE_NODISCARD
constexpr bool has_value() const noexcept {
return ptr_ !=
nullptr; }
1017 constexpr explicit operator bool() const noexcept {
return ptr_ !=
nullptr; }
1072 template <
typename U>
1085 template <
typename U>
1088 return _NEFORCE
move(*ptr_);
1099 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1113 template <
typename F, enable_if_t<is_invocable_v<F>,
int> = 0>
1116 return _NEFORCE
move(*
this);
1127 template <
typename F>
1141 template <
typename F>
1155 template <
typename F>
1169 template <
typename F>
1183 template <
typename F>
1197 template <
typename F>
1211 template <
typename F>
1225 template <
typename F>
1249 constexpr const T&
operator*() const& noexcept {
return *ptr_; }
1261 constexpr const T&&
operator*() const&& noexcept {
return *ptr_; }
1275 if (ptr_ ==
nullptr || rhs.ptr_ ==
nullptr) {
1276 return ptr_ == rhs.ptr_;
1278 return *ptr_ == *rhs.ptr_;
1286 constexpr bool operator<(
const optional& rhs)
const noexcept {
return ptr_ && rhs.ptr_ && *ptr_ < *rhs.ptr_; }
1288 constexpr bool operator==(
none_t)
const noexcept {
return ptr_ ==
nullptr; }
1289 constexpr bool operator!=(
none_t)
const noexcept {
return ptr_ !=
nullptr; }
1290 constexpr bool operator>(
none_t)
const noexcept {
return ptr_ !=
nullptr; }
1293 constexpr bool operator<=(
none_t)
const noexcept {
return ptr_ ==
nullptr; }
1317#ifdef NEFORCE_STANDARD_17
1318template <
typename T>
1329template <
typename T, enable_if_t<is_constructible_v<decay_t<T>, T>,
int> = 0>
1355template <
typename T,
typename U,
typename... Args>
1368template <
typename T>
1376template <
typename T>
1387template <
typename T>
1389 return static_cast<const T&
>(
static_cast<const optional<T>&
>(opt).
value());
1399template <
typename T>
1411template <
typename T>
1413 return static_cast<const T&&
>(
static_cast<const optional<T>&&
>(opt).
value());
1423template <
typename T>
1430NEFORCE_END_NAMESPACE__
NEFORCE_CONSTEXPR20 void reset() noexcept
重置引用
constexpr const T & operator*() const &noexcept
常量左值解引用运算符
constexpr T && operator*() &&noexcept
右值解引用运算符
NEFORCE_CONSTEXPR20 optional & operator=(const optional &other) noexcept=default
复制赋值运算符
const T & const_reference
常量引用类型
NEFORCE_CONSTEXPR20 optional & operator=(optional &&other) noexcept
移动赋值运算符
constexpr auto transform(F &&f) &-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
左值转换操作
constexpr bool operator<(const optional &rhs) const noexcept
小于比较运算符
constexpr T value_or(U &&value) &&
取出存储的引用的移动值
constexpr auto transform(F &&f) const &&-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
常量右值转换操作
constexpr optional(const _NEFORCE optional< U & > &other) noexcept
从引用可选值隐式转换复制构造
constexpr T * operator->() noexcept
箭头运算符
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr optional(U &value) noexcept
从可转换引用隐式转换构造
constexpr T value_or(U &&value) const &
取出存储的引用的拷贝值
NEFORCE_NODISCARD constexpr bool has_value() const noexcept
检查是否持有引用
NEFORCE_CONSTEXPR20 optional & operator=(U &value)
从引用赋值
constexpr const T * operator->() const noexcept
常量箭头运算符
constexpr T & value() &
获取左值引用
constexpr optional(optional &&other) noexcept
移动构造函数
NEFORCE_CONSTEXPR20 T & emplace(U &value) noexcept
隐式转换原位构造引用
constexpr optional(T &value) noexcept
从引用构造
NEFORCE_CONSTEXPR20 optional & operator=(const _NEFORCE optional< U & > &other)
从引用可选值赋值
constexpr const T && value() const &&
获取常量右值引用
constexpr optional(const optional &other) noexcept=default
复制构造函数
constexpr const T & value() const &
获取常量左值引用
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
constexpr bool operator==(const optional &rhs) const noexcept
等于比较运算符
const T * const_pointer
常量指针类型
constexpr auto transform(F &&f) &&-> _NEFORCE 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 &
常量左值然后操作
constexpr const T && operator*() const &&noexcept
常量右值解引用运算符
constexpr auto transform(F &&f) const &-> _NEFORCE optional< remove_cvref_t< decltype(f(*ptr_))> >
常量左值转换操作
constexpr T & operator*() &noexcept
左值解引用运算符
constexpr decltype(auto) and_then(F &&f) &
左值然后操作
constexpr decltype(auto) and_then(F &&f) const &&
常量右值然后操作
constexpr optional or_else(F &&f) const &
常量左值否则操作
NEFORCE_CONSTEXPR20 optional & operator=(none_t n) noexcept
空值赋值运算符
NEFORCE_CONSTEXPR20 void swap(optional &other) noexcept
交换两个可选值
constexpr decltype(auto) and_then(F &&f) &&
右值然后操作
constexpr auto transform(F &&f) const &&-> optional< remove_cvref_t< decltype(f(_NEFORCE move(*get_ptr())))> >
右值转换操作
constexpr value_type && operator*() &&noexcept
右值解引用运算符
constexpr value_type value_or(value_type value) const &noexcept(is_nothrow_copy_constructible_v< value_type >)
取出存储的值的拷贝值
constexpr optional(inplace_construct_tag, std::initializer_list< U > ilist, Types &&... args) noexcept(is_nothrow_constructible_v< T, std::initializer_list< U > &, Types... >)
使用初始化列表原位构造
constexpr auto transform(F &&f) &-> optional< remove_cvref_t< decltype(f(*get_ptr()))> >
左值转换操作
constexpr const_reference operator*() const &noexcept
常量左值解引用运算符
NEFORCE_CONSTEXPR20 optional & operator=(const optional< U & > &other)
从引用可选值赋值
constexpr decltype(auto) and_then(F &&f) const &
常量左值然后操作
constexpr optional(const optional< U & > &other)
从引用可选值赋值
constexpr optional(const T &value) noexcept(is_nothrow_copy_constructible_v< T >)
从值拷贝构造
constexpr optional(U &&value) noexcept(is_nothrow_constructible_v< T, U >)
从值隐式转换构造
NEFORCE_CONSTEXPR20 void reset() noexcept
重置可选值为空
constexpr const value_type && operator*() const &&noexcept
常量右值解引用运算符
optional(const optional &other)
复制构造函数
constexpr optional(optional< U > &&other) noexcept(is_nothrow_constructible_v< T, U >)
从可选值隐式转换移动构造
NEFORCE_CONSTEXPR20 void emplace(Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造值
constexpr reference operator*() &noexcept
左值解引用运算符
constexpr auto transform(F &&f) &&-> optional< remove_cvref_t< decltype(f(_NEFORCE move(*get_ptr())))> >
常量右值转换操作
constexpr size_t to_hash() const noexcept
计算哈希值
optional & operator=(optional &&other) noexcept
移动赋值运算符
NEFORCE_NODISCARD constexpr bool has_value() const noexcept
检查是否包含值
constexpr optional(const optional< U > &other) noexcept(is_nothrow_constructible_v< T, const U & >)
从可选值隐式转换复制构造
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 >)
取出存储的值的移出值
NEFORCE_CONSTEXPR20 optional & operator=(optional< U > &&other) noexcept(is_nothrow_constructible_v< T, U > &&is_nothrow_assignable_v< T &, U >)
从可选值移动赋值
optional & operator=(const optional &other)
复制赋值运算符
constexpr optional or_else(F &&f) const &
常量左值否则操作
NEFORCE_CONSTEXPR20 optional & operator=(none_t n) noexcept
空值赋值运算符
constexpr value_type && value() &&
取出存储的值
constexpr const_pointer operator->() const noexcept
常量箭头运算符
constexpr optional or_else(F &&f) &&
右值否则操作
NEFORCE_CONSTEXPR20 optional & operator=(const optional< U > &other) noexcept(is_nothrow_constructible_v< T, const U & > &&is_nothrow_assignable_v< T &, const U & >)
从可选值复制赋值
constexpr optional(inplace_construct_tag, Types &&... args) noexcept(is_nothrow_constructible_v< T, Types... >)
原位构造
NEFORCE_CONSTEXPR20 ~optional() noexcept
析构函数
constexpr decltype(auto) and_then(F &&f) &
左值然后操作
NEFORCE_CONSTEXPR20 void emplace(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 optional(T &&value) noexcept(is_nothrow_move_constructible_v< T >)
从值移动构造
constexpr const_reference value() const &
取出存储的值
constexpr bool operator==(const optional &rhs) const noexcept
等于比较运算符
NEFORCE_CONSTEXPR20 void swap(optional &other) noexcept(is_nothrow_move_constructible_v< T > &&is_nothrow_swappable_v< T >)
交换两个可选值
constexpr pointer operator->() noexcept
箭头运算符
NEFORCE_CONSTEXPR20 optional & operator=(U &&value) noexcept(is_nothrow_constructible_v< T, U > &&is_nothrow_assignable_v< T &, U >)
从值赋值
constexpr const value_type && value() const &&
取出存储的值
constexpr reference value() &
取出存储的值
constexpr bool operator<(const optional &rhs) const noexcept
小于比较运算符
optional(optional &&other) noexcept
移动构造函数
typename aligned_storage< Len, Align >::type aligned_storage_t
aligned_storage的便捷别名
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 constexpr bool is_reference_v
is_reference的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_array_v
is_array的便捷变量模板
NEFORCE_INLINE17 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
等于空指针比较
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
NEFORCE_INLINE17 constexpr none_t none
默认空表示
NEFORCE_NODISCARD constexpr bool operator<=(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于等于比较运算符
NEFORCE_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
NEFORCE_NODISCARD constexpr bool operator>(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
大于比较运算符
NEFORCE_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) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_assignable_v
is_nothrow_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_constructible_v
is_nothrow_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_assignable_v
is_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_constructible_v
is_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_any_of_v
is_any_of的便捷变量模板
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数
NEFORCE_NODISCARD int code() const noexcept
获取异常码
NEFORCE_NODISCARD const char * type() const noexcept
获取异常类型
static constexpr bool value