679 changes: 679 additions & 0 deletions libcxx/include/compare

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ module std [system] {
header "codecvt"
export *
}
module compare {
header "compare"
export *
}
module complex {
header "complex"
export *
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/libcxx/double_include.sh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <clocale>
#include <cmath>
#include <codecvt>
#include <compare>
#include <complex>
#include <complex.h>
#include <condition_variable>
Expand Down
20 changes: 20 additions & 0 deletions libcxx/test/libcxx/language.support/cmp/version.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <compare>

#include <compare>

#ifndef _LIBCPP_VERSION
#error _LIBCPP_VERSION not defined
#endif

int main()
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// template <class ...Ts> struct common_comparison_category
// template <class ...Ts> using common_comparison_category_t


#include <compare>
#include <type_traits>
#include <cassert>

#include "test_macros.h"

const volatile void* volatile sink;

template <class Expect, class ...Args>
void test_cat() {
using Cat = std::common_comparison_category<Args...>;
using CatT = typename Cat::type;
static_assert(std::is_same<CatT, std::common_comparison_category_t<Args...>>::value, "");
static_assert(std::is_same<CatT, Expect>::value, "expected different category");
};


// [class.spaceship]p4: The 'common comparison type' U of a possibly-empty list
// of 'n' types T0, T1, ..., TN, is defined as follows:
int main() {
using WE = std::weak_equality;
using SE = std::strong_equality;
using PO = std::partial_ordering;
using WO = std::weak_ordering;
using SO = std::strong_ordering;

// [class.spaceship]p4.1: If any Ti is not a comparison category tpe, U is void.
{
test_cat<void, void>();
test_cat<void, int*>();
test_cat<void, SO&>();
test_cat<void, SO const>();
test_cat<void, SO*>();
test_cat<void, SO, void, SO>();
}

// [class.spaceship]p4.2: Otherwise, if at least on Ti is
// std::weak_equality, or at least one Ti is std::strong_equality and at least
// one Tj is std::partial_ordering or std::weak_ordering, U is std::weak_equality
{
test_cat<WE, WE>();
test_cat<WE, SO, WE, SO>();
test_cat<WE, SE, SO, PO>();
test_cat<WE, WO, SO, SE>();
}

// [class.spaceship]p4.3: Otherwise, if at least one Ti is std::strong_equality,
// U is std::strong_equality
{
test_cat<SE, SE>();
test_cat<SE, SO, SE, SO>();
}

// [class.spaceship]p4.4: Otherwise, if at least one Ti is std::partial_ordering,
// U is std::partial_ordering
{
test_cat<PO, PO>();
test_cat<PO, SO, PO, SO>();
test_cat<PO, WO, PO, SO>();
}

// [class.spaceship]p4.5: Otherwise, if at least one Ti is std::weak_ordering,
// U is std::weak_ordering
{
test_cat<WO, WO>();
test_cat<WO, SO, WO, SO>();
}

// [class.spaceship]p4.6: Otherwise, U is std::strong_ordering. [Note: in
// particular this is the result when n is 0. -- end note]
{
test_cat<SO>(); // empty type list
test_cat<SO, SO>();
test_cat<SO, SO, SO>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// class partial_ordering


#include <compare>
#include <type_traits>
#include <cassert>

#include "test_macros.h"

const volatile void* volatile sink;

void test_static_members() {
DoNotOptimize(&std::partial_ordering::less);
DoNotOptimize(&std::partial_ordering::equivalent);
DoNotOptimize(&std::partial_ordering::greater);
DoNotOptimize(&std::partial_ordering::unordered);
}

void test_signatures() {
auto& Eq = std::partial_ordering::equivalent;

ASSERT_NOEXCEPT(Eq == 0);
ASSERT_NOEXCEPT(0 == Eq);
ASSERT_NOEXCEPT(Eq != 0);
ASSERT_NOEXCEPT(0 != Eq);
ASSERT_NOEXCEPT(0 < Eq);
ASSERT_NOEXCEPT(Eq < 0);
ASSERT_NOEXCEPT(0 <= Eq);
ASSERT_NOEXCEPT(Eq <= 0);
ASSERT_NOEXCEPT(0 > Eq);
ASSERT_NOEXCEPT(Eq > 0);
ASSERT_NOEXCEPT(0 >= Eq);
ASSERT_NOEXCEPT(Eq >= 0);
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
ASSERT_NOEXCEPT(0 <=> Eq);
ASSERT_NOEXCEPT(Eq <=> 0);
ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::partial_ordering);
ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::partial_ordering);
#endif
}

constexpr bool test_conversion() {
static_assert(std::is_convertible<const std::partial_ordering, std::weak_equality>::value, "");
{ // value == 0
auto V = std::partial_ordering::equivalent;
std::weak_equality WV = V;
assert(WV == 0);
}
std::partial_ordering TestCases[] = {
std::partial_ordering::less,
std::partial_ordering::greater,
std::partial_ordering::unordered
};
for (auto V : TestCases)
{ // value != 0
std::weak_equality WV = V;
assert(WV != 0);
}
return true;
}

constexpr bool test_constexpr() {
auto& Eq = std::partial_ordering::equivalent;
auto& Less = std::partial_ordering::less;
auto& Greater = std::partial_ordering::greater;
auto& Unord = std::partial_ordering::unordered;
struct {
std::partial_ordering Value;
bool ExpectEq;
bool ExpectNeq;
bool ExpectLess;
bool ExpectGreater;
} TestCases[] = {
{Eq, true, false, false, false},
{Less, false, true, true, false},
{Greater, false, true, false, true},
{Unord, false, true, false, false}
};
for (auto TC : TestCases) {
auto V = TC.Value;
assert((V == 0) == TC.ExpectEq);
assert((0 == V) == TC.ExpectEq);
assert((V != 0) == TC.ExpectNeq);
assert((0 != V) == TC.ExpectNeq);

assert((V < 0) == TC.ExpectLess);
assert((V > 0) == TC.ExpectGreater);
assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));

assert((0 < V) == TC.ExpectGreater);
assert((0 > V) == TC.ExpectLess);
assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
}
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
{
std::partial_ordering res = (Eq <=> 0);
((void)res);
res = (0 <=> Eq);
((void)res);
}
enum ExpectRes {
ER_Greater,
ER_Less,
ER_Equiv,
ER_Unord
};
struct {
std::partial_ordering Value;
ExpectRes Expect;
} SpaceshipTestCases[] = {
{std::partial_ordering::equivalent, ER_Equiv},
{std::partial_ordering::less, ER_Less},
{std::partial_ordering::greater, ER_Greater},
{std::partial_ordering::unordered, ER_Unord}
};
for (auto TC : SpaceshipTestCases)
{
std::partial_ordering Res = (0 <=> TC.Value);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
assert(0 == Res);
break;
case ER_Less:
assert(Res < 0);
break;
case ER_Greater:
assert(Res > 0);
break;
case ER_Unord:
assert(Res != 0);
assert(0 != Res);
assert((Res < 0) == false);
assert((Res > 0) == false);
assert((Res == 0) == false);
break;
}
}
#endif

