1//===-- Utility class to test different flavors of totalorder ---*- C++ -*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERTEST_H
10#define LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERTEST_H
11
12#include "test/UnitTest/FEnvSafeTest.h"
13#include "test/UnitTest/FPMatcher.h"
14#include "test/UnitTest/Test.h"
15
16using LIBC_NAMESPACE::Sign;
17
18template <typename T>
19class TotalOrderTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
20
21 DECLARE_SPECIAL_CONSTANTS(T)
22
23public:
24 typedef int (*TotalOrderFunc)(const T *, const T *);
25
26 bool funcWrapper(TotalOrderFunc func, T x, T y) { return func(&x, &y) != 0; }
27
28 void testXLesserThanY(TotalOrderFunc func) {
29 EXPECT_TRUE(funcWrapper(func, neg_inf, inf));
30
31 EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.1)));
32 EXPECT_TRUE(funcWrapper(func, T(0.0), T(123.38)));
33
34 EXPECT_TRUE(funcWrapper(func, T(-0.1), T(0.0)));
35 EXPECT_TRUE(funcWrapper(func, T(-123.38), T(0.0)));
36
37 EXPECT_TRUE(funcWrapper(func, T(-0.1), T(0.1)));
38 EXPECT_TRUE(funcWrapper(func, T(-123.38), T(123.38)));
39 }
40
41 void testXGreaterThanY(TotalOrderFunc func) {
42 EXPECT_FALSE(funcWrapper(func, inf, neg_inf));
43
44 EXPECT_FALSE(funcWrapper(func, T(0.0), T(-0.1)));
45 EXPECT_FALSE(funcWrapper(func, T(0.0), T(-123.38)));
46
47 EXPECT_FALSE(funcWrapper(func, T(0.1), T(0.0)));
48 EXPECT_FALSE(funcWrapper(func, T(123.38), T(0.0)));
49
50 EXPECT_FALSE(funcWrapper(func, T(0.1), T(-0.1)));
51 EXPECT_FALSE(funcWrapper(func, T(123.38), T(-123.38)));
52 }
53
54 void testXEqualToY(TotalOrderFunc func) {
55 EXPECT_TRUE(funcWrapper(func, inf, inf));
56 EXPECT_TRUE(funcWrapper(func, neg_inf, neg_inf));
57
58 EXPECT_TRUE(funcWrapper(func, T(-0.0), T(0.0)));
59 EXPECT_FALSE(funcWrapper(func, T(0.0), T(-0.0)));
60
61 EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.0)));
62 EXPECT_TRUE(funcWrapper(func, T(-0.0), T(-0.0)));
63 EXPECT_TRUE(funcWrapper(func, T(0.1), T(0.1)));
64 EXPECT_TRUE(funcWrapper(func, T(-0.1), T(-0.1)));
65 EXPECT_TRUE(funcWrapper(func, T(123.38), T(123.38)));
66 EXPECT_TRUE(funcWrapper(func, T(-123.38), T(-123.38)));
67 }
68
69 void testSingleNaN(TotalOrderFunc func) {
70 EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(0.0)));
71 EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(0.1)));
72 EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(123.38)));
73
74 EXPECT_FALSE(funcWrapper(func, T(0.0), neg_aNaN));
75 EXPECT_FALSE(funcWrapper(func, T(0.1), neg_aNaN));
76 EXPECT_FALSE(funcWrapper(func, T(123.38), neg_aNaN));
77
78 EXPECT_TRUE(funcWrapper(func, T(0.0), aNaN));
79 EXPECT_TRUE(funcWrapper(func, T(0.1), aNaN));
80 EXPECT_TRUE(funcWrapper(func, T(123.38), aNaN));
81
82 EXPECT_FALSE(funcWrapper(func, aNaN, T(0.0)));
83 EXPECT_FALSE(funcWrapper(func, aNaN, T(0.1)));
84 EXPECT_FALSE(funcWrapper(func, aNaN, T(123.38)));
85 }
86
87 void testNaNSigns(TotalOrderFunc func) {
88 EXPECT_TRUE(funcWrapper(func, neg_aNaN, aNaN));
89 EXPECT_TRUE(funcWrapper(func, neg_aNaN, sNaN));
90 EXPECT_TRUE(funcWrapper(func, neg_sNaN, aNaN));
91 EXPECT_TRUE(funcWrapper(func, neg_sNaN, sNaN));
92
93 EXPECT_FALSE(funcWrapper(func, aNaN, neg_aNaN));
94 EXPECT_FALSE(funcWrapper(func, aNaN, neg_sNaN));
95 EXPECT_FALSE(funcWrapper(func, sNaN, neg_aNaN));
96 EXPECT_FALSE(funcWrapper(func, sNaN, neg_sNaN));
97 }
98
99 void testQuietVsSignalingNaN(TotalOrderFunc func) {
100 EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_sNaN));
101 EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_aNaN));
102 EXPECT_TRUE(funcWrapper(func, sNaN, aNaN));
103 EXPECT_FALSE(funcWrapper(func, aNaN, sNaN));
104 }
105
106 void testNaNPayloads(TotalOrderFunc func) {
107 T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
108 T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
109 T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
110 T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
111
112 EXPECT_TRUE(funcWrapper(func, aNaN, aNaN));
113 EXPECT_TRUE(funcWrapper(func, sNaN, sNaN));
114 EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
115 EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
116 EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
117 EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
118
119 EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN));
120 EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN));
121 EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
122 EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
123 EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
124 EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
125 }
126};
127
128#define LIST_TOTALORDER_TESTS(T, func) \
129 using LlvmLibcTotalOrderTest = TotalOrderTestTemplate<T>; \
130 TEST_F(LlvmLibcTotalOrderTest, XLesserThanY) { testXLesserThanY(&func); } \
131 TEST_F(LlvmLibcTotalOrderTest, XGreaterThanY) { testXGreaterThanY(&func); } \
132 TEST_F(LlvmLibcTotalOrderTest, XEqualToY) { testXEqualToY(&func); } \
133 TEST_F(LlvmLibcTotalOrderTest, SingleNaN) { testSingleNaN(&func); } \
134 TEST_F(LlvmLibcTotalOrderTest, NaNSigns) { testNaNSigns(&func); } \
135 TEST_F(LlvmLibcTotalOrderTest, QuietVsSignalingNaN) { \
136 testQuietVsSignalingNaN(&func); \
137 } \
138 TEST_F(LlvmLibcTotalOrderTest, NaNPayloads) { testNaNPayloads(&func); }
139
140#endif // LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERTEST_H
141

source code of libc/test/src/math/smoke/TotalOrderTest.h