[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / libc / test / src / math / exhaustive / fmod_generic_impl_test.cpp
blob1273cf0b588bd1b2432a10f9345d22c87d8a376c
1 //===-- Utility class to test FMod generic implementation -------*- 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 #include "src/__support/CPP/type_traits.h"
9 #include "src/__support/FPUtil/generic/FMod.h"
10 #include "test/UnitTest/FPMatcher.h"
11 #include "test/UnitTest/Test.h"
12 #include "utils/MPFRWrapper/MPFRUtils.h"
14 #include <array>
15 #include <limits>
17 namespace mpfr = __llvm_libc::testing::mpfr;
19 template <typename T, bool InverseMultiplication>
20 class LlvmLibcFModTest : public __llvm_libc::testing::Test {
22 using DivisionHelper = __llvm_libc::cpp::conditional_t<
23 InverseMultiplication,
24 __llvm_libc::fputil::generic::FModDivisionInvMultHelper<T>,
25 __llvm_libc::fputil::generic::FModDivisionSimpleHelper<T>>;
27 static constexpr std::array<T, 11> test_bases = {
28 T(0.0),
29 T(1.0),
30 T(3.0),
31 T(27.0),
32 T(11.0 / 8.0),
33 T(2.764443),
34 T(1.0) - std::numeric_limits<T>::epsilon(),
35 T(1.0) + std::numeric_limits<T>::epsilon(),
36 T(M_PI),
37 T(M_SQRT2),
38 T(M_E)};
40 public:
41 void testExtensive() {
42 using FMod = __llvm_libc::fputil::generic::FMod<
43 T, __llvm_libc::fputil::generic::FModFastMathWrapper<T>,
44 DivisionHelper>;
45 using nl = std::numeric_limits<T>;
46 int min2 = nl::min_exponent - nl::digits - 5;
47 int max2 = nl::max_exponent + 3;
48 for (T by : test_bases) {
49 for (int iy = min2; iy < max2; iy++) {
50 T y = by * std::ldexp(2, iy);
51 if (y == 0 || !std::isfinite(y))
52 continue;
53 for (T bx : test_bases) {
54 for (int ix = min2; ix < max2; ix++) {
55 T x = bx * std::ldexp(2, ix);
56 if (!std::isfinite(x))
57 continue;
58 T result = FMod::eval(x, y);
59 mpfr::BinaryInput<T> input{x, y};
60 EXPECT_MPFR_MATCH(mpfr::Operation::Fmod, input, result, 0.0);
68 using LlvmLibcFModFloatTest = LlvmLibcFModTest<float, false>;
69 TEST_F(LlvmLibcFModFloatTest, ExtensiveTest) { testExtensive(); }
71 using LlvmLibcFModFloatInvTest = LlvmLibcFModTest<float, true>;
72 TEST_F(LlvmLibcFModFloatInvTest, ExtensiveTest) { testExtensive(); }
74 using LlvmLibcFModDoubleTest = LlvmLibcFModTest<double, false>;
75 TEST_F(LlvmLibcFModDoubleTest, ExtensiveTest) { testExtensive(); }
77 using LlvmLibcFModDoubleInvTest = LlvmLibcFModTest<double, true>;
78 TEST_F(LlvmLibcFModDoubleInvTest, ExtensiveTest) { testExtensive(); }