return true;
}

int main() {
test_static_members();
test_signatures();
static_assert(test_conversion(), "conversion test failed");
static_assert(test_constexpr(), "constexpr test failed");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// class strong_equality


#include <compare>
#include <type_traits>
#include <cassert>

#include "test_macros.h"

const volatile void* volatile sink;

void test_static_members() {
DoNotOptimize(&std::strong_equality::equal);
DoNotOptimize(&std::strong_equality::nonequal);
DoNotOptimize(&std::strong_equality::equivalent);
DoNotOptimize(&std::strong_equality::nonequivalent);
}

void test_signatures() {
auto& Eq = std::strong_equality::equivalent;

ASSERT_NOEXCEPT(Eq == 0);
ASSERT_NOEXCEPT(0 == Eq);
ASSERT_NOEXCEPT(Eq != 0);
ASSERT_NOEXCEPT(0 != Eq);
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
ASSERT_NOEXCEPT(0 <=> Eq);
ASSERT_NOEXCEPT(Eq <=> 0);
ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::strong_equality);
ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_equality);
#endif
}

void test_conversion() {
constexpr std::weak_equality res = std::strong_equality::equivalent;
static_assert(res == 0, "");
static_assert(std::is_convertible<const std::strong_equality&,
std::weak_equality>::value, "");
static_assert(res == 0, "expected equal");

constexpr std::weak_equality neq_res = std::strong_equality::nonequivalent;
static_assert(neq_res != 0, "expected not equal");
}

