xref: /llvm-project/libcxx/test/std/numerics/c.math/signbit.pass.cpp (revision 7f845cba2ccc2ab637b8e40fbafb9f83a2d67c70)
11a126472SRobin Caloudis //===----------------------------------------------------------------------===//
21a126472SRobin Caloudis //
31a126472SRobin Caloudis // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41a126472SRobin Caloudis // See https://llvm.org/LICENSE.txt for license information.
51a126472SRobin Caloudis // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61a126472SRobin Caloudis //
71a126472SRobin Caloudis //===----------------------------------------------------------------------===//
81a126472SRobin Caloudis 
91a126472SRobin Caloudis // bool signbit(floating-point-type x); // constexpr since C++23
101a126472SRobin Caloudis 
111a126472SRobin Caloudis // We don't control the implementation on windows
121a126472SRobin Caloudis // UNSUPPORTED: windows
131a126472SRobin Caloudis 
141a126472SRobin Caloudis // These compilers don't support constexpr `__builtin_signbit` yet.
15*7f845cbaSNikolas Klauser // UNSUPPORTED: clang-18, clang-19, apple-clang-15, apple-clang-16
161a126472SRobin Caloudis 
17b9a2658aSNikolas Klauser // XFAIL: FROZEN-CXX03-HEADERS-FIXME
18b9a2658aSNikolas Klauser 
191a126472SRobin Caloudis #include <cassert>
201a126472SRobin Caloudis #include <cmath>
211a126472SRobin Caloudis #include <limits>
221a126472SRobin Caloudis 
231a126472SRobin Caloudis #include "test_macros.h"
241a126472SRobin Caloudis #include "type_algorithms.h"
251a126472SRobin Caloudis 
261a126472SRobin Caloudis struct TestFloat {
271a126472SRobin Caloudis   template <class T>
281a126472SRobin Caloudis   static TEST_CONSTEXPR_CXX23 bool test() {
291a126472SRobin Caloudis     assert(!std::signbit(T(0)));
301a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::min()));
311a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::denorm_min()));
321a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::max()));
331a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::infinity()));
341a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::quiet_NaN()));
351a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::signaling_NaN()));
361a126472SRobin Caloudis     assert(std::signbit(-T(0)));
371a126472SRobin Caloudis     assert(std::signbit(-std::numeric_limits<T>::infinity()));
381a126472SRobin Caloudis     assert(std::signbit(std::numeric_limits<T>::lowest()));
391a126472SRobin Caloudis 
401a126472SRobin Caloudis     return true;
411a126472SRobin Caloudis   }
421a126472SRobin Caloudis 
431a126472SRobin Caloudis   template <class T>
441a126472SRobin Caloudis   TEST_CONSTEXPR_CXX23 void operator()() {
451a126472SRobin Caloudis     test<T>();
461a126472SRobin Caloudis #if TEST_STD_VER >= 23
471a126472SRobin Caloudis     static_assert(test<T>());
481a126472SRobin Caloudis #endif
491a126472SRobin Caloudis   }
501a126472SRobin Caloudis };
511a126472SRobin Caloudis 
521a126472SRobin Caloudis struct TestInt {
531a126472SRobin Caloudis   template <class T>
541a126472SRobin Caloudis   static TEST_CONSTEXPR_CXX23 bool test() {
551a126472SRobin Caloudis     assert(!std::signbit(std::numeric_limits<T>::max()));
561a126472SRobin Caloudis     assert(!std::signbit(T(0)));
571a126472SRobin Caloudis     if (std::is_unsigned<T>::value) {
581a126472SRobin Caloudis       assert(!std::signbit(std::numeric_limits<T>::lowest()));
591a126472SRobin Caloudis     } else {
601a126472SRobin Caloudis       assert(std::signbit(std::numeric_limits<T>::lowest()));
611a126472SRobin Caloudis     }
621a126472SRobin Caloudis 
631a126472SRobin Caloudis     return true;
641a126472SRobin Caloudis   }
651a126472SRobin Caloudis 
661a126472SRobin Caloudis   template <class T>
671a126472SRobin Caloudis   TEST_CONSTEXPR_CXX23 void operator()() {
681a126472SRobin Caloudis     test<T>();
691a126472SRobin Caloudis #if TEST_STD_VER >= 23
701a126472SRobin Caloudis     static_assert(test<T>());
711a126472SRobin Caloudis #endif
721a126472SRobin Caloudis   }
731a126472SRobin Caloudis };
741a126472SRobin Caloudis 
75c6b2aa18SRobin Caloudis template <typename T>
76c6b2aa18SRobin Caloudis struct ConvertibleTo {
77c6b2aa18SRobin Caloudis   operator T() const { return T(); }
78c6b2aa18SRobin Caloudis };
79c6b2aa18SRobin Caloudis 
801a126472SRobin Caloudis int main(int, char**) {
811a126472SRobin Caloudis   types::for_each(types::floating_point_types(), TestFloat());
821a126472SRobin Caloudis   types::for_each(types::integral_types(), TestInt());
831a126472SRobin Caloudis 
84c6b2aa18SRobin Caloudis   // Make sure we can call `std::signbit` with convertible types. This checks
85c6b2aa18SRobin Caloudis   // whether overloads for all cv-unqualified floating-point types are working
86c6b2aa18SRobin Caloudis   // as expected.
87c6b2aa18SRobin Caloudis   {
88c6b2aa18SRobin Caloudis     assert(!std::signbit(ConvertibleTo<float>()));
89c6b2aa18SRobin Caloudis     assert(!std::signbit(ConvertibleTo<double>()));
90c6b2aa18SRobin Caloudis     assert(!std::signbit(ConvertibleTo<long double>()));
91c6b2aa18SRobin Caloudis   }
921a126472SRobin Caloudis   return 0;
931a126472SRobin Caloudis }
94