96 lines · cpp
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9// bool signbit(floating-point-type x); // constexpr since C++2310 11// We don't control the implementation on windows12// UNSUPPORTED: windows13 14// These compilers don't support constexpr `__builtin_signbit` yet.15// UNSUPPORTED: apple-clang-1716 17// GCC warns about signbit comparing `bool_v < 0`, which we're testing18// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-bool-compare19 20#include <cassert>21#include <cmath>22#include <limits>23#include <type_traits>24 25#include "test_macros.h"26#include "type_algorithms.h"27 28struct TestFloat {29 template <class T>30 static TEST_CONSTEXPR_CXX23 bool test() {31 assert(!std::signbit(T(0)));32 assert(!std::signbit(std::numeric_limits<T>::min()));33 assert(!std::signbit(std::numeric_limits<T>::denorm_min()));34 assert(!std::signbit(std::numeric_limits<T>::max()));35 assert(!std::signbit(std::numeric_limits<T>::infinity()));36 assert(!std::signbit(std::numeric_limits<T>::quiet_NaN()));37 assert(!std::signbit(std::numeric_limits<T>::signaling_NaN()));38 assert(std::signbit(-T(0)));39 assert(std::signbit(-std::numeric_limits<T>::infinity()));40 assert(std::signbit(std::numeric_limits<T>::lowest()));41 42 return true;43 }44 45 template <class T>46 TEST_CONSTEXPR_CXX23 void operator()() {47 test<T>();48#if TEST_STD_VER >= 2349 static_assert(test<T>());50#endif51 }52};53 54struct TestInt {55 template <class T>56 static TEST_CONSTEXPR_CXX23 bool test() {57 assert(!std::signbit(std::numeric_limits<T>::max()));58 assert(!std::signbit(T(0)));59 if (std::is_unsigned<T>::value) {60 assert(!std::signbit(std::numeric_limits<T>::lowest()));61 } else {62 assert(std::signbit(std::numeric_limits<T>::lowest()));63 }64 65 return true;66 }67 68 template <class T>69 TEST_CONSTEXPR_CXX23 void operator()() {70 test<T>();71#if TEST_STD_VER >= 2372 static_assert(test<T>());73#endif74 }75};76 77template <typename T>78struct ConvertibleTo {79 operator T() const { return T(); }80};81 82int main(int, char**) {83 types::for_each(types::floating_point_types(), TestFloat());84 types::for_each(types::integral_types(), TestInt());85 86 // Make sure we can call `std::signbit` with convertible types. This checks87 // whether overloads for all cv-unqualified floating-point types are working88 // as expected.89 {90 assert(!std::signbit(ConvertibleTo<float>()));91 assert(!std::signbit(ConvertibleTo<double>()));92 assert(!std::signbit(ConvertibleTo<long double>()));93 }94 return 0;95}96