forked from OSchip/llvm-project
[libc++][spaceship] Implement std::variant::operator<=>
Implements [variant.relops] and [variant.monostate.relops] for P1614R2 Reviewed By: Mordante, #libc, avogelsgesang Differential Revision: https://reviews.llvm.org/D131372
This commit is contained in:
parent
b2ac153ba4
commit
c4566cac49
|
@ -25,7 +25,7 @@ Section,Description,Dependencies,Assignee,Complete
|
||||||
| nullopt",None,Kent Ross,|In Progress|
|
| nullopt",None,Kent Ross,|In Progress|
|
||||||
"| `[variant.relops] <https://wg21.link/variant.relops>`_
|
"| `[variant.relops] <https://wg21.link/variant.relops>`_
|
||||||
| `[variant.monostate.relops] <https://wg21.link/variant.monostate.relops>`_","| `monostate <https://reviews.llvm.org/D131372>`_
|
| `[variant.monostate.relops] <https://wg21.link/variant.monostate.relops>`_","| `monostate <https://reviews.llvm.org/D131372>`_
|
||||||
| `variant <https://reviews.llvm.org/D131372>`_",None,Kent Ross,|In Progress|
|
| `variant <https://reviews.llvm.org/D131372>`_",None,Kent Ross,|Complete|
|
||||||
| `[unique.ptr.special] <https://wg21.link/unique.ptr.special>`_,| `unique_ptr <https://reviews.llvm.org/D130838>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
|
| `[unique.ptr.special] <https://wg21.link/unique.ptr.special>`_,| `unique_ptr <https://reviews.llvm.org/D130838>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
|
||||||
| `[util.smartptr.shared.cmp] <https://wg21.link/util.smartptr.shared.cmp>`_,| `shared_ptr <https://reviews.llvm.org/D130852>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
|
| `[util.smartptr.shared.cmp] <https://wg21.link/util.smartptr.shared.cmp>`_,| `shared_ptr <https://reviews.llvm.org/D130852>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
|
||||||
| `[type.index.members] <https://wg21.link/type.index.members>`_,| `type_index <https://reviews.llvm.org/D131357>`_,None,Adrian Vogelsgesang,|Complete|
|
| `[type.index.members] <https://wg21.link/type.index.members>`_,| `type_index <https://reviews.llvm.org/D131357>`_,None,Adrian Vogelsgesang,|Complete|
|
||||||
|
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef _LIBCPP___VARIANT_MONOSTATE_H
|
#ifndef _LIBCPP___VARIANT_MONOSTATE_H
|
||||||
#define _LIBCPP___VARIANT_MONOSTATE_H
|
#define _LIBCPP___VARIANT_MONOSTATE_H
|
||||||
|
|
||||||
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/hash.h>
|
#include <__functional/hash.h>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -24,31 +25,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
struct _LIBCPP_TEMPLATE_VIS monostate {};
|
struct _LIBCPP_TEMPLATE_VIS monostate {};
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
||||||
constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
# if _LIBCPP_STD_VER > 17
|
||||||
constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(monostate, monostate) noexcept {
|
||||||
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
|
return strong_ordering::equal;
|
||||||
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
# else // _LIBCPP_STD_VER > 17
|
||||||
constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
||||||
constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
||||||
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(monostate, monostate) noexcept { return true; }
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER > 17
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
|
struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
|
||||||
using argument_type = monostate;
|
using argument_type = monostate;
|
||||||
using result_type = size_t;
|
using result_type = size_t;
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_HIDE_FROM_ABI result_type operator()(const argument_type&) const _NOEXCEPT {
|
||||||
result_type operator()(const argument_type&) const _NOEXCEPT {
|
|
||||||
return 66740831; // return a fundamentally attractive random value.
|
return 66740831; // return a fundamentally attractive random value.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -165,6 +165,10 @@ namespace std {
|
||||||
template <class... Types>
|
template <class... Types>
|
||||||
constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
|
constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
|
||||||
|
|
||||||
|
template <class... Types>
|
||||||
|
constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
|
||||||
|
operator<=>(const variant<Types...>&, const variant<Types...>&); // since C++20
|
||||||
|
|
||||||
// 20.7.6, visitation
|
// 20.7.6, visitation
|
||||||
template <class Visitor, class... Variants>
|
template <class Visitor, class... Variants>
|
||||||
constexpr see below visit(Visitor&&, Variants&&...);
|
constexpr see below visit(Visitor&&, Variants&&...);
|
||||||
|
@ -176,12 +180,13 @@ namespace std {
|
||||||
struct monostate;
|
struct monostate;
|
||||||
|
|
||||||
// 20.7.8, monostate relational operators
|
// 20.7.8, monostate relational operators
|
||||||
constexpr bool operator<(monostate, monostate) noexcept;
|
|
||||||
constexpr bool operator>(monostate, monostate) noexcept;
|
|
||||||
constexpr bool operator<=(monostate, monostate) noexcept;
|
|
||||||
constexpr bool operator>=(monostate, monostate) noexcept;
|
|
||||||
constexpr bool operator==(monostate, monostate) noexcept;
|
constexpr bool operator==(monostate, monostate) noexcept;
|
||||||
constexpr bool operator!=(monostate, monostate) noexcept;
|
constexpr bool operator!=(monostate, monostate) noexcept; // until C++20
|
||||||
|
constexpr bool operator<(monostate, monostate) noexcept; // until C++20
|
||||||
|
constexpr bool operator>(monostate, monostate) noexcept; // until C++20
|
||||||
|
constexpr bool operator<=(monostate, monostate) noexcept; // until C++20
|
||||||
|
constexpr bool operator>=(monostate, monostate) noexcept; // until C++20
|
||||||
|
constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // since C++20
|
||||||
|
|
||||||
// 20.7.9, specialized algorithms
|
// 20.7.9, specialized algorithms
|
||||||
template <class... Types>
|
template <class... Types>
|
||||||
|
@ -201,6 +206,9 @@ namespace std {
|
||||||
|
|
||||||
#include <__assert> // all public C++ headers provide the assertion handler
|
#include <__assert> // all public C++ headers provide the assertion handler
|
||||||
#include <__availability>
|
#include <__availability>
|
||||||
|
#include <__compare/common_comparison_category.h>
|
||||||
|
#include <__compare/compare_three_way_result.h>
|
||||||
|
#include <__compare/three_way_comparable.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/hash.h>
|
#include <__functional/hash.h>
|
||||||
#include <__functional/operations.h>
|
#include <__functional/operations.h>
|
||||||
|
@ -262,7 +270,7 @@ struct __farray {
|
||||||
};
|
};
|
||||||
|
|
||||||
_LIBCPP_NORETURN
|
_LIBCPP_NORETURN
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
void __throw_bad_variant_access() {
|
void __throw_bad_variant_access() {
|
||||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||||
|
@ -373,7 +381,7 @@ __as_variant(const variant<_Types...>&& __vs) noexcept {
|
||||||
namespace __find_detail {
|
namespace __find_detail {
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr size_t __find_index() {
|
constexpr size_t __find_index() {
|
||||||
constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
|
constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
|
||||||
size_t __result = __not_found;
|
size_t __result = __not_found;
|
||||||
|
@ -418,7 +426,7 @@ constexpr _Trait __trait =
|
||||||
? _Trait::_TriviallyAvailable
|
? _Trait::_TriviallyAvailable
|
||||||
: _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
|
: _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
|
constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
|
||||||
_Trait __result = _Trait::_TriviallyAvailable;
|
_Trait __result = _Trait::_TriviallyAvailable;
|
||||||
for (_Trait __t : __traits) {
|
for (_Trait __t : __traits) {
|
||||||
|
@ -457,13 +465,13 @@ namespace __access {
|
||||||
|
|
||||||
struct __union {
|
struct __union {
|
||||||
template <class _Vp>
|
template <class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
|
static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
|
||||||
return _VSTD::forward<_Vp>(__v).__head;
|
return _VSTD::forward<_Vp>(__v).__head;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Vp, size_t _Ip>
|
template <class _Vp, size_t _Ip>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
|
static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
|
||||||
return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
|
return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
|
||||||
}
|
}
|
||||||
|
@ -471,7 +479,7 @@ struct __union {
|
||||||
|
|
||||||
struct __base {
|
struct __base {
|
||||||
template <size_t _Ip, class _Vp>
|
template <size_t _Ip, class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto&& __get_alt(_Vp&& __v) {
|
static constexpr auto&& __get_alt(_Vp&& __v) {
|
||||||
return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
|
return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
|
||||||
in_place_index<_Ip>);
|
in_place_index<_Ip>);
|
||||||
|
@ -480,7 +488,7 @@ struct __base {
|
||||||
|
|
||||||
struct __variant {
|
struct __variant {
|
||||||
template <size_t _Ip, class _Vp>
|
template <size_t _Ip, class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto&& __get_alt(_Vp&& __v) {
|
static constexpr auto&& __get_alt(_Vp&& __v) {
|
||||||
return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
|
return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
|
||||||
}
|
}
|
||||||
|
@ -492,7 +500,7 @@ namespace __visitation {
|
||||||
|
|
||||||
struct __base {
|
struct __base {
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto)
|
static constexpr decltype(auto)
|
||||||
__visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
__visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
||||||
constexpr auto __fdiagonal =
|
constexpr auto __fdiagonal =
|
||||||
|
@ -503,7 +511,7 @@ struct __base {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
|
static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
|
||||||
_Vs&&... __vs) {
|
_Vs&&... __vs) {
|
||||||
constexpr auto __fmatrix =
|
constexpr auto __fmatrix =
|
||||||
|
@ -516,11 +524,11 @@ struct __base {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
|
static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
|
||||||
|
|
||||||
template <class _Tp, size_t _Np, typename... _Indices>
|
template <class _Tp, size_t _Np, typename... _Indices>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems,
|
static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems,
|
||||||
size_t __index, _Indices... __indices) {
|
size_t __index, _Indices... __indices) {
|
||||||
return __at(__elems[__index], __indices...);
|
return __at(__elems[__index], __indices...);
|
||||||
|
@ -534,7 +542,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Fs>
|
template <class... _Fs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_farray(_Fs&&... __fs) {
|
static constexpr auto __make_farray(_Fs&&... __fs) {
|
||||||
__std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
|
__std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
|
||||||
using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
|
using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
|
||||||
|
@ -544,7 +552,7 @@ private:
|
||||||
template <size_t... _Is>
|
template <size_t... _Is>
|
||||||
struct __dispatcher {
|
struct __dispatcher {
|
||||||
template <class _Fp, class... _Vs>
|
template <class _Fp, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
|
static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
|
||||||
return _VSTD::__invoke(
|
return _VSTD::__invoke(
|
||||||
static_cast<_Fp>(__f),
|
static_cast<_Fp>(__f),
|
||||||
|
@ -553,26 +561,26 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Fp, class... _Vs, size_t... _Is>
|
template <class _Fp, class... _Vs, size_t... _Is>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_dispatch(index_sequence<_Is...>) {
|
static constexpr auto __make_dispatch(index_sequence<_Is...>) {
|
||||||
return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
|
return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class _Fp, class... _Vs>
|
template <size_t _Ip, class _Fp, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fdiagonal_impl() {
|
static constexpr auto __make_fdiagonal_impl() {
|
||||||
return __make_dispatch<_Fp, _Vs...>(
|
return __make_dispatch<_Fp, _Vs...>(
|
||||||
index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
|
index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Fp, class... _Vs, size_t... _Is>
|
template <class _Fp, class... _Vs, size_t... _Is>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
|
static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
|
||||||
return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
|
return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Fp, class _Vp, class... _Vs>
|
template <class _Fp, class _Vp, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fdiagonal() {
|
static constexpr auto __make_fdiagonal() {
|
||||||
constexpr size_t _Np = __uncvref_t<_Vp>::__size();
|
constexpr size_t _Np = __uncvref_t<_Vp>::__size();
|
||||||
static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
|
static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
|
||||||
|
@ -580,13 +588,13 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Fp, class... _Vs, size_t... _Is>
|
template <class _Fp, class... _Vs, size_t... _Is>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
|
static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
|
||||||
return __make_dispatch<_Fp, _Vs...>(__is);
|
return __make_dispatch<_Fp, _Vs...>(__is);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
|
template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
|
static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
|
||||||
index_sequence<_Js...>,
|
index_sequence<_Js...>,
|
||||||
_Ls... __ls) {
|
_Ls... __ls) {
|
||||||
|
@ -595,7 +603,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Fp, class... _Vs>
|
template <class _Fp, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_fmatrix() {
|
static constexpr auto __make_fmatrix() {
|
||||||
return __make_fmatrix_impl<_Fp, _Vs...>(
|
return __make_fmatrix_impl<_Fp, _Vs...>(
|
||||||
index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
|
index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
|
||||||
|
@ -604,7 +612,7 @@ private:
|
||||||
|
|
||||||
struct __variant {
|
struct __variant {
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto)
|
static constexpr decltype(auto)
|
||||||
__visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
__visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
||||||
return __base::__visit_alt_at(__index,
|
return __base::__visit_alt_at(__index,
|
||||||
|
@ -613,7 +621,7 @@ struct __variant {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
|
static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
|
||||||
_Vs&&... __vs) {
|
_Vs&&... __vs) {
|
||||||
return __base::__visit_alt(
|
return __base::__visit_alt(
|
||||||
|
@ -622,7 +630,7 @@ struct __variant {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto)
|
static constexpr decltype(auto)
|
||||||
__visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
__visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
|
||||||
return __visit_alt_at(
|
return __visit_alt_at(
|
||||||
|
@ -632,7 +640,7 @@ struct __variant {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Visitor, class... _Vs>
|
template <class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
|
static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
|
||||||
_Vs&&... __vs) {
|
_Vs&&... __vs) {
|
||||||
return __visit_alt(
|
return __visit_alt(
|
||||||
|
@ -642,7 +650,7 @@ struct __variant {
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER > 17
|
#if _LIBCPP_STD_VER > 17
|
||||||
template <class _Rp, class _Visitor, class... _Vs>
|
template <class _Rp, class _Visitor, class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr _Rp __visit_value(_Visitor&& __visitor,
|
static constexpr _Rp __visit_value(_Visitor&& __visitor,
|
||||||
_Vs&&... __vs) {
|
_Vs&&... __vs) {
|
||||||
return __visit_alt(
|
return __visit_alt(
|
||||||
|
@ -661,7 +669,7 @@ private:
|
||||||
template <class _Visitor>
|
template <class _Visitor>
|
||||||
struct __value_visitor {
|
struct __value_visitor {
|
||||||
template <class... _Alts>
|
template <class... _Alts>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr decltype(auto) operator()(_Alts&&... __alts) const {
|
constexpr decltype(auto) operator()(_Alts&&... __alts) const {
|
||||||
__std_visit_exhaustive_visitor_check<
|
__std_visit_exhaustive_visitor_check<
|
||||||
_Visitor,
|
_Visitor,
|
||||||
|
@ -676,7 +684,7 @@ private:
|
||||||
template <class _Rp, class _Visitor>
|
template <class _Rp, class _Visitor>
|
||||||
struct __value_visitor_return_type {
|
struct __value_visitor_return_type {
|
||||||
template <class... _Alts>
|
template <class... _Alts>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr _Rp operator()(_Alts&&... __alts) const {
|
constexpr _Rp operator()(_Alts&&... __alts) const {
|
||||||
__std_visit_exhaustive_visitor_check<
|
__std_visit_exhaustive_visitor_check<
|
||||||
_Visitor,
|
_Visitor,
|
||||||
|
@ -696,14 +704,14 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class _Visitor>
|
template <class _Visitor>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
|
static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
|
||||||
return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
|
return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER > 17
|
#if _LIBCPP_STD_VER > 17
|
||||||
template <class _Rp, class _Visitor>
|
template <class _Rp, class _Visitor>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
|
static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
|
||||||
return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
|
return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
|
||||||
}
|
}
|
||||||
|
@ -717,7 +725,7 @@ struct _LIBCPP_TEMPLATE_VIS __alt {
|
||||||
using __value_type = _Tp;
|
using __value_type = _Tp;
|
||||||
|
|
||||||
template <class... _Args>
|
template <class... _Args>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr __alt(in_place_t, _Args&&... __args)
|
explicit constexpr __alt(in_place_t, _Args&&... __args)
|
||||||
: __value(_VSTD::forward<_Args>(__args)...) {}
|
: __value(_VSTD::forward<_Args>(__args)...) {}
|
||||||
|
|
||||||
|
@ -732,21 +740,21 @@ union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
|
||||||
|
|
||||||
#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
|
#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
|
||||||
template <size_t _Index, class _Tp, class... _Types> \
|
template <size_t _Index, class _Tp, class... _Types> \
|
||||||
union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
|
union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
|
||||||
_Index, \
|
_Index, \
|
||||||
_Tp, \
|
_Tp, \
|
||||||
_Types...> { \
|
_Types...> { \
|
||||||
public: \
|
public: \
|
||||||
inline _LIBCPP_INLINE_VISIBILITY \
|
_LIBCPP_HIDE_FROM_ABI \
|
||||||
explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
|
explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
|
||||||
\
|
\
|
||||||
template <class... _Args> \
|
template <class... _Args> \
|
||||||
inline _LIBCPP_INLINE_VISIBILITY \
|
_LIBCPP_HIDE_FROM_ABI \
|
||||||
explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
|
explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
|
||||||
: __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
|
: __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
|
||||||
\
|
\
|
||||||
template <size_t _Ip, class... _Args> \
|
template <size_t _Ip, class... _Args> \
|
||||||
inline _LIBCPP_INLINE_VISIBILITY \
|
_LIBCPP_HIDE_FROM_ABI \
|
||||||
explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
|
explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
|
||||||
: __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
|
: __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
|
||||||
\
|
\
|
||||||
|
@ -777,41 +785,41 @@ class _LIBCPP_TEMPLATE_VIS __base {
|
||||||
public:
|
public:
|
||||||
using __index_t = __variant_index_t<sizeof...(_Types)>;
|
using __index_t = __variant_index_t<sizeof...(_Types)>;
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr __base(__valueless_t __tag) noexcept
|
explicit constexpr __base(__valueless_t __tag) noexcept
|
||||||
: __data(__tag), __index(__variant_npos<__index_t>) {}
|
: __data(__tag), __index(__variant_npos<__index_t>) {}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Args>
|
template <size_t _Ip, class... _Args>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
|
explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
|
||||||
:
|
:
|
||||||
__data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
|
__data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
|
||||||
__index(_Ip) {}
|
__index(_Ip) {}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool valueless_by_exception() const noexcept {
|
constexpr bool valueless_by_exception() const noexcept {
|
||||||
return index() == variant_npos;
|
return index() == variant_npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr size_t index() const noexcept {
|
constexpr size_t index() const noexcept {
|
||||||
return __index == __variant_npos<__index_t> ? variant_npos : __index;
|
return __index == __variant_npos<__index_t> ? variant_npos : __index;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __as_base() & { return *this; }
|
constexpr auto&& __as_base() & { return *this; }
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __as_base() && { return _VSTD::move(*this); }
|
constexpr auto&& __as_base() && { return _VSTD::move(*this); }
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __as_base() const & { return *this; }
|
constexpr auto&& __as_base() const & { return *this; }
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
|
constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static constexpr size_t __size() { return sizeof...(_Types); }
|
static constexpr size_t __size() { return sizeof...(_Types); }
|
||||||
|
|
||||||
__union<_DestructibleTrait, 0, _Types...> __data;
|
__union<_DestructibleTrait, 0, _Types...> __data;
|
||||||
|
@ -843,7 +851,7 @@ class _LIBCPP_TEMPLATE_VIS __dtor;
|
||||||
__dtor& operator=(__dtor&&) = default; \
|
__dtor& operator=(__dtor&&) = default; \
|
||||||
\
|
\
|
||||||
protected: \
|
protected: \
|
||||||
inline _LIBCPP_INLINE_VISIBILITY \
|
inline _LIBCPP_HIDE_FROM_ABI \
|
||||||
destroy \
|
destroy \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +892,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <size_t _Ip, class _Tp, class... _Args>
|
template <size_t _Ip, class _Tp, class... _Args>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
|
static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
|
||||||
::new ((void*)_VSTD::addressof(__a))
|
::new ((void*)_VSTD::addressof(__a))
|
||||||
__alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
|
__alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
|
||||||
|
@ -892,7 +900,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Rhs>
|
template <class _Rhs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
|
static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
|
||||||
__lhs.__destroy();
|
__lhs.__destroy();
|
||||||
if (!__rhs.valueless_by_exception()) {
|
if (!__rhs.valueless_by_exception()) {
|
||||||
|
@ -955,7 +963,7 @@ class _LIBCPP_TEMPLATE_VIS __copy_constructor;
|
||||||
#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
|
#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
|
||||||
copy_constructor) \
|
copy_constructor) \
|
||||||
template <class... _Types> \
|
template <class... _Types> \
|
||||||
class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
|
class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
|
||||||
copy_constructible_trait> \
|
copy_constructible_trait> \
|
||||||
: public __move_constructor<__traits<_Types...>> { \
|
: public __move_constructor<__traits<_Types...>> { \
|
||||||
using __base_type = __move_constructor<__traits<_Types...>>; \
|
using __base_type = __move_constructor<__traits<_Types...>>; \
|
||||||
|
@ -997,7 +1005,7 @@ public:
|
||||||
using __base_type::operator=;
|
using __base_type::operator=;
|
||||||
|
|
||||||
template <size_t _Ip, class... _Args>
|
template <size_t _Ip, class... _Args>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
auto& __emplace(_Args&&... __args) {
|
auto& __emplace(_Args&&... __args) {
|
||||||
this->__destroy();
|
this->__destroy();
|
||||||
auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
|
auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
|
||||||
|
@ -1008,7 +1016,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <size_t _Ip, class _Tp, class _Arg>
|
template <size_t _Ip, class _Tp, class _Arg>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
|
void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
|
||||||
if (this->index() == _Ip) {
|
if (this->index() == _Ip) {
|
||||||
__a.__value = _VSTD::forward<_Arg>(__arg);
|
__a.__value = _VSTD::forward<_Arg>(__arg);
|
||||||
|
@ -1029,7 +1037,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _That>
|
template <class _That>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
void __generic_assign(_That&& __that) {
|
void __generic_assign(_That&& __that) {
|
||||||
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
|
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
|
@ -1054,7 +1062,7 @@ class _LIBCPP_TEMPLATE_VIS __move_assignment;
|
||||||
#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
|
#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
|
||||||
move_assignment) \
|
move_assignment) \
|
||||||
template <class... _Types> \
|
template <class... _Types> \
|
||||||
class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
|
class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
|
||||||
move_assignable_trait> \
|
move_assignable_trait> \
|
||||||
: public __assignment<__traits<_Types...>> { \
|
: public __assignment<__traits<_Types...>> { \
|
||||||
using __base_type = __assignment<__traits<_Types...>>; \
|
using __base_type = __assignment<__traits<_Types...>>; \
|
||||||
|
@ -1095,7 +1103,7 @@ class _LIBCPP_TEMPLATE_VIS __copy_assignment;
|
||||||
#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
|
#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
|
||||||
copy_assignment) \
|
copy_assignment) \
|
||||||
template <class... _Types> \
|
template <class... _Types> \
|
||||||
class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
|
class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
|
||||||
copy_assignable_trait> \
|
copy_assignable_trait> \
|
||||||
: public __move_assignment<__traits<_Types...>> { \
|
: public __move_assignment<__traits<_Types...>> { \
|
||||||
using __base_type = __move_assignment<__traits<_Types...>>; \
|
using __base_type = __move_assignment<__traits<_Types...>>; \
|
||||||
|
@ -1141,13 +1149,13 @@ public:
|
||||||
__impl& operator=(__impl&&) = default;
|
__impl& operator=(__impl&&) = default;
|
||||||
|
|
||||||
template <size_t _Ip, class _Arg>
|
template <size_t _Ip, class _Arg>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
void __assign(_Arg&& __arg) {
|
void __assign(_Arg&& __arg) {
|
||||||
this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
|
this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
|
||||||
_VSTD::forward<_Arg>(__arg));
|
_VSTD::forward<_Arg>(__arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_HIDE_FROM_ABI
|
||||||
void __swap(__impl& __that) {
|
void __swap(__impl& __that) {
|
||||||
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
|
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
|
@ -1193,7 +1201,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_HIDE_FROM_ABI
|
||||||
bool __move_nothrow() const {
|
bool __move_nothrow() const {
|
||||||
constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
|
constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
|
||||||
return this->valueless_by_exception() || __results[this->index()];
|
return this->valueless_by_exception() || __results[this->index()];
|
||||||
|
@ -1299,7 +1307,7 @@ public:
|
||||||
enable_if_t<__dependent_type<is_default_constructible<__first_type>,
|
enable_if_t<__dependent_type<is_default_constructible<__first_type>,
|
||||||
_Dummy>::value,
|
_Dummy>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
|
constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
|
||||||
: __impl(in_place_index<0>) {}
|
: __impl(in_place_index<0>) {}
|
||||||
|
|
||||||
|
@ -1315,7 +1323,7 @@ public:
|
||||||
size_t _Ip =
|
size_t _Ip =
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
|
enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr variant(_Arg&& __arg) noexcept(
|
constexpr variant(_Arg&& __arg) noexcept(
|
||||||
is_nothrow_constructible_v<_Tp, _Arg>)
|
is_nothrow_constructible_v<_Tp, _Arg>)
|
||||||
: __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
|
: __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
|
||||||
|
@ -1324,7 +1332,7 @@ public:
|
||||||
class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
|
class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
|
||||||
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr variant(
|
explicit constexpr variant(
|
||||||
in_place_index_t<_Ip>,
|
in_place_index_t<_Ip>,
|
||||||
_Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
|
_Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
|
||||||
|
@ -1338,7 +1346,7 @@ public:
|
||||||
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
||||||
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr variant(
|
explicit constexpr variant(
|
||||||
in_place_index_t<_Ip>,
|
in_place_index_t<_Ip>,
|
||||||
initializer_list<_Up> __il,
|
initializer_list<_Up> __il,
|
||||||
|
@ -1352,7 +1360,7 @@ public:
|
||||||
size_t _Ip =
|
size_t _Ip =
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
|
explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
|
||||||
is_nothrow_constructible_v<_Tp, _Args...>)
|
is_nothrow_constructible_v<_Tp, _Args...>)
|
||||||
: __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
|
: __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
|
||||||
|
@ -1365,7 +1373,7 @@ public:
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
explicit constexpr variant(
|
explicit constexpr variant(
|
||||||
in_place_type_t<_Tp>,
|
in_place_type_t<_Tp>,
|
||||||
initializer_list<_Up> __il,
|
initializer_list<_Up> __il,
|
||||||
|
@ -1386,7 +1394,7 @@ public:
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
|
enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
variant& operator=(_Arg&& __arg) noexcept(
|
variant& operator=(_Arg&& __arg) noexcept(
|
||||||
is_nothrow_assignable_v<_Tp&, _Arg> &&
|
is_nothrow_assignable_v<_Tp&, _Arg> &&
|
||||||
is_nothrow_constructible_v<_Tp, _Arg>) {
|
is_nothrow_constructible_v<_Tp, _Arg>) {
|
||||||
|
@ -1400,7 +1408,7 @@ public:
|
||||||
enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
|
enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
|
||||||
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_Tp& emplace(_Args&&... __args) {
|
_Tp& emplace(_Args&&... __args) {
|
||||||
return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
|
return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1421,7 @@ public:
|
||||||
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
|
||||||
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
_Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
||||||
return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
|
return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
@ -1424,7 +1432,7 @@ public:
|
||||||
size_t _Ip =
|
size_t _Ip =
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_Tp& emplace(_Args&&... __args) {
|
_Tp& emplace(_Args&&... __args) {
|
||||||
return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
|
return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
@ -1437,17 +1445,17 @@ public:
|
||||||
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
__find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
|
||||||
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
_Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
||||||
return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
|
return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool valueless_by_exception() const noexcept {
|
constexpr bool valueless_by_exception() const noexcept {
|
||||||
return __impl.valueless_by_exception();
|
return __impl.valueless_by_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr size_t index() const noexcept { return __impl.index(); }
|
constexpr size_t index() const noexcept { return __impl.index(); }
|
||||||
|
|
||||||
template <
|
template <
|
||||||
|
@ -1457,7 +1465,7 @@ public:
|
||||||
__dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
|
__dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
|
||||||
__dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
|
__dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
void swap(variant& __that) noexcept(
|
void swap(variant& __that) noexcept(
|
||||||
__all<(is_nothrow_move_constructible_v<_Types> &&
|
__all<(is_nothrow_move_constructible_v<_Types> &&
|
||||||
is_nothrow_swappable_v<_Types>)...>::value) {
|
is_nothrow_swappable_v<_Types>)...>::value) {
|
||||||
|
@ -1472,19 +1480,19 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
|
constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
|
||||||
return __v.index() == _Ip;
|
return __v.index() == _Ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
|
constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
|
||||||
return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class _Vp>
|
template <size_t _Ip, class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr auto&& __generic_get(_Vp&& __v) {
|
constexpr auto&& __generic_get(_Vp&& __v) {
|
||||||
using __variant_detail::__access::__variant;
|
using __variant_detail::__access::__variant;
|
||||||
|
@ -1495,7 +1503,7 @@ constexpr auto&& __generic_get(_Vp&& __v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
|
constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
|
||||||
variant<_Types...>& __v) {
|
variant<_Types...>& __v) {
|
||||||
|
@ -1505,7 +1513,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
||||||
variant<_Types...>&& __v) {
|
variant<_Types...>&& __v) {
|
||||||
|
@ -1515,7 +1523,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
|
constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
|
||||||
const variant<_Types...>& __v) {
|
const variant<_Types...>& __v) {
|
||||||
|
@ -1525,7 +1533,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
||||||
const variant<_Types...>&& __v) {
|
const variant<_Types...>&& __v) {
|
||||||
|
@ -1535,7 +1543,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr _Tp& get(variant<_Types...>& __v) {
|
constexpr _Tp& get(variant<_Types...>& __v) {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1543,7 +1551,7 @@ constexpr _Tp& get(variant<_Types...>& __v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr _Tp&& get(variant<_Types...>&& __v) {
|
constexpr _Tp&& get(variant<_Types...>&& __v) {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1552,7 +1560,7 @@ constexpr _Tp&& get(variant<_Types...>&& __v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr const _Tp& get(const variant<_Types...>& __v) {
|
constexpr const _Tp& get(const variant<_Types...>& __v) {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1560,7 +1568,7 @@ constexpr const _Tp& get(const variant<_Types...>& __v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
constexpr const _Tp&& get(const variant<_Types...>&& __v) {
|
constexpr const _Tp&& get(const variant<_Types...>&& __v) {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1569,7 +1577,7 @@ constexpr const _Tp&& get(const variant<_Types...>&& __v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class _Vp>
|
template <size_t _Ip, class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto* __generic_get_if(_Vp* __v) noexcept {
|
constexpr auto* __generic_get_if(_Vp* __v) noexcept {
|
||||||
using __variant_detail::__access::__variant;
|
using __variant_detail::__access::__variant;
|
||||||
return __v && __holds_alternative<_Ip>(*__v)
|
return __v && __holds_alternative<_Ip>(*__v)
|
||||||
|
@ -1578,7 +1586,7 @@ constexpr auto* __generic_get_if(_Vp* __v) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
|
constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
|
||||||
get_if(variant<_Types...>* __v) noexcept {
|
get_if(variant<_Types...>* __v) noexcept {
|
||||||
static_assert(_Ip < sizeof...(_Types));
|
static_assert(_Ip < sizeof...(_Types));
|
||||||
|
@ -1587,7 +1595,7 @@ get_if(variant<_Types...>* __v) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t _Ip, class... _Types>
|
template <size_t _Ip, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
|
constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
|
||||||
get_if(const variant<_Types...>* __v) noexcept {
|
get_if(const variant<_Types...>* __v) noexcept {
|
||||||
static_assert(_Ip < sizeof...(_Types));
|
static_assert(_Ip < sizeof...(_Types));
|
||||||
|
@ -1596,7 +1604,7 @@ get_if(const variant<_Types...>* __v) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr add_pointer_t<_Tp>
|
constexpr add_pointer_t<_Tp>
|
||||||
get_if(variant<_Types...>* __v) noexcept {
|
get_if(variant<_Types...>* __v) noexcept {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1604,7 +1612,7 @@ get_if(variant<_Types...>* __v) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr add_pointer_t<const _Tp>
|
constexpr add_pointer_t<const _Tp>
|
||||||
get_if(const variant<_Types...>* __v) noexcept {
|
get_if(const variant<_Types...>* __v) noexcept {
|
||||||
static_assert(!is_void_v<_Tp>);
|
static_assert(!is_void_v<_Tp>);
|
||||||
|
@ -1614,7 +1622,8 @@ get_if(const variant<_Types...>* __v) noexcept {
|
||||||
template <class _Operator>
|
template <class _Operator>
|
||||||
struct __convert_to_bool {
|
struct __convert_to_bool {
|
||||||
template <class _T1, class _T2>
|
template <class _T1, class _T2>
|
||||||
_LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
|
constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
|
||||||
static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
|
static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
|
||||||
"the relational operator does not return a type which is implicitly convertible to bool");
|
"the relational operator does not return a type which is implicitly convertible to bool");
|
||||||
return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
|
return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
|
||||||
|
@ -1622,7 +1631,7 @@ struct __convert_to_bool {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator==(const variant<_Types...>& __lhs,
|
constexpr bool operator==(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1631,8 +1640,29 @@ constexpr bool operator==(const variant<_Types...>& __lhs,
|
||||||
return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
|
return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER > 17
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
|
||||||
|
operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
|
||||||
|
using __variant_detail::__visitation::__variant;
|
||||||
|
using __result_t = common_comparison_category_t<compare_three_way_result_t<_Types>...>;
|
||||||
|
if (__lhs.valueless_by_exception() && __rhs.valueless_by_exception())
|
||||||
|
return strong_ordering::equal;
|
||||||
|
if (__lhs.valueless_by_exception())
|
||||||
|
return strong_ordering::less;
|
||||||
|
if (__rhs.valueless_by_exception())
|
||||||
|
return strong_ordering::greater;
|
||||||
|
if (auto __c = __lhs.index() <=> __rhs.index(); __c != 0)
|
||||||
|
return __c;
|
||||||
|
auto __three_way = []<class _Type>(const _Type& __v, const _Type& __w) -> __result_t { return __v <=> __w; };
|
||||||
|
return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER > 17
|
||||||
|
|
||||||
|
template <class... _Types>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator!=(const variant<_Types...>& __lhs,
|
constexpr bool operator!=(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1643,7 +1673,7 @@ constexpr bool operator!=(const variant<_Types...>& __lhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator<(const variant<_Types...>& __lhs,
|
constexpr bool operator<(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1655,7 +1685,7 @@ constexpr bool operator<(const variant<_Types...>& __lhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator>(const variant<_Types...>& __lhs,
|
constexpr bool operator>(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1667,7 +1697,7 @@ constexpr bool operator>(const variant<_Types...>& __lhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator<=(const variant<_Types...>& __lhs,
|
constexpr bool operator<=(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1680,7 +1710,7 @@ constexpr bool operator<=(const variant<_Types...>& __lhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr bool operator>=(const variant<_Types...>& __lhs,
|
constexpr bool operator>=(const variant<_Types...>& __lhs,
|
||||||
const variant<_Types...>& __rhs) {
|
const variant<_Types...>& __rhs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
|
@ -1693,9 +1723,9 @@ constexpr bool operator>=(const variant<_Types...>& __lhs,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... _Vs>
|
template <class... _Vs>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
__throw_if_valueless(_Vs&&... __vs) {
|
constexpr void __throw_if_valueless(_Vs&&... __vs) {
|
||||||
const bool __valueless =
|
const bool __valueless =
|
||||||
(... || _VSTD::__as_variant(__vs).valueless_by_exception());
|
(... || _VSTD::__as_variant(__vs).valueless_by_exception());
|
||||||
if (__valueless) {
|
if (__valueless) {
|
||||||
|
@ -1706,9 +1736,9 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||||
template <
|
template <
|
||||||
class _Visitor, class... _Vs,
|
class _Visitor, class... _Vs,
|
||||||
typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
|
typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
|
constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
_VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
|
_VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
|
||||||
return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
|
return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
|
||||||
|
@ -1719,9 +1749,9 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||||
template <
|
template <
|
||||||
class _Rp, class _Visitor, class... _Vs,
|
class _Rp, class _Visitor, class... _Vs,
|
||||||
typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
|
typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
|
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
|
||||||
visit(_Visitor&& __visitor, _Vs&&... __vs) {
|
constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
_VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
|
_VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
|
||||||
return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
|
return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
|
||||||
|
@ -1730,7 +1760,7 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class... _Types>
|
template <class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
auto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
|
auto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
|
||||||
noexcept(noexcept(__lhs.swap(__rhs)))
|
noexcept(noexcept(__lhs.swap(__rhs)))
|
||||||
-> decltype( __lhs.swap(__rhs))
|
-> decltype( __lhs.swap(__rhs))
|
||||||
|
@ -1742,7 +1772,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<
|
||||||
using argument_type = variant<_Types...>;
|
using argument_type = variant<_Types...>;
|
||||||
using result_type = size_t;
|
using result_type = size_t;
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
result_type operator()(const argument_type& __v) const {
|
result_type operator()(const argument_type& __v) const {
|
||||||
using __variant_detail::__visitation::__variant;
|
using __variant_detail::__visitation::__variant;
|
||||||
size_t __res =
|
size_t __res =
|
||||||
|
@ -1764,20 +1794,20 @@ struct _LIBCPP_TEMPLATE_VIS hash<
|
||||||
// type whereas std::get will throw or returning nullptr. This makes it faster than
|
// type whereas std::get will throw or returning nullptr. This makes it faster than
|
||||||
// std::get.
|
// std::get.
|
||||||
template <size_t _Ip, class _Vp>
|
template <size_t _Ip, class _Vp>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
|
constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
|
||||||
using __variant_detail::__access::__variant;
|
using __variant_detail::__access::__variant;
|
||||||
return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
|
return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
|
constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
|
||||||
return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class... _Types>
|
template <class _Tp, class... _Types>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
|
constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
|
||||||
return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,40 +16,32 @@
|
||||||
// constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
// constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
||||||
// constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
// constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
||||||
// constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
// constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
||||||
|
// constexpr strong_ordering operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } // since C++20
|
||||||
|
|
||||||
#include "test_macros.h"
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <type_traits>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
int main(int, char**) {
|
#include "test_comparisons.h"
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
|
constexpr bool test() {
|
||||||
using M = std::monostate;
|
using M = std::monostate;
|
||||||
constexpr M m1{};
|
constexpr M m1{};
|
||||||
constexpr M m2{};
|
constexpr M m2{};
|
||||||
{
|
assert(testComparisons(m1, m2, /*isEqual*/ true, /*isLess*/ false));
|
||||||
static_assert((m1 < m2) == false, "");
|
AssertComparisonsAreNoexcept<M>();
|
||||||
ASSERT_NOEXCEPT(m1 < m2);
|
|
||||||
}
|
#if TEST_STD_VER > 17
|
||||||
{
|
assert(testOrder(m1, m2, std::strong_ordering::equal));
|
||||||
static_assert((m1 > m2) == false, "");
|
AssertOrderAreNoexcept<M>();
|
||||||
ASSERT_NOEXCEPT(m1 > m2);
|
#endif // TEST_STD_VER > 17
|
||||||
}
|
|
||||||
{
|
return true;
|
||||||
static_assert((m1 <= m2) == true, "");
|
}
|
||||||
ASSERT_NOEXCEPT(m1 <= m2);
|
|
||||||
}
|
int main(int, char**) {
|
||||||
{
|
test();
|
||||||
static_assert((m1 >= m2) == true, "");
|
static_assert(test());
|
||||||
ASSERT_NOEXCEPT(m1 >= m2);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static_assert((m1 == m2) == true, "");
|
|
||||||
ASSERT_NOEXCEPT(m1 == m2);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static_assert((m1 != m2) == false, "");
|
|
||||||
ASSERT_NOEXCEPT(m1 != m2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||||
|
|
||||||
|
// <variant>
|
||||||
|
|
||||||
|
// template <class... Types> class variant;
|
||||||
|
|
||||||
|
// template<class... Types>
|
||||||
|
// constexpr std::common_comparison_category_t<
|
||||||
|
// std::compare_three_way_result_t<Types>...>
|
||||||
|
// operator<=>(const variant<Types...>& t, const variant<Types...>& u);
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
#include "test_comparisons.h"
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
// MakeEmptyT throws in operator=(&&), so we can move to it to create valueless-by-exception variants.
|
||||||
|
struct MakeEmptyT {
|
||||||
|
MakeEmptyT() = default;
|
||||||
|
MakeEmptyT(MakeEmptyT&&) { throw 42; }
|
||||||
|
MakeEmptyT& operator=(MakeEmptyT&&) { throw 42; }
|
||||||
|
};
|
||||||
|
inline bool operator==(const MakeEmptyT&, const MakeEmptyT&) {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline std::weak_ordering operator<=>(const MakeEmptyT&, const MakeEmptyT&) {
|
||||||
|
assert(false);
|
||||||
|
return std::weak_ordering::equivalent;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Variant>
|
||||||
|
void makeEmpty(Variant& v) {
|
||||||
|
Variant v2(std::in_place_type<MakeEmptyT>);
|
||||||
|
try {
|
||||||
|
v = std::move(v2);
|
||||||
|
assert(false);
|
||||||
|
} catch (...) {
|
||||||
|
assert(v.valueless_by_exception());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_empty() {
|
||||||
|
{
|
||||||
|
using V = std::variant<int, MakeEmptyT>;
|
||||||
|
V v1;
|
||||||
|
V v2;
|
||||||
|
makeEmpty(v2);
|
||||||
|
assert(testOrder(v1, v2, std::weak_ordering::greater));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using V = std::variant<int, MakeEmptyT>;
|
||||||
|
V v1;
|
||||||
|
makeEmpty(v1);
|
||||||
|
V v2;
|
||||||
|
assert(testOrder(v1, v2, std::weak_ordering::less));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using V = std::variant<int, MakeEmptyT>;
|
||||||
|
V v1;
|
||||||
|
makeEmpty(v1);
|
||||||
|
V v2;
|
||||||
|
makeEmpty(v2);
|
||||||
|
assert(testOrder(v1, v2, std::weak_ordering::equivalent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TEST_HAS_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
template <class T1, class T2, class Order>
|
||||||
|
constexpr bool test_with_types() {
|
||||||
|
using V = std::variant<T1, T2>;
|
||||||
|
AssertOrderReturn<Order, V>();
|
||||||
|
{ // same index, same value
|
||||||
|
constexpr V v1(std::in_place_index<0>, T1{1});
|
||||||
|
constexpr V v2(std::in_place_index<0>, T1{1});
|
||||||
|
assert(testOrder(v1, v2, Order::equivalent));
|
||||||
|
}
|
||||||
|
{ // same index, value < other_value
|
||||||
|
constexpr V v1(std::in_place_index<0>, T1{0});
|
||||||
|
constexpr V v2(std::in_place_index<0>, T1{1});
|
||||||
|
assert(testOrder(v1, v2, Order::less));
|
||||||
|
}
|
||||||
|
{ // same index, value > other_value
|
||||||
|
constexpr V v1(std::in_place_index<0>, T1{1});
|
||||||
|
constexpr V v2(std::in_place_index<0>, T1{0});
|
||||||
|
assert(testOrder(v1, v2, Order::greater));
|
||||||
|
}
|
||||||
|
{ // LHS.index() < RHS.index()
|
||||||
|
constexpr V v1(std::in_place_index<0>, T1{0});
|
||||||
|
constexpr V v2(std::in_place_index<1>, T2{0});
|
||||||
|
assert(testOrder(v1, v2, Order::less));
|
||||||
|
}
|
||||||
|
{ // LHS.index() > RHS.index()
|
||||||
|
constexpr V v1(std::in_place_index<1>, T2{0});
|
||||||
|
constexpr V v2(std::in_place_index<0>, T1{0});
|
||||||
|
assert(testOrder(v1, v2, Order::greater));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool test_three_way() {
|
||||||
|
assert((test_with_types<int, double, std::partial_ordering>()));
|
||||||
|
assert((test_with_types<int, long, std::strong_ordering>()));
|
||||||
|
|
||||||
|
{
|
||||||
|
using V = std::variant<int, double>;
|
||||||
|
constexpr double nan = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
{
|
||||||
|
constexpr V v1(std::in_place_type<int>, 1);
|
||||||
|
constexpr V v2(std::in_place_type<double>, nan);
|
||||||
|
assert(testOrder(v1, v2, std::partial_ordering::less));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr V v1(std::in_place_type<double>, nan);
|
||||||
|
constexpr V v2(std::in_place_type<int>, 2);
|
||||||
|
assert(testOrder(v1, v2, std::partial_ordering::greater));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr V v1(std::in_place_type<double>, nan);
|
||||||
|
constexpr V v2(std::in_place_type<double>, nan);
|
||||||
|
assert(testOrder(v1, v2, std::partial_ordering::unordered));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SFINAE tests
|
||||||
|
template <class T, class U = T>
|
||||||
|
concept has_three_way_op = requires (T& t, U& u) { t <=> u; };
|
||||||
|
|
||||||
|
// std::three_way_comparable is a more stringent requirement that demands
|
||||||
|
// operator== and a few other things.
|
||||||
|
using std::three_way_comparable;
|
||||||
|
|
||||||
|
struct HasSimpleOrdering {
|
||||||
|
constexpr bool operator==(const HasSimpleOrdering&) const;
|
||||||
|
constexpr bool operator<(const HasSimpleOrdering&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HasOnlySpaceship {
|
||||||
|
constexpr bool operator==(const HasOnlySpaceship&) const = delete;
|
||||||
|
constexpr std::weak_ordering operator<=>(const HasOnlySpaceship&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HasFullOrdering {
|
||||||
|
constexpr bool operator==(const HasFullOrdering&) const;
|
||||||
|
constexpr std::weak_ordering operator<=>(const HasFullOrdering&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// operator<=> must resolve the return types of all its union types'
|
||||||
|
// operator<=>s to determine its own return type, so it is detectable by SFINAE
|
||||||
|
static_assert(!has_three_way_op<HasSimpleOrdering>);
|
||||||
|
static_assert(!has_three_way_op<std::variant<int, HasSimpleOrdering>>);
|
||||||
|
|
||||||
|
static_assert(!three_way_comparable<HasSimpleOrdering>);
|
||||||
|
static_assert(!three_way_comparable<std::variant<int, HasSimpleOrdering>>);
|
||||||
|
|
||||||
|
static_assert( has_three_way_op<HasOnlySpaceship>);
|
||||||
|
static_assert( has_three_way_op<std::variant<int, HasOnlySpaceship>>);
|
||||||
|
|
||||||
|
// variants containing types with unavailable operator== still exist but will
|
||||||
|
// generate a compilation error if their operator== is invoked, so the variant
|
||||||
|
// type here participates when asked for operator== and operator<=> even though
|
||||||
|
// it would actually fail.
|
||||||
|
static_assert(!three_way_comparable<HasOnlySpaceship>);
|
||||||
|
static_assert( three_way_comparable<std::variant<int, HasOnlySpaceship>>);
|
||||||
|
|
||||||
|
static_assert( has_three_way_op<HasFullOrdering>);
|
||||||
|
static_assert( has_three_way_op<std::variant<int, HasFullOrdering>>);
|
||||||
|
|
||||||
|
static_assert( three_way_comparable<HasFullOrdering>);
|
||||||
|
static_assert( three_way_comparable<std::variant<int, HasFullOrdering>>);
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
test_three_way();
|
||||||
|
static_assert(test_three_way());
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
test_empty();
|
||||||
|
#endif // TEST_HAS_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -23,18 +23,20 @@
|
||||||
#ifndef TEST_COMPARISONS_H
|
#ifndef TEST_COMPARISONS_H
|
||||||
#define TEST_COMPARISONS_H
|
#define TEST_COMPARISONS_H
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
|
||||||
// Test all six comparison operations for sanity
|
// Test the consistency of the six basic comparison operators for values that are ordered or unordered.
|
||||||
template <class T, class U = T>
|
template <class T, class U = T>
|
||||||
TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t2, bool isEqual, bool isLess)
|
TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool
|
||||||
{
|
testComparisonsComplete(const T& t1, const U& t2, bool isEqual, bool isLess, bool isGreater) {
|
||||||
assert(!(isEqual && isLess) && "isEqual and isLess cannot be both true");
|
assert(((isEqual ? 1 : 0) + (isLess ? 1 : 0) + (isGreater ? 1 : 0) <= 1) &&
|
||||||
if (isEqual)
|
"at most one of isEqual, isLess, and isGreater can be true");
|
||||||
{
|
if (isEqual) {
|
||||||
if (!(t1 == t2)) return false;
|
if (!(t1 == t2)) return false;
|
||||||
if (!(t2 == t1)) return false;
|
if (!(t2 == t1)) return false;
|
||||||
if ( (t1 != t2)) return false;
|
if ( (t1 != t2)) return false;
|
||||||
|
@ -47,9 +49,7 @@ TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t
|
||||||
if ( (t2 > t1)) return false;
|
if ( (t2 > t1)) return false;
|
||||||
if (!(t1 >= t2)) return false;
|
if (!(t1 >= t2)) return false;
|
||||||
if (!(t2 >= t1)) return false;
|
if (!(t2 >= t1)) return false;
|
||||||
}
|
} else if (isLess) {
|
||||||
else if (isLess)
|
|
||||||
{
|
|
||||||
if ( (t1 == t2)) return false;
|
if ( (t1 == t2)) return false;
|
||||||
if ( (t2 == t1)) return false;
|
if ( (t2 == t1)) return false;
|
||||||
if (!(t1 != t2)) return false;
|
if (!(t1 != t2)) return false;
|
||||||
|
@ -62,9 +62,7 @@ TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t
|
||||||
if (!(t2 > t1)) return false;
|
if (!(t2 > t1)) return false;
|
||||||
if ( (t1 >= t2)) return false;
|
if ( (t1 >= t2)) return false;
|
||||||
if (!(t2 >= t1)) return false;
|
if (!(t2 >= t1)) return false;
|
||||||
}
|
} else if (isGreater) {
|
||||||
else /* greater */
|
|
||||||
{
|
|
||||||
if ( (t1 == t2)) return false;
|
if ( (t1 == t2)) return false;
|
||||||
if ( (t2 == t1)) return false;
|
if ( (t2 == t1)) return false;
|
||||||
if (!(t1 != t2)) return false;
|
if (!(t1 != t2)) return false;
|
||||||
|
@ -77,19 +75,41 @@ TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t
|
||||||
if ( (t2 > t1)) return false;
|
if ( (t2 > t1)) return false;
|
||||||
if (!(t1 >= t2)) return false;
|
if (!(t1 >= t2)) return false;
|
||||||
if ( (t2 >= t1)) return false;
|
if ( (t2 >= t1)) return false;
|
||||||
}
|
} else { // unordered
|
||||||
|
if ( (t1 == t2)) return false;
|
||||||
|
if ( (t2 == t1)) return false;
|
||||||
|
if (!(t1 != t2)) return false;
|
||||||
|
if (!(t2 != t1)) return false;
|
||||||
|
if ( (t1 < t2)) return false;
|
||||||
|
if ( (t2 < t1)) return false;
|
||||||
|
if ( (t1 <= t2)) return false;
|
||||||
|
if ( (t2 <= t1)) return false;
|
||||||
|
if ( (t1 > t2)) return false;
|
||||||
|
if ( (t2 > t1)) return false;
|
||||||
|
if ( (t1 >= t2)) return false;
|
||||||
|
if ( (t2 >= t1)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test the six basic comparison operators for ordered values.
|
||||||
|
template <class T, class U = T>
|
||||||
|
TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t2, bool isEqual, bool isLess) {
|
||||||
|
assert(!(isEqual && isLess) && "isEqual and isLess cannot be both true");
|
||||||
|
bool isGreater = !isEqual && !isLess;
|
||||||
|
return testComparisonsComplete(t1, t2, isEqual, isLess, isGreater);
|
||||||
|
}
|
||||||
|
|
||||||
// Easy call when you can init from something already comparable.
|
// Easy call when you can init from something already comparable.
|
||||||
template <class T, class Param>
|
template <class T, class Param>
|
||||||
TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisonsValues(Param val1, Param val2)
|
TEST_NODISCARD TEST_CONSTEXPR_CXX14 bool testComparisonsValues(Param val1, Param val2)
|
||||||
{
|
{
|
||||||
const bool isEqual = val1 == val2;
|
const bool isEqual = val1 == val2;
|
||||||
const bool isLess = val1 < val2;
|
const bool isLess = val1 < val2;
|
||||||
|
const bool isGreater = val1 > val2;
|
||||||
|
|
||||||
return testComparisons(T(val1), T(val2), isEqual, isLess);
|
return testComparisonsComplete(T(val1), T(val2), isEqual, isLess, isGreater);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U = T>
|
template <class T, class U = T>
|
||||||
|
@ -138,10 +158,11 @@ constexpr void AssertOrderReturn() {
|
||||||
|
|
||||||
template <class Order, class T, class U = T>
|
template <class Order, class T, class U = T>
|
||||||
TEST_NODISCARD constexpr bool testOrder(const T& t1, const U& t2, Order order) {
|
TEST_NODISCARD constexpr bool testOrder(const T& t1, const U& t2, Order order) {
|
||||||
bool equal = order == Order::equivalent;
|
bool equal = order == Order::equivalent;
|
||||||
bool less = order == Order::less;
|
bool less = order == Order::less;
|
||||||
|
bool greater = order == Order::greater;
|
||||||
|
|
||||||
return (t1 <=> t2 == order) && testComparisons(t1, t2, equal, less);
|
return (t1 <=> t2 == order) && testComparisonsComplete(t1, t2, equal, less, greater);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class Param>
|
template <class T, class Param>
|
||||||
|
|
Loading…
Reference in New Issue