constexpr bool test_constexpr() {
auto& Eq = std::strong_equality::equal;
auto& NEq = std::strong_equality::nonequal;
auto& Equiv = std::strong_equality::equivalent;
auto& NEquiv = std::strong_equality::nonequivalent;
assert((Eq == 0) == true);
assert((0 == Eq) == true);
assert((Equiv == 0) == true);
assert((0 == Equiv) == true);
assert((NEq == 0) == false);
assert((0 == NEq) == false);
assert((NEquiv == 0) == false);
assert((0 == NEquiv) == false);

assert((Eq != 0) == false);
assert((0 != Eq) == false);
assert((Equiv != 0) == false);
assert((0 != Equiv) == false);
assert((NEq != 0) == true);
assert((0 != NEq) == true);
assert((NEquiv != 0) == true);
assert((0 != NEquiv) == true);

#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
std::strong_equality res = (Eq <=> 0);
((void)res);
res = (0 <=> Eq);
((void)res);
#endif

return true;
}

int main() {
test_static_members();
test_signatures();
test_conversion();
static_assert(test_constexpr(), "constexpr test failed");
}
212 changes: 212 additions & 0 deletions libcxx/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// class strong_ordering


#include <compare>
#include <type_traits>
#include <cassert>

#include "test_macros.h"

const volatile void* volatile sink;

void test_static_members() {
DoNotOptimize(&std::strong_ordering::less);
DoNotOptimize(&std::strong_ordering::equal);
DoNotOptimize(&std::strong_ordering::equivalent);
DoNotOptimize(&std::strong_ordering::greater);
}

void test_signatures() {
auto& Eq = std::strong_ordering::equivalent;

ASSERT_NOEXCEPT(Eq == 0);
ASSERT_NOEXCEPT(0 == Eq);
ASSERT_NOEXCEPT(Eq != 0);
ASSERT_NOEXCEPT(0 != Eq);
ASSERT_NOEXCEPT(0 < Eq);
ASSERT_NOEXCEPT(Eq < 0);
ASSERT_NOEXCEPT(0 <= Eq);
ASSERT_NOEXCEPT(Eq <= 0);
ASSERT_NOEXCEPT(0 > Eq);
ASSERT_NOEXCEPT(Eq > 0);
ASSERT_NOEXCEPT(0 >= Eq);
ASSERT_NOEXCEPT(Eq >= 0);
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
ASSERT_NOEXCEPT(0 <=> Eq);
ASSERT_NOEXCEPT(Eq <=> 0);
ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::strong_ordering);
ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_ordering);
#endif
}

constexpr bool test_conversion() {
static_assert(std::is_convertible<const std::strong_ordering&,
std::weak_equality>::value, "");
{ // value == 0
auto V = std::strong_ordering::equivalent;
std::weak_equality WV = V;
assert(WV == 0);
}
std::strong_ordering WeakTestCases[] = {
std::strong_ordering::less,
std::strong_ordering::greater,
};
for (auto V : WeakTestCases)
{ // value != 0
std::weak_equality WV = V;
assert(WV != 0);
}
static_assert(std::is_convertible<const std::strong_ordering&,
std::strong_equality>::value, "");
{ // value == 0
auto V = std::strong_ordering::equivalent;
std::strong_equality WV = V;
assert(WV == 0);
}
{ // value == 0
auto V = std::strong_ordering::equal;
std::strong_equality WV = V;
assert(WV == 0);
}
std::strong_ordering StrongTestCases[] = {
std::strong_ordering::less,
std::strong_ordering::greater,
};
for (auto V : StrongTestCases)
{ // value != 0
std::strong_equality WV = V;
assert(WV != 0);
}

static_assert(std::is_convertible<const std::strong_ordering&,
std::partial_ordering>::value, "");
{ // value == 0
auto V = std::strong_ordering::equivalent;
std::partial_ordering WV = V;
assert(WV == 0);
}
{ // value < 0
auto V = std::strong_ordering::less;
std::partial_ordering WV = V;
assert(WV < 0);
}
{ // value > 0
auto V = std::strong_ordering::greater;
std::partial_ordering WV = V;
assert(WV > 0);
}

static_assert(std::is_convertible<const std::strong_ordering&,
std::weak_ordering>::value, "");
{ // value == 0
auto V = std::strong_ordering::equivalent;
std::weak_ordering WV = V;
assert(WV == 0);
}
{ // value < 0
auto V = std::strong_ordering::less;
std::weak_ordering WV = V;
assert(WV < 0);
}
{ // value > 0
auto V = std::strong_ordering::greater;
std::weak_ordering WV = V;
assert(WV > 0);
}
return true;
}

constexpr bool test_constexpr() {
auto& Eq = std::strong_ordering::equal;
auto& Equiv = std::strong_ordering::equivalent;
auto& Less = std::strong_ordering::less;
auto& Greater = std::strong_ordering::greater;
struct {
std::strong_ordering Value;
bool ExpectEq;
bool ExpectNeq;
bool ExpectLess;
bool ExpectGreater;
} TestCases[] = {
{Eq, true, false, false, false},
{Equiv, true, false, false, false},
{Less, false, true, true, false},
{Greater, false, true, false, true},
};
for (auto TC : TestCases) {
auto V = TC.Value;
assert((V == 0) == TC.ExpectEq);
assert((0 == V) == TC.ExpectEq);
assert((V != 0) == TC.ExpectNeq);
assert((0 != V) == TC.ExpectNeq);

assert((V < 0) == TC.ExpectLess);
assert((V > 0) == TC.ExpectGreater);
assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));

assert((0 < V) == TC.ExpectGreater);
assert((0 > V) == TC.ExpectLess);
assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
}
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
{
std::strong_ordering res = (Eq <=> 0);
((void)res);
res = (0 <=> Eq);
((void)res);
}
enum ExpectRes {
ER_Greater,
ER_Less,
ER_Equiv
};
struct {
std::strong_ordering Value;
ExpectRes Expect;
} SpaceshipTestCases[] = {
{std::strong_ordering::equivalent, ER_Equiv},
{std::strong_ordering::less, ER_Less},
{std::strong_ordering::greater, ER_Greater},
};
for (auto TC : SpaceshipTestCases)
{
std::strong_ordering Res = (0 <=> TC.Value);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
assert(0 == Res);
break;
case ER_Less:
assert(Res < 0);
break;
case ER_Greater:
assert(Res > 0);
break;
}
}
#endif

return true;
}

int main() {
test_static_members();
test_signatures();
static_assert(test_conversion(), "conversion test failed");
static_assert(test_constexpr(), "constexpr test failed");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// class weak_equality


#include <compare>
#include <cassert>
#include "test_macros.h"

const volatile void* volatile sink;

void test_static_members() {
DoNotOptimize(&std::weak_equality::equivalent);
DoNotOptimize(&std::weak_equality::nonequivalent);
}

void test_signatures() {
auto& Eq = std::weak_equality::equivalent;

ASSERT_NOEXCEPT(Eq == 0);
ASSERT_NOEXCEPT(0 == Eq);
ASSERT_NOEXCEPT(Eq != 0);
ASSERT_NOEXCEPT(0 != Eq);
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
ASSERT_NOEXCEPT(0 <=> Eq);
ASSERT_NOEXCEPT(Eq <=> 0);
ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::weak_equality);
ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::weak_equality);
#endif
}

constexpr bool test_constexpr() {
auto& Eq = std::weak_equality::equivalent;
auto& NEq = std::weak_equality::nonequivalent;
assert((Eq == 0) == true);
assert((0 == Eq) == true);
assert((NEq == 0) == false);
assert((0 == NEq) == false);

assert((Eq != 0) == false);
assert((0 != Eq) == false);
assert((NEq != 0) == true);
assert((0 != NEq) == true);

#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
std::weak_equality res = (Eq <=> 0);
((void)res);
res = (0 <=> Eq);
((void)res);
#endif

return true;
}

int main() {
test_static_members();
test_signatures();
static_assert(test_constexpr(), "constexpr test failed");
}
169 changes: 169 additions & 0 deletions libcxx/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17

// <compare>

// class weak_ordering


#include <compare>
#include <type_traits>
#include <cassert>

#include "test_macros.h"

const volatile void* volatile sink;

void test_static_members() {
DoNotOptimize(&std::weak_ordering::less);
DoNotOptimize(&std::weak_ordering::equivalent);
DoNotOptimize(&std::weak_ordering::greater);
}

void test_signatures() {
auto& Eq = std::weak_ordering::equivalent;

ASSERT_NOEXCEPT(Eq == 0);
ASSERT_NOEXCEPT(0 == Eq);
ASSERT_NOEXCEPT(Eq != 0);
ASSERT_NOEXCEPT(0 != Eq);
ASSERT_NOEXCEPT(0 < Eq);
ASSERT_NOEXCEPT(Eq < 0);
ASSERT_NOEXCEPT(0 <= Eq);
ASSERT_NOEXCEPT(Eq <= 0);
ASSERT_NOEXCEPT(0 > Eq);
ASSERT_NOEXCEPT(Eq > 0);
ASSERT_NOEXCEPT(0 >= Eq);
ASSERT_NOEXCEPT(Eq >= 0);
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
ASSERT_NOEXCEPT(0 <=> Eq);
ASSERT_NOEXCEPT(Eq <=> 0);
ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::weak_ordering);
ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::weak_ordering);
#endif
}

constexpr bool test_conversion() {
static_assert(std::is_convertible<const std::weak_ordering&,
std::weak_equality>::value, "");
{ // value == 0
auto V = std::weak_ordering::equivalent;
std::weak_equality WV = V;
assert(WV == 0);
}
std::weak_ordering WeakTestCases[] = {
std::weak_ordering::less,
std::weak_ordering::greater,
};
for (auto V : WeakTestCases)
{ // value != 0
std::weak_equality WV = V;
assert(WV != 0);
}
static_assert(std::is_convertible<const std::weak_ordering&,
std::partial_ordering>::value, "");
{ // value == 0
auto V = std::weak_ordering::equivalent;
std::partial_ordering WV = V;
assert(WV == 0);
}
{ // value < 0
auto V = std::weak_ordering::less;
std::partial_ordering WV = V;
assert(WV < 0);
}
{ // value > 0
auto V = std::weak_ordering::greater;
std::partial_ordering WV = V;
assert(WV > 0);
}
return true;
}

constexpr bool test_constexpr() {
auto& Eq = std::weak_ordering::equivalent;
auto& Less = std::weak_ordering::less;
auto& Greater = std::weak_ordering::greater;
struct {
std::weak_ordering Value;
bool ExpectEq;
bool ExpectNeq;
bool ExpectLess;
bool ExpectGreater;
} TestCases[] = {
{Eq, true, false, false, false},
{Less, false, true, true, false},
{Greater, false, true, false, true},
};
for (auto TC : TestCases) {
auto V = TC.Value;
assert((V == 0) == TC.ExpectEq);
assert((0 == V) == TC.ExpectEq);
assert((V != 0) == TC.ExpectNeq);
assert((0 != V) == TC.ExpectNeq);

assert((V < 0) == TC.ExpectLess);
assert((V > 0) == TC.ExpectGreater);
assert((V <= 0) == (TC.ExpectLess || TC.ExpectEq));
assert((V >= 0) == (TC.ExpectGreater || TC.ExpectEq));

assert((0 < V) == TC.ExpectGreater);
assert((0 > V) == TC.ExpectLess);
assert((0 <= V) == (TC.ExpectGreater || TC.ExpectEq));
assert((0 >= V) == (TC.ExpectLess || TC.ExpectEq));
}
#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR
{
std::weak_ordering res = (Eq <=> 0);
((void)res);
res = (0 <=> Eq);
((void)res);
}
enum ExpectRes {
ER_Greater,
ER_Less,
ER_Equiv
};
struct {
std::weak_ordering Value;
ExpectRes Expect;
} SpaceshipTestCases[] = {
{std::weak_ordering::equivalent, ER_Equiv},
{std::weak_ordering::less, ER_Less},
{std::weak_ordering::greater, ER_Greater},
};
for (auto TC : SpaceshipTestCases)
{
std::weak_ordering Res = (0 <=> TC.Value);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
assert(0 == Res);
break;
case ER_Less:
assert(Res < 0);
break;
case ER_Greater:
assert(Res > 0);
break;
}
}
#endif

return true;
}

int main() {
test_static_members();
test_signatures();
static_assert(test_conversion(), "conversion test failed");
static_assert(test_constexpr(), "constexpr test failed");
}
5 changes: 5 additions & 0 deletions libcxx/test/support/test_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@
#define TEST_SAFE_STATIC
#endif

// FIXME: Fix this feature check when either (A) a compiler provides a complete
// implementation, or (b) a feature check macro is specified
#define TEST_HAS_NO_SPACESHIP_OPERATOR


#if TEST_STD_VER < 11
#define ASSERT_NOEXCEPT(...)
#define ASSERT_NOT_NOEXCEPT(...)
Expand Down