226 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class T, class Cat = partial_ordering>12// concept three_way_comparable = // see below13 14#include <compare>15#include <cstddef>16 17#include "compare_types.h"18#include "test_macros.h"19 20namespace fundamentals {21// with default ordering22static_assert(std::three_way_comparable<int>);23static_assert(std::three_way_comparable<double>);24static_assert(std::three_way_comparable<void*>);25static_assert(std::three_way_comparable<char*>);26static_assert(std::three_way_comparable<char const*>);27static_assert(std::three_way_comparable<char volatile*>);28static_assert(std::three_way_comparable<char const volatile*>);29static_assert(std::three_way_comparable<wchar_t&>);30#ifndef TEST_HAS_NO_CHAR8_T31static_assert(std::three_way_comparable<char8_t const&>);32#endif33static_assert(std::three_way_comparable<char16_t volatile&>);34static_assert(std::three_way_comparable<char32_t const volatile&>);35#ifndef TEST_HAS_NO_INT12836static_assert(std::three_way_comparable<__int128_t const&>);37static_assert(std::three_way_comparable<__uint128_t const&>);38#endif39static_assert(std::three_way_comparable<unsigned char&&>);40static_assert(std::three_way_comparable<unsigned short const&&>);41static_assert(std::three_way_comparable<unsigned int volatile&&>);42static_assert(std::three_way_comparable<unsigned long const volatile&&>);43 44// with explicit ordering45static_assert(std::three_way_comparable<int, std::strong_ordering>);46static_assert(std::three_way_comparable<int, std::weak_ordering>);47static_assert(std::three_way_comparable<double, std::partial_ordering>);48static_assert(!std::three_way_comparable<double, std::weak_ordering>);49static_assert(std::three_way_comparable<void*, std::strong_ordering>);50static_assert(std::three_way_comparable<void*, std::weak_ordering>);51static_assert(std::three_way_comparable<char*, std::strong_ordering>);52static_assert(std::three_way_comparable<char*, std::weak_ordering>);53static_assert(std::three_way_comparable<char const*, std::strong_ordering>);54static_assert(std::three_way_comparable<char const*, std::weak_ordering>);55static_assert(std::three_way_comparable<char volatile*, std::strong_ordering>);56static_assert(std::three_way_comparable<char volatile*, std::weak_ordering>);57static_assert(std::three_way_comparable<char const volatile*, std::strong_ordering>);58static_assert(std::three_way_comparable<char const volatile*, std::weak_ordering>);59static_assert(std::three_way_comparable<wchar_t&, std::strong_ordering>);60static_assert(std::three_way_comparable<wchar_t&, std::weak_ordering>);61static_assert(std::three_way_comparable<char8_t const&, std::strong_ordering>);62static_assert(std::three_way_comparable<char8_t const&, std::weak_ordering>);63static_assert(std::three_way_comparable<char16_t volatile&, std::strong_ordering>);64static_assert(std::three_way_comparable<char16_t volatile&, std::weak_ordering>);65static_assert(std::three_way_comparable<char32_t const volatile&, std::strong_ordering>);66static_assert(std::three_way_comparable<char32_t const volatile&, std::weak_ordering>);67static_assert(std::three_way_comparable<unsigned char&&, std::strong_ordering>);68static_assert(std::three_way_comparable<unsigned char&&, std::weak_ordering>);69static_assert(std::three_way_comparable<unsigned short const&&, std::strong_ordering>);70static_assert(std::three_way_comparable<unsigned short const&&, std::weak_ordering>);71static_assert(std::three_way_comparable<unsigned int volatile&&, std::strong_ordering>);72static_assert(std::three_way_comparable<unsigned int volatile&&, std::weak_ordering>);73static_assert(std::three_way_comparable<unsigned long const volatile&&, std::strong_ordering>);74static_assert(std::three_way_comparable<unsigned long const volatile&&, std::weak_ordering>);75 76static_assert(!std::three_way_comparable<int[5]>);77static_assert(!std::three_way_comparable<int (*)(int)>);78static_assert(!std::three_way_comparable<int (&)(int)>);79static_assert(!std::three_way_comparable<int (*)(int) noexcept>);80static_assert(!std::three_way_comparable<int (&)(int) noexcept>);81static_assert(!std::three_way_comparable<std::nullptr_t>);82static_assert(!std::three_way_comparable<void>);83 84struct S {};85static_assert(!std::three_way_comparable<int S::*>);86static_assert(!std::three_way_comparable<int (S::*)()>);87static_assert(!std::three_way_comparable<int (S::*)() noexcept>);88static_assert(!std::three_way_comparable<int (S::*)() &>);89static_assert(!std::three_way_comparable<int (S::*)() & noexcept>);90static_assert(!std::three_way_comparable<int (S::*)() &&>);91static_assert(!std::three_way_comparable<int (S::*)() && noexcept>);92static_assert(!std::three_way_comparable<int (S::*)() const>);93static_assert(!std::three_way_comparable<int (S::*)() const noexcept>);94static_assert(!std::three_way_comparable<int (S::*)() const&>);95static_assert(!std::three_way_comparable<int (S::*)() const & noexcept>);96static_assert(!std::three_way_comparable<int (S::*)() const&&>);97static_assert(!std::three_way_comparable<int (S::*)() const && noexcept>);98static_assert(!std::three_way_comparable<int (S::*)() volatile>);99static_assert(!std::three_way_comparable<int (S::*)() volatile noexcept>);100static_assert(!std::three_way_comparable<int (S::*)() volatile&>);101static_assert(!std::three_way_comparable<int (S::*)() volatile & noexcept>);102static_assert(!std::three_way_comparable<int (S::*)() volatile&&>);103static_assert(!std::three_way_comparable<int (S::*)() volatile && noexcept>);104static_assert(!std::three_way_comparable<int (S::*)() const volatile>);105static_assert(!std::three_way_comparable<int (S::*)() const volatile noexcept>);106static_assert(!std::three_way_comparable<int (S::*)() const volatile&>);107static_assert(!std::three_way_comparable<int (S::*)() const volatile & noexcept>);108static_assert(!std::three_way_comparable<int (S::*)() const volatile&&>);109static_assert(!std::three_way_comparable<int (S::*)() const volatile && noexcept>);110} // namespace fundamentals111 112namespace user_defined {113 114struct S {115 auto operator<=>(const S&) const = default;116};117 118static_assert(std::three_way_comparable<S>);119static_assert(std::three_way_comparable<S, std::strong_ordering>);120static_assert(std::three_way_comparable<S, std::partial_ordering>);121 122struct SpaceshipNotDeclared {123};124 125static_assert(!std::three_way_comparable<SpaceshipNotDeclared>);126 127struct SpaceshipDeleted {128 auto operator<=>(const SpaceshipDeleted&) const = delete;129};130 131static_assert(!std::three_way_comparable<SpaceshipDeleted>);132 133struct SpaceshipWithoutEqualityOperator {134 auto operator<=>(const SpaceshipWithoutEqualityOperator&) const;135};136 137static_assert(!std::three_way_comparable<SpaceshipWithoutEqualityOperator>);138 139struct EqualityOperatorDeleted {140 bool operator==(const EqualityOperatorDeleted&) const = delete;141};142 143static_assert(!std::three_way_comparable<EqualityOperatorDeleted>);144 145struct EqualityOperatorOnly {146 bool operator==(const EqualityOperatorOnly&) const = default;147};148 149static_assert(!std::three_way_comparable<EqualityOperatorOnly>);150 151struct SpaceshipDeclaredEqualityOperatorDeleted {152 bool operator==(const SpaceshipDeclaredEqualityOperatorDeleted&) const = delete;153 auto operator<=>(const SpaceshipDeclaredEqualityOperatorDeleted&) const = default;154};155 156static_assert(!std::three_way_comparable<SpaceshipDeclaredEqualityOperatorDeleted>);157 158struct AllInequalityOperators {159 bool operator<(const AllInequalityOperators&) const;160 bool operator<=(const AllInequalityOperators&) const;161 bool operator>(const AllInequalityOperators&) const;162 bool operator>=(const AllInequalityOperators&) const;163 bool operator!=(const AllInequalityOperators&) const;164};165 166static_assert(!std::three_way_comparable<AllInequalityOperators>);167 168struct AllComparisonOperators {169 bool operator<(const AllComparisonOperators&) const;170 bool operator<=(const AllComparisonOperators&) const;171 bool operator>(const AllComparisonOperators&) const;172 bool operator>=(const AllComparisonOperators&) const;173 bool operator!=(const AllComparisonOperators&) const;174 bool operator==(const AllComparisonOperators&) const;175};176 177static_assert(!std::three_way_comparable<AllComparisonOperators>);178 179struct AllButOneInequalityOperators {180 bool operator<(const AllButOneInequalityOperators&) const;181 bool operator<=(const AllButOneInequalityOperators&) const;182 bool operator>(const AllButOneInequalityOperators&) const;183 bool operator!=(const AllButOneInequalityOperators&) const;184};185 186static_assert(!std::three_way_comparable<AllButOneInequalityOperators>);187 188struct AllInequalityOperatorsOneDeleted {189 bool operator<(const AllInequalityOperatorsOneDeleted&) const;190 bool operator<=(const AllInequalityOperatorsOneDeleted&) const;191 bool operator>(const AllInequalityOperatorsOneDeleted&) const;192 bool operator>=(const AllInequalityOperatorsOneDeleted&) const = delete;193 bool operator!=(const AllInequalityOperatorsOneDeleted&) const;194};195 196static_assert(!std::three_way_comparable<AllInequalityOperatorsOneDeleted>);197 198struct EqualityOperatorWrongReturnType {199 int operator==(const EqualityOperatorWrongReturnType&);200 auto operator<=>(const EqualityOperatorWrongReturnType&) const = default;201};202 203static_assert(!std::three_way_comparable<EqualityOperatorWrongReturnType>);204 205struct SpaceshipWrongReturnType {206 bool operator==(const SpaceshipWrongReturnType&) const = default;207 int operator<=>(const SpaceshipWrongReturnType&);208};209 210static_assert(!std::three_way_comparable<SpaceshipWrongReturnType>);211 212struct EqualityOperatorNonConstArgument {213 bool operator==(EqualityOperatorNonConstArgument&);214 auto operator<=>(const EqualityOperatorNonConstArgument&) const = default;215};216 217static_assert(!std::three_way_comparable<EqualityOperatorNonConstArgument>);218 219struct SpaceshipNonConstArgument {220 bool operator==(const SpaceshipNonConstArgument&) const = default;221 auto operator<=>(SpaceshipNonConstArgument&);222};223 224static_assert(!std::three_way_comparable<SpaceshipNonConstArgument>);225} // namespace user_defined226