// Copyright (C) 2020-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// .
// only: float|double|ldouble * * *
// expensive: * [1-9] * *
#include "bits/main.h"
#include
template
auto
verify_no_fp_exceptions(F&& fun)
{
std::feclearexcept(FE_ALL_EXCEPT);
auto r = fun();
COMPARE(std::fetestexcept(FE_ALL_EXCEPT), 0);
return r;
}
#define NOFPEXCEPT(...) verify_no_fp_exceptions([&]() { return __VA_ARGS__; })
template
void
test()
{
using T = typename V::value_type;
using intv = std::experimental::fixed_size_simd;
#if __GCC_IEC_559 >= 2
constexpr T inf = std::__infinity_v;
constexpr T denorm_min = std::__infinity_v;
constexpr T nan = std::__quiet_NaN_v;
#endif
constexpr T max = std::__finite_max_v;
constexpr T norm_min = std::__norm_min_v;
test_values(
{0., 1., -1.,
#if __GCC_IEC_559 >= 2
-0., inf, -inf, denorm_min, -denorm_min, nan,
norm_min * 0.9, -norm_min * 0.9,
#endif
max, -max, norm_min, -norm_min
},
[](const V input) {
COMPARE(NOFPEXCEPT(isfinite(input)),
!V([&](auto i) { return std::isfinite(input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(isinf(input)),
!V([&](auto i) { return std::isinf(input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(isnan(input)),
!V([&](auto i) { return std::isnan(input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(isnormal(input)),
!V([&](auto i) { return std::isnormal(input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(signbit(input)),
!V([&](auto i) { return std::signbit(input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(isunordered(input, V())),
!V([&](auto i) { return std::isunordered(input[i], 0) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(isunordered(V(), input)),
!V([&](auto i) { return std::isunordered(0, input[i]) ? 0 : 1; }))
<< input;
COMPARE(NOFPEXCEPT(fpclassify(input)),
intv([&](auto i) { return std::fpclassify(input[i]); }))
<< input;
});
#ifdef __SUPPORT_SNAN__
const V snan = std::__signaling_NaN_v;
COMPARE(isfinite(snan),
!V([&](auto i) { return std::isfinite(snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(isinf(snan), !V([&](auto i) { return std::isinf(snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(isnan(snan), !V([&](auto i) { return std::isnan(snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(isnormal(snan),
!V([&](auto i) { return std::isnormal(snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(signbit(snan),
!V([&](auto i) { return std::signbit(snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(isunordered(snan, V()),
!V([&](auto i) { return std::isunordered(snan[i], 0) ? 0 : 1; }))
<< snan;
COMPARE(isunordered(V(), snan),
!V([&](auto i) { return std::isunordered(0, snan[i]) ? 0 : 1; }))
<< snan;
COMPARE(fpclassify(snan),
intv([&](auto i) { return std::fpclassify(snan[i]); }))
<< snan;
#endif
}