10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===-------------------------- compare -----------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_COMPARE 110b57cec5SDimitry Andric#define _LIBCPP_COMPARE 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric compare synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std { 170b57cec5SDimitry Andric // [cmp.categories], comparison category types 180b57cec5SDimitry Andric class weak_equality; 190b57cec5SDimitry Andric class strong_equality; 200b57cec5SDimitry Andric class partial_ordering; 210b57cec5SDimitry Andric class weak_ordering; 220b57cec5SDimitry Andric class strong_ordering; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // named comparison functions 250b57cec5SDimitry Andric constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; } 260b57cec5SDimitry Andric constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; } 270b57cec5SDimitry Andric constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } 280b57cec5SDimitry Andric constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } 290b57cec5SDimitry Andric constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } 300b57cec5SDimitry Andric constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // [cmp.common], common comparison category type 330b57cec5SDimitry Andric template<class... Ts> 340b57cec5SDimitry Andric struct common_comparison_category { 350b57cec5SDimitry Andric using type = see below; 360b57cec5SDimitry Andric }; 370b57cec5SDimitry Andric template<class... Ts> 380b57cec5SDimitry Andric using common_comparison_category_t = typename common_comparison_category<Ts...>::type; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // [cmp.alg], comparison algorithms 410b57cec5SDimitry Andric template<class T> constexpr strong_ordering strong_order(const T& a, const T& b); 420b57cec5SDimitry Andric template<class T> constexpr weak_ordering weak_order(const T& a, const T& b); 430b57cec5SDimitry Andric template<class T> constexpr partial_ordering partial_order(const T& a, const T& b); 440b57cec5SDimitry Andric template<class T> constexpr strong_equality strong_equal(const T& a, const T& b); 450b57cec5SDimitry Andric template<class T> constexpr weak_equality weak_equal(const T& a, const T& b); 46*5ffd83dbSDimitry Andric 47*5ffd83dbSDimitry Andric // [cmp.partialord], Class partial_ordering 48*5ffd83dbSDimitry Andric class partial_ordering { 49*5ffd83dbSDimitry Andric public: 50*5ffd83dbSDimitry Andric // valid values 51*5ffd83dbSDimitry Andric static const partial_ordering less; 52*5ffd83dbSDimitry Andric static const partial_ordering equivalent; 53*5ffd83dbSDimitry Andric static const partial_ordering greater; 54*5ffd83dbSDimitry Andric static const partial_ordering unordered; 55*5ffd83dbSDimitry Andric 56*5ffd83dbSDimitry Andric // comparisons 57*5ffd83dbSDimitry Andric friend constexpr bool operator==(partial_ordering v, unspecified) noexcept; 58*5ffd83dbSDimitry Andric friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default; 59*5ffd83dbSDimitry Andric friend constexpr bool operator< (partial_ordering v, unspecified) noexcept; 60*5ffd83dbSDimitry Andric friend constexpr bool operator> (partial_ordering v, unspecified) noexcept; 61*5ffd83dbSDimitry Andric friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept; 62*5ffd83dbSDimitry Andric friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept; 63*5ffd83dbSDimitry Andric friend constexpr bool operator< (unspecified, partial_ordering v) noexcept; 64*5ffd83dbSDimitry Andric friend constexpr bool operator> (unspecified, partial_ordering v) noexcept; 65*5ffd83dbSDimitry Andric friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept; 66*5ffd83dbSDimitry Andric friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept; 67*5ffd83dbSDimitry Andric friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept; 68*5ffd83dbSDimitry Andric friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept; 69*5ffd83dbSDimitry Andric }; 70*5ffd83dbSDimitry Andric 71*5ffd83dbSDimitry Andric // [cmp.weakord], Class weak_ordering 72*5ffd83dbSDimitry Andric class weak_ordering { 73*5ffd83dbSDimitry Andric public: 74*5ffd83dbSDimitry Andric // valid values 75*5ffd83dbSDimitry Andric static const weak_ordering less; 76*5ffd83dbSDimitry Andric static const weak_ordering equivalent; 77*5ffd83dbSDimitry Andric static const weak_ordering greater; 78*5ffd83dbSDimitry Andric 79*5ffd83dbSDimitry Andric // conversions 80*5ffd83dbSDimitry Andric constexpr operator partial_ordering() const noexcept; 81*5ffd83dbSDimitry Andric 82*5ffd83dbSDimitry Andric // comparisons 83*5ffd83dbSDimitry Andric friend constexpr bool operator==(weak_ordering v, unspecified) noexcept; 84*5ffd83dbSDimitry Andric friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default; 85*5ffd83dbSDimitry Andric friend constexpr bool operator< (weak_ordering v, unspecified) noexcept; 86*5ffd83dbSDimitry Andric friend constexpr bool operator> (weak_ordering v, unspecified) noexcept; 87*5ffd83dbSDimitry Andric friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept; 88*5ffd83dbSDimitry Andric friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept; 89*5ffd83dbSDimitry Andric friend constexpr bool operator< (unspecified, weak_ordering v) noexcept; 90*5ffd83dbSDimitry Andric friend constexpr bool operator> (unspecified, weak_ordering v) noexcept; 91*5ffd83dbSDimitry Andric friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept; 92*5ffd83dbSDimitry Andric friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept; 93*5ffd83dbSDimitry Andric friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept; 94*5ffd83dbSDimitry Andric friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept; 95*5ffd83dbSDimitry Andric }; 96*5ffd83dbSDimitry Andric 97*5ffd83dbSDimitry Andric // [cmp.strongord], Class strong_ordering 98*5ffd83dbSDimitry Andric class strong_ordering { 99*5ffd83dbSDimitry Andric public: 100*5ffd83dbSDimitry Andric // valid values 101*5ffd83dbSDimitry Andric static const strong_ordering less; 102*5ffd83dbSDimitry Andric static const strong_ordering equal; 103*5ffd83dbSDimitry Andric static const strong_ordering equivalent; 104*5ffd83dbSDimitry Andric static const strong_ordering greater; 105*5ffd83dbSDimitry Andric 106*5ffd83dbSDimitry Andric // conversions 107*5ffd83dbSDimitry Andric constexpr operator partial_ordering() const noexcept; 108*5ffd83dbSDimitry Andric constexpr operator weak_ordering() const noexcept; 109*5ffd83dbSDimitry Andric 110*5ffd83dbSDimitry Andric // comparisons 111*5ffd83dbSDimitry Andric friend constexpr bool operator==(strong_ordering v, unspecified) noexcept; 112*5ffd83dbSDimitry Andric friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default; 113*5ffd83dbSDimitry Andric friend constexpr bool operator< (strong_ordering v, unspecified) noexcept; 114*5ffd83dbSDimitry Andric friend constexpr bool operator> (strong_ordering v, unspecified) noexcept; 115*5ffd83dbSDimitry Andric friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept; 116*5ffd83dbSDimitry Andric friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept; 117*5ffd83dbSDimitry Andric friend constexpr bool operator< (unspecified, strong_ordering v) noexcept; 118*5ffd83dbSDimitry Andric friend constexpr bool operator> (unspecified, strong_ordering v) noexcept; 119*5ffd83dbSDimitry Andric friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept; 120*5ffd83dbSDimitry Andric friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept; 121*5ffd83dbSDimitry Andric friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept; 122*5ffd83dbSDimitry Andric friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept; 123*5ffd83dbSDimitry Andric }; 1240b57cec5SDimitry Andric} 1250b57cec5SDimitry Andric*/ 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric#include <__config> 1280b57cec5SDimitry Andric#include <type_traits> 1290b57cec5SDimitry Andric#include <array> 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 1320b57cec5SDimitry Andric#pragma GCC system_header 1330b57cec5SDimitry Andric#endif 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric// exposition only 1400b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { 1410b57cec5SDimitry Andric __zero = 0, 1420b57cec5SDimitry Andric __equal = __zero, 1430b57cec5SDimitry Andric __equiv = __equal, 1440b57cec5SDimitry Andric __nonequal = 1, 1450b57cec5SDimitry Andric __nonequiv = __nonequal 1460b57cec5SDimitry Andric}; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 1490b57cec5SDimitry Andric __less = -1, 1500b57cec5SDimitry Andric __greater = 1 1510b57cec5SDimitry Andric}; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 1540b57cec5SDimitry Andric __unordered = -127 1550b57cec5SDimitry Andric}; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andricstruct _CmpUnspecifiedType; 1580b57cec5SDimitry Andricusing _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andricclass weak_equality { 1610b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1620b57cec5SDimitry Andric constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andricpublic: 1650b57cec5SDimitry Andric static const weak_equality equivalent; 1660b57cec5SDimitry Andric static const weak_equality nonequivalent; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; 1690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; 1700b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; 1710b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 1740b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; 1750b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; 1760b57cec5SDimitry Andric#endif 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andricprivate: 1790b57cec5SDimitry Andric _EqResult __value_; 1800b57cec5SDimitry Andric}; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); 1830b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1860b57cec5SDimitry Andricinline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { 1870b57cec5SDimitry Andric return __v.__value_ == _EqResult::__zero; 1880b57cec5SDimitry Andric} 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1910b57cec5SDimitry Andricinline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { 1920b57cec5SDimitry Andric return __v.__value_ == _EqResult::__zero; 1930b57cec5SDimitry Andric} 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1960b57cec5SDimitry Andricinline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { 1970b57cec5SDimitry Andric return __v.__value_ != _EqResult::__zero; 1980b57cec5SDimitry Andric} 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2010b57cec5SDimitry Andricinline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { 2020b57cec5SDimitry Andric return __v.__value_ != _EqResult::__zero; 2030b57cec5SDimitry Andric} 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 2060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2070b57cec5SDimitry Andricinline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { 2080b57cec5SDimitry Andric return __v; 2090b57cec5SDimitry Andric} 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2120b57cec5SDimitry Andricinline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { 2130b57cec5SDimitry Andric return __v; 2140b57cec5SDimitry Andric} 2150b57cec5SDimitry Andric#endif 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andricclass strong_equality { 2180b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2190b57cec5SDimitry Andric explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andricpublic: 2220b57cec5SDimitry Andric static const strong_equality equal; 2230b57cec5SDimitry Andric static const strong_equality nonequal; 2240b57cec5SDimitry Andric static const strong_equality equivalent; 2250b57cec5SDimitry Andric static const strong_equality nonequivalent; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric // conversion 2280b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { 2290b57cec5SDimitry Andric return __value_ == _EqResult::__zero ? weak_equality::equivalent 2300b57cec5SDimitry Andric : weak_equality::nonequivalent; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // comparisons 2340b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; 2350b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; 2360b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; 2370b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 2400b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; 2410b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; 2420b57cec5SDimitry Andric#endif 2430b57cec5SDimitry Andricprivate: 2440b57cec5SDimitry Andric _EqResult __value_; 2450b57cec5SDimitry Andric}; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal); 2480b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); 2490b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); 2500b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2530b57cec5SDimitry Andricconstexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { 2540b57cec5SDimitry Andric return __v.__value_ == _EqResult::__zero; 2550b57cec5SDimitry Andric} 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2580b57cec5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { 2590b57cec5SDimitry Andric return __v.__value_ == _EqResult::__zero; 2600b57cec5SDimitry Andric} 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2630b57cec5SDimitry Andricconstexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { 2640b57cec5SDimitry Andric return __v.__value_ != _EqResult::__zero; 2650b57cec5SDimitry Andric} 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2680b57cec5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { 2690b57cec5SDimitry Andric return __v.__value_ != _EqResult::__zero; 2700b57cec5SDimitry Andric} 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 2730b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2740b57cec5SDimitry Andricconstexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { 2750b57cec5SDimitry Andric return __v; 2760b57cec5SDimitry Andric} 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2790b57cec5SDimitry Andricconstexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { 2800b57cec5SDimitry Andric return __v; 2810b57cec5SDimitry Andric} 2820b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andricclass partial_ordering { 2850b57cec5SDimitry Andric using _ValueT = signed char; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2880b57cec5SDimitry Andric explicit constexpr partial_ordering(_EqResult __v) noexcept 2890b57cec5SDimitry Andric : __value_(_ValueT(__v)) {} 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2920b57cec5SDimitry Andric explicit constexpr partial_ordering(_OrdResult __v) noexcept 2930b57cec5SDimitry Andric : __value_(_ValueT(__v)) {} 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2960b57cec5SDimitry Andric explicit constexpr partial_ordering(_NCmpResult __v) noexcept 2970b57cec5SDimitry Andric : __value_(_ValueT(__v)) {} 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric constexpr bool __is_ordered() const noexcept { 3000b57cec5SDimitry Andric return __value_ != _ValueT(_NCmpResult::__unordered); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andricpublic: 3030b57cec5SDimitry Andric // valid values 3040b57cec5SDimitry Andric static const partial_ordering less; 3050b57cec5SDimitry Andric static const partial_ordering equivalent; 3060b57cec5SDimitry Andric static const partial_ordering greater; 3070b57cec5SDimitry Andric static const partial_ordering unordered; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // conversion 3100b57cec5SDimitry Andric constexpr operator weak_equality() const noexcept { 3110b57cec5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric // comparisons 3150b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3160b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3170b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3180b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3190b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3200b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3210b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3220b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3240b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3250b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3260b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 329*5ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 330*5ffd83dbSDimitry Andric 3310b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 3320b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 3330b57cec5SDimitry Andric#endif 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andricprivate: 3360b57cec5SDimitry Andric _ValueT __value_; 3370b57cec5SDimitry Andric}; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 3400b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); 3410b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 3420b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3450b57cec5SDimitry Andricconstexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3460b57cec5SDimitry Andric return __v.__is_ordered() && __v.__value_ == 0; 3470b57cec5SDimitry Andric} 3480b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3490b57cec5SDimitry Andricconstexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3500b57cec5SDimitry Andric return __v.__is_ordered() && __v.__value_ < 0; 3510b57cec5SDimitry Andric} 3520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3530b57cec5SDimitry Andricconstexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3540b57cec5SDimitry Andric return __v.__is_ordered() && __v.__value_ <= 0; 3550b57cec5SDimitry Andric} 3560b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3570b57cec5SDimitry Andricconstexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3580b57cec5SDimitry Andric return __v.__is_ordered() && __v.__value_ > 0; 3590b57cec5SDimitry Andric} 3600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3610b57cec5SDimitry Andricconstexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3620b57cec5SDimitry Andric return __v.__is_ordered() && __v.__value_ >= 0; 3630b57cec5SDimitry Andric} 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3660b57cec5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3670b57cec5SDimitry Andric return __v.__is_ordered() && 0 == __v.__value_; 3680b57cec5SDimitry Andric} 3690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3700b57cec5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3710b57cec5SDimitry Andric return __v.__is_ordered() && 0 < __v.__value_; 3720b57cec5SDimitry Andric} 3730b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3740b57cec5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3750b57cec5SDimitry Andric return __v.__is_ordered() && 0 <= __v.__value_; 3760b57cec5SDimitry Andric} 3770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3780b57cec5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3790b57cec5SDimitry Andric return __v.__is_ordered() && 0 > __v.__value_; 3800b57cec5SDimitry Andric} 3810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3820b57cec5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3830b57cec5SDimitry Andric return __v.__is_ordered() && 0 >= __v.__value_; 3840b57cec5SDimitry Andric} 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3870b57cec5SDimitry Andricconstexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3880b57cec5SDimitry Andric return !__v.__is_ordered() || __v.__value_ != 0; 3890b57cec5SDimitry Andric} 3900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3910b57cec5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 3920b57cec5SDimitry Andric return !__v.__is_ordered() || __v.__value_ != 0; 3930b57cec5SDimitry Andric} 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 3960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3970b57cec5SDimitry Andricconstexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 3980b57cec5SDimitry Andric return __v; 3990b57cec5SDimitry Andric} 4000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4010b57cec5SDimitry Andricconstexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 4020b57cec5SDimitry Andric return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 4030b57cec5SDimitry Andric} 4040b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andricclass weak_ordering { 4070b57cec5SDimitry Andric using _ValueT = signed char; 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4100b57cec5SDimitry Andric explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 4110b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4120b57cec5SDimitry Andric explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andricpublic: 4150b57cec5SDimitry Andric static const weak_ordering less; 4160b57cec5SDimitry Andric static const weak_ordering equivalent; 4170b57cec5SDimitry Andric static const weak_ordering greater; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric // conversions 4200b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4210b57cec5SDimitry Andric constexpr operator weak_equality() const noexcept { 4220b57cec5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent 4230b57cec5SDimitry Andric : weak_equality::nonequivalent; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4270b57cec5SDimitry Andric constexpr operator partial_ordering() const noexcept { 4280b57cec5SDimitry Andric return __value_ == 0 ? partial_ordering::equivalent 4290b57cec5SDimitry Andric : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric // comparisons 4330b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4340b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4350b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4360b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4370b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4380b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4390b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4400b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4410b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4420b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4430b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 447*5ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 448*5ffd83dbSDimitry Andric 4490b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 4500b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 4510b57cec5SDimitry Andric#endif 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andricprivate: 4540b57cec5SDimitry Andric _ValueT __value_; 4550b57cec5SDimitry Andric}; 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 4580b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); 4590b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4620b57cec5SDimitry Andricconstexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4630b57cec5SDimitry Andric return __v.__value_ == 0; 4640b57cec5SDimitry Andric} 4650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4660b57cec5SDimitry Andricconstexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4670b57cec5SDimitry Andric return __v.__value_ != 0; 4680b57cec5SDimitry Andric} 4690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4700b57cec5SDimitry Andricconstexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4710b57cec5SDimitry Andric return __v.__value_ < 0; 4720b57cec5SDimitry Andric} 4730b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4740b57cec5SDimitry Andricconstexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4750b57cec5SDimitry Andric return __v.__value_ <= 0; 4760b57cec5SDimitry Andric} 4770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4780b57cec5SDimitry Andricconstexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4790b57cec5SDimitry Andric return __v.__value_ > 0; 4800b57cec5SDimitry Andric} 4810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4820b57cec5SDimitry Andricconstexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 4830b57cec5SDimitry Andric return __v.__value_ >= 0; 4840b57cec5SDimitry Andric} 4850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4860b57cec5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 4870b57cec5SDimitry Andric return 0 == __v.__value_; 4880b57cec5SDimitry Andric} 4890b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4900b57cec5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 4910b57cec5SDimitry Andric return 0 != __v.__value_; 4920b57cec5SDimitry Andric} 4930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4940b57cec5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 4950b57cec5SDimitry Andric return 0 < __v.__value_; 4960b57cec5SDimitry Andric} 4970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4980b57cec5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 4990b57cec5SDimitry Andric return 0 <= __v.__value_; 5000b57cec5SDimitry Andric} 5010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5020b57cec5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 5030b57cec5SDimitry Andric return 0 > __v.__value_; 5040b57cec5SDimitry Andric} 5050b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5060b57cec5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 5070b57cec5SDimitry Andric return 0 >= __v.__value_; 5080b57cec5SDimitry Andric} 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 5110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5120b57cec5SDimitry Andricconstexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 5130b57cec5SDimitry Andric return __v; 5140b57cec5SDimitry Andric} 5150b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5160b57cec5SDimitry Andricconstexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 5170b57cec5SDimitry Andric return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 5180b57cec5SDimitry Andric} 5190b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andricclass strong_ordering { 5220b57cec5SDimitry Andric using _ValueT = signed char; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5250b57cec5SDimitry Andric explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 5260b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5270b57cec5SDimitry Andric explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andricpublic: 5300b57cec5SDimitry Andric static const strong_ordering less; 5310b57cec5SDimitry Andric static const strong_ordering equal; 5320b57cec5SDimitry Andric static const strong_ordering equivalent; 5330b57cec5SDimitry Andric static const strong_ordering greater; 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric // conversions 5360b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5370b57cec5SDimitry Andric constexpr operator weak_equality() const noexcept { 5380b57cec5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent 5390b57cec5SDimitry Andric : weak_equality::nonequivalent; 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5430b57cec5SDimitry Andric constexpr operator strong_equality() const noexcept { 5440b57cec5SDimitry Andric return __value_ == 0 ? strong_equality::equal 5450b57cec5SDimitry Andric : strong_equality::nonequal; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5490b57cec5SDimitry Andric constexpr operator partial_ordering() const noexcept { 5500b57cec5SDimitry Andric return __value_ == 0 ? partial_ordering::equivalent 5510b57cec5SDimitry Andric : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 5550b57cec5SDimitry Andric constexpr operator weak_ordering() const noexcept { 5560b57cec5SDimitry Andric return __value_ == 0 ? weak_ordering::equivalent 5570b57cec5SDimitry Andric : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric // comparisons 5610b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5620b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5630b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5640b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5650b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5660b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5670b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5680b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5700b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5710b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5720b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 575*5ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 576*5ffd83dbSDimitry Andric 5770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 5780b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 5790b57cec5SDimitry Andric#endif 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andricprivate: 5820b57cec5SDimitry Andric _ValueT __value_; 5830b57cec5SDimitry Andric}; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 5860b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); 5870b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); 5880b57cec5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5910b57cec5SDimitry Andricconstexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 5920b57cec5SDimitry Andric return __v.__value_ == 0; 5930b57cec5SDimitry Andric} 5940b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5950b57cec5SDimitry Andricconstexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 5960b57cec5SDimitry Andric return __v.__value_ != 0; 5970b57cec5SDimitry Andric} 5980b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5990b57cec5SDimitry Andricconstexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 6000b57cec5SDimitry Andric return __v.__value_ < 0; 6010b57cec5SDimitry Andric} 6020b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6030b57cec5SDimitry Andricconstexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 6040b57cec5SDimitry Andric return __v.__value_ <= 0; 6050b57cec5SDimitry Andric} 6060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6070b57cec5SDimitry Andricconstexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 6080b57cec5SDimitry Andric return __v.__value_ > 0; 6090b57cec5SDimitry Andric} 6100b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6110b57cec5SDimitry Andricconstexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 6120b57cec5SDimitry Andric return __v.__value_ >= 0; 6130b57cec5SDimitry Andric} 6140b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6150b57cec5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6160b57cec5SDimitry Andric return 0 == __v.__value_; 6170b57cec5SDimitry Andric} 6180b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6190b57cec5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6200b57cec5SDimitry Andric return 0 != __v.__value_; 6210b57cec5SDimitry Andric} 6220b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6230b57cec5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6240b57cec5SDimitry Andric return 0 < __v.__value_; 6250b57cec5SDimitry Andric} 6260b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6270b57cec5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6280b57cec5SDimitry Andric return 0 <= __v.__value_; 6290b57cec5SDimitry Andric} 6300b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6310b57cec5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6320b57cec5SDimitry Andric return 0 > __v.__value_; 6330b57cec5SDimitry Andric} 6340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6350b57cec5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6360b57cec5SDimitry Andric return 0 >= __v.__value_; 6370b57cec5SDimitry Andric} 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 6400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6410b57cec5SDimitry Andricconstexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 6420b57cec5SDimitry Andric return __v; 6430b57cec5SDimitry Andric} 6440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6450b57cec5SDimitry Andricconstexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 6460b57cec5SDimitry Andric return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 6470b57cec5SDimitry Andric} 6480b57cec5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric// named comparison functions 6510b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6520b57cec5SDimitry Andricconstexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6550b57cec5SDimitry Andricconstexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6580b57cec5SDimitry Andricconstexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6610b57cec5SDimitry Andricconstexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6640b57cec5SDimitry Andricconstexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6670b57cec5SDimitry Andricconstexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andricnamespace __comp_detail { 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andricenum _ClassifyCompCategory : unsigned{ 6720b57cec5SDimitry Andric _None, 6730b57cec5SDimitry Andric _WeakEq, 6740b57cec5SDimitry Andric _StrongEq, 6750b57cec5SDimitry Andric _PartialOrd, 6760b57cec5SDimitry Andric _WeakOrd, 6770b57cec5SDimitry Andric _StrongOrd, 6780b57cec5SDimitry Andric _CCC_Size 6790b57cec5SDimitry Andric}; 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andrictemplate <class _Tp> 6820b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 6830b57cec5SDimitry Andricconstexpr _ClassifyCompCategory __type_to_enum() noexcept { 6840b57cec5SDimitry Andric if (is_same_v<_Tp, weak_equality>) 6850b57cec5SDimitry Andric return _WeakEq; 6860b57cec5SDimitry Andric if (is_same_v<_Tp, strong_equality>) 6870b57cec5SDimitry Andric return _StrongEq; 6880b57cec5SDimitry Andric if (is_same_v<_Tp, partial_ordering>) 6890b57cec5SDimitry Andric return _PartialOrd; 6900b57cec5SDimitry Andric if (is_same_v<_Tp, weak_ordering>) 6910b57cec5SDimitry Andric return _WeakOrd; 6920b57cec5SDimitry Andric if (is_same_v<_Tp, strong_ordering>) 6930b57cec5SDimitry Andric return _StrongOrd; 6940b57cec5SDimitry Andric return _None; 6950b57cec5SDimitry Andric} 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andrictemplate <size_t _Size> 6980b57cec5SDimitry Andricconstexpr _ClassifyCompCategory 6990b57cec5SDimitry Andric__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) { 7000b57cec5SDimitry Andric std::array<int, _CCC_Size> __seen = {}; 7010b57cec5SDimitry Andric for (auto __type : __types) 7020b57cec5SDimitry Andric ++__seen[__type]; 7030b57cec5SDimitry Andric if (__seen[_None]) 7040b57cec5SDimitry Andric return _None; 7050b57cec5SDimitry Andric if (__seen[_WeakEq]) 7060b57cec5SDimitry Andric return _WeakEq; 7070b57cec5SDimitry Andric if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd])) 7080b57cec5SDimitry Andric return _WeakEq; 7090b57cec5SDimitry Andric if (__seen[_StrongEq]) 7100b57cec5SDimitry Andric return _StrongEq; 7110b57cec5SDimitry Andric if (__seen[_PartialOrd]) 7120b57cec5SDimitry Andric return _PartialOrd; 7130b57cec5SDimitry Andric if (__seen[_WeakOrd]) 7140b57cec5SDimitry Andric return _WeakOrd; 7150b57cec5SDimitry Andric return _StrongOrd; 7160b57cec5SDimitry Andric} 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andrictemplate <class ..._Ts> 7190b57cec5SDimitry Andricconstexpr auto __get_comp_type() { 7200b57cec5SDimitry Andric using _CCC = _ClassifyCompCategory; 7210b57cec5SDimitry Andric constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}}; 7220b57cec5SDimitry Andric constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd 7230b57cec5SDimitry Andric : __compute_comp_type(__type_kinds); 7240b57cec5SDimitry Andric if constexpr (_Cat == _None) 7250b57cec5SDimitry Andric return void(); 7260b57cec5SDimitry Andric else if constexpr (_Cat == _WeakEq) 7270b57cec5SDimitry Andric return weak_equality::equivalent; 7280b57cec5SDimitry Andric else if constexpr (_Cat == _StrongEq) 7290b57cec5SDimitry Andric return strong_equality::equivalent; 7300b57cec5SDimitry Andric else if constexpr (_Cat == _PartialOrd) 7310b57cec5SDimitry Andric return partial_ordering::equivalent; 7320b57cec5SDimitry Andric else if constexpr (_Cat == _WeakOrd) 7330b57cec5SDimitry Andric return weak_ordering::equivalent; 7340b57cec5SDimitry Andric else if constexpr (_Cat == _StrongOrd) 7350b57cec5SDimitry Andric return strong_ordering::equivalent; 7360b57cec5SDimitry Andric else 7370b57cec5SDimitry Andric static_assert(_Cat != _Cat, "unhandled case"); 7380b57cec5SDimitry Andric} 7390b57cec5SDimitry Andric} // namespace __comp_detail 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric// [cmp.common], common comparison category type 7420b57cec5SDimitry Andrictemplate<class... _Ts> 7430b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS common_comparison_category { 7440b57cec5SDimitry Andric using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 7450b57cec5SDimitry Andric}; 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andrictemplate<class... _Ts> 7480b57cec5SDimitry Andricusing common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric// [cmp.alg], comparison algorithms 7510b57cec5SDimitry Andric// TODO: unimplemented 7520b57cec5SDimitry Andrictemplate<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); 7530b57cec5SDimitry Andrictemplate<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); 7540b57cec5SDimitry Andrictemplate<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); 7550b57cec5SDimitry Andrictemplate<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); 7560b57cec5SDimitry Andrictemplate<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs); 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric#endif // _LIBCPP_COMPARE 763