1000 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// <math.h>10 11// GCC warns about signbit comparing `bool_v < 0`, which we're testing12// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-bool-compare13 14#include <math.h>15#include <type_traits>16#include <cassert>17 18#include "test_macros.h"19#include "hexfloat.h"20#include "truncate_fp.h"21#include "type_algorithms.h"22 23// convertible to int/float/double/etc24template <class T, int N=0>25struct Value {26 operator T () { return T(N); }27};28 29// See PR2108330// Ambiguous is a user-defined type that defines its own overloads of cmath31// functions. When the std overloads are candidates too (by using or adl),32// they should not interfere.33struct Ambiguous : std::true_type { // ADL34 operator float () { return 0.f; }35 operator double () { return 0.; }36};37Ambiguous abs(Ambiguous){ return Ambiguous(); }38Ambiguous acos(Ambiguous){ return Ambiguous(); }39Ambiguous asin(Ambiguous){ return Ambiguous(); }40Ambiguous atan(Ambiguous){ return Ambiguous(); }41Ambiguous atan2(Ambiguous, Ambiguous){ return Ambiguous(); }42Ambiguous ceil(Ambiguous){ return Ambiguous(); }43Ambiguous cos(Ambiguous){ return Ambiguous(); }44Ambiguous cosh(Ambiguous){ return Ambiguous(); }45Ambiguous exp(Ambiguous){ return Ambiguous(); }46Ambiguous fabs(Ambiguous){ return Ambiguous(); }47Ambiguous floor(Ambiguous){ return Ambiguous(); }48Ambiguous fmod(Ambiguous, Ambiguous){ return Ambiguous(); }49Ambiguous frexp(Ambiguous, int*){ return Ambiguous(); }50Ambiguous ldexp(Ambiguous, int){ return Ambiguous(); }51Ambiguous log(Ambiguous){ return Ambiguous(); }52Ambiguous log10(Ambiguous){ return Ambiguous(); }53Ambiguous modf(Ambiguous, Ambiguous*){ return Ambiguous(); }54Ambiguous pow(Ambiguous, Ambiguous){ return Ambiguous(); }55Ambiguous sin(Ambiguous){ return Ambiguous(); }56Ambiguous sinh(Ambiguous){ return Ambiguous(); }57Ambiguous sqrt(Ambiguous){ return Ambiguous(); }58Ambiguous tan(Ambiguous){ return Ambiguous(); }59Ambiguous tanh(Ambiguous){ return Ambiguous(); }60Ambiguous signbit(Ambiguous){ return Ambiguous(); }61Ambiguous fpclassify(Ambiguous){ return Ambiguous(); }62Ambiguous isfinite(Ambiguous){ return Ambiguous(); }63Ambiguous isnormal(Ambiguous){ return Ambiguous(); }64Ambiguous isgreater(Ambiguous, Ambiguous){ return Ambiguous(); }65Ambiguous isgreaterequal(Ambiguous, Ambiguous){ return Ambiguous(); }66Ambiguous isless(Ambiguous, Ambiguous){ return Ambiguous(); }67Ambiguous islessequal(Ambiguous, Ambiguous){ return Ambiguous(); }68Ambiguous islessgreater(Ambiguous, Ambiguous){ return Ambiguous(); }69Ambiguous isunordered(Ambiguous, Ambiguous){ return Ambiguous(); }70Ambiguous acosh(Ambiguous){ return Ambiguous(); }71Ambiguous asinh(Ambiguous){ return Ambiguous(); }72Ambiguous atanh(Ambiguous){ return Ambiguous(); }73Ambiguous cbrt(Ambiguous){ return Ambiguous(); }74Ambiguous copysign(Ambiguous, Ambiguous){ return Ambiguous(); }75Ambiguous erf(Ambiguous){ return Ambiguous(); }76Ambiguous erfc(Ambiguous){ return Ambiguous(); }77Ambiguous exp2(Ambiguous){ return Ambiguous(); }78Ambiguous expm1(Ambiguous){ return Ambiguous(); }79Ambiguous fdim(Ambiguous, Ambiguous){ return Ambiguous(); }80Ambiguous fma(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); }81Ambiguous fmax(Ambiguous, Ambiguous){ return Ambiguous(); }82Ambiguous fmin(Ambiguous, Ambiguous){ return Ambiguous(); }83Ambiguous hypot(Ambiguous, Ambiguous){ return Ambiguous(); }84Ambiguous ilogb(Ambiguous){ return Ambiguous(); }85Ambiguous lgamma(Ambiguous){ return Ambiguous(); }86Ambiguous llrint(Ambiguous){ return Ambiguous(); }87Ambiguous llround(Ambiguous){ return Ambiguous(); }88Ambiguous log1p(Ambiguous){ return Ambiguous(); }89Ambiguous log2(Ambiguous){ return Ambiguous(); }90Ambiguous logb(Ambiguous){ return Ambiguous(); }91Ambiguous lrint(Ambiguous){ return Ambiguous(); }92Ambiguous lround(Ambiguous){ return Ambiguous(); }93Ambiguous nearbyint(Ambiguous){ return Ambiguous(); }94Ambiguous nextafter(Ambiguous, Ambiguous){ return Ambiguous(); }95Ambiguous nexttoward(Ambiguous, Ambiguous){ return Ambiguous(); }96Ambiguous remainder(Ambiguous, Ambiguous){ return Ambiguous(); }97Ambiguous remquo(Ambiguous, Ambiguous, int*){ return Ambiguous(); }98Ambiguous rint(Ambiguous){ return Ambiguous(); }99Ambiguous round(Ambiguous){ return Ambiguous(); }100Ambiguous scalbln(Ambiguous, Ambiguous){ return Ambiguous(); }101Ambiguous scalbn(Ambiguous, Ambiguous){ return Ambiguous(); }102Ambiguous tgamma(Ambiguous){ return Ambiguous(); }103Ambiguous trunc(Ambiguous){ return Ambiguous(); }104 105template <class T, class = decltype(::abs(T()))>106std::true_type has_abs_imp(int);107template <class T>108std::false_type has_abs_imp(...);109 110template <class T>111struct has_abs : decltype(has_abs_imp<T>(0)) {};112 113void test_abs() {114 TEST_DIAGNOSTIC_PUSH115 TEST_CLANG_DIAGNOSTIC_IGNORED("-Wabsolute-value")116 117 ASSERT_SAME_TYPE(decltype(abs((float)0)), float);118 ASSERT_SAME_TYPE(decltype(abs((double)0)), double);119 ASSERT_SAME_TYPE(decltype(abs((long double)0)), long double);120 ASSERT_SAME_TYPE(decltype(abs((int)0)), int);121 ASSERT_SAME_TYPE(decltype(abs((long)0)), long);122 ASSERT_SAME_TYPE(decltype(abs((long long)0)), long long);123 ASSERT_SAME_TYPE(decltype(abs((unsigned char)0)), int);124 ASSERT_SAME_TYPE(decltype(abs((unsigned short)0)), int);125 ASSERT_SAME_TYPE(decltype(abs(Ambiguous())), Ambiguous);126 127 static_assert(!has_abs<unsigned>::value, "");128 static_assert(!has_abs<unsigned long>::value, "");129 static_assert(!has_abs<unsigned long long>::value, "");130 131 TEST_DIAGNOSTIC_POP132 133 assert(abs(-1.) == 1);134}135 136void test_acos() {137 ASSERT_SAME_TYPE(decltype(acosf(0)), float);138 ASSERT_SAME_TYPE(decltype(acosl(0)), long double);139 ASSERT_SAME_TYPE(decltype(acos(Ambiguous())), Ambiguous);140 assert(acos(1) == 0);141}142 143void test_asin() {144 ASSERT_SAME_TYPE(decltype(asinf(0)), float);145 ASSERT_SAME_TYPE(decltype(asinl(0)), long double);146 ASSERT_SAME_TYPE(decltype(asin(Ambiguous())), Ambiguous);147 assert(asin(0) == 0);148}149 150void test_atan() {151 ASSERT_SAME_TYPE(decltype(atanf(0)), float);152 ASSERT_SAME_TYPE(decltype(atanl(0)), long double);153 ASSERT_SAME_TYPE(decltype(atan(Ambiguous())), Ambiguous);154 assert(atan(0) == 0);155}156 157void test_atan2() {158 ASSERT_SAME_TYPE(decltype(atan2f(0,0)), float);159 ASSERT_SAME_TYPE(decltype(atan2l(0,0)), long double);160 ASSERT_SAME_TYPE(decltype(atan2(Ambiguous(), Ambiguous())), Ambiguous);161 assert(atan2(0,1) == 0);162}163 164void test_ceil() {165 ASSERT_SAME_TYPE(decltype(ceilf(0)), float);166 ASSERT_SAME_TYPE(decltype(ceill(0)), long double);167 ASSERT_SAME_TYPE(decltype(ceil(Ambiguous())), Ambiguous);168 assert(ceil(0) == 0);169}170 171void test_cos() {172 ASSERT_SAME_TYPE(decltype(cosf(0)), float);173 ASSERT_SAME_TYPE(decltype(cosl(0)), long double);174 ASSERT_SAME_TYPE(decltype(cos(Ambiguous())), Ambiguous);175 assert(cos(0) == 1);176}177 178void test_cosh() {179 ASSERT_SAME_TYPE(decltype(coshf(0)), float);180 ASSERT_SAME_TYPE(decltype(coshl(0)), long double);181 ASSERT_SAME_TYPE(decltype(cosh(Ambiguous())), Ambiguous);182 assert(cosh(0) == 1);183}184 185void test_exp() {186 ASSERT_SAME_TYPE(decltype(expf(0)), float);187 ASSERT_SAME_TYPE(decltype(expl(0)), long double);188 ASSERT_SAME_TYPE(decltype(exp(Ambiguous())), Ambiguous);189 assert(exp(0) == 1);190}191 192void test_fabs() {193 ASSERT_SAME_TYPE(decltype(fabsf(0.0f)), float);194 ASSERT_SAME_TYPE(decltype(fabsl(0.0L)), long double);195 ASSERT_SAME_TYPE(decltype(fabs(Ambiguous())), Ambiguous);196 assert(fabs(-1) == 1);197}198 199void test_floor() {200 ASSERT_SAME_TYPE(decltype(floorf(0)), float);201 ASSERT_SAME_TYPE(decltype(floorl(0)), long double);202 ASSERT_SAME_TYPE(decltype(floor(Ambiguous())), Ambiguous);203 assert(floor(1) == 1);204}205 206void test_fmod() {207 ASSERT_SAME_TYPE(decltype(fmodf(0,0)), float);208 ASSERT_SAME_TYPE(decltype(fmodl(0,0)), long double);209 ASSERT_SAME_TYPE(decltype(fmod(Ambiguous(), Ambiguous())), Ambiguous);210 assert(fmod(1.5,1) == .5);211}212 213void test_frexp() {214 int ip;215 ASSERT_SAME_TYPE(decltype(frexpf(0, &ip)), float);216 ASSERT_SAME_TYPE(decltype(frexpl(0, &ip)), long double);217 ASSERT_SAME_TYPE(decltype(frexp(Ambiguous(), &ip)), Ambiguous);218 assert(frexp(0, &ip) == 0);219}220 221void test_ldexp() {222 int ip = 1;223 ASSERT_SAME_TYPE(decltype(ldexpf(0, ip)), float);224 ASSERT_SAME_TYPE(decltype(ldexpl(0, ip)), long double);225 ASSERT_SAME_TYPE(decltype(ldexp(Ambiguous(), ip)), Ambiguous);226 assert(ldexp(1, ip) == 2);227}228 229void test_log() {230 ASSERT_SAME_TYPE(decltype(logf(0)), float);231 ASSERT_SAME_TYPE(decltype(logl(0)), long double);232 ASSERT_SAME_TYPE(decltype(log(Ambiguous())), Ambiguous);233 assert(log(1) == 0);234}235 236void test_log10() {237 ASSERT_SAME_TYPE(decltype(log10f(0)), float);238 ASSERT_SAME_TYPE(decltype(log10l(0)), long double);239 ASSERT_SAME_TYPE(decltype(log10(Ambiguous())), Ambiguous);240 assert(log10(1) == 0);241}242 243void test_modf() {244 ASSERT_SAME_TYPE(decltype(modf((float)0, (float*)0)), float);245 ASSERT_SAME_TYPE(decltype(modf((double)0, (double*)0)), double);246 ASSERT_SAME_TYPE(decltype(modf((long double)0, (long double*)0)), long double);247 ASSERT_SAME_TYPE(decltype(modff(0, (float*)0)), float);248 ASSERT_SAME_TYPE(decltype(modfl(0, (long double*)0)), long double);249 ASSERT_SAME_TYPE(decltype(modf(Ambiguous(), (Ambiguous*)0)), Ambiguous);250 double i;251 assert(modf(1., &i) == 0);252}253 254void test_pow() {255 ASSERT_SAME_TYPE(decltype(powf(0,0)), float);256 ASSERT_SAME_TYPE(decltype(powl(0,0)), long double);257 ASSERT_SAME_TYPE(decltype(pow((int)0, (int)0)), double);258 // ASSERT_SAME_TYPE(decltype(pow(Value<int>(), (int)0)), double);259 // ASSERT_SAME_TYPE(decltype(pow(Value<long double>(), (float)0)), long double);260 // ASSERT_SAME_TYPE(decltype(pow((float) 0, Value<float>())), float);261 ASSERT_SAME_TYPE(decltype(pow(Ambiguous(), Ambiguous())), Ambiguous);262 assert(pow(1,1) == 1);263 // assert(pow(Value<int,1>(), Value<float,1>()) == 1);264 // assert(pow(1.0f, Value<double,1>()) == 1);265 // assert(pow(1.0, Value<int,1>()) == 1);266 // assert(pow(Value<long double,1>(), 1LL) == 1);267}268 269void test_sin() {270 ASSERT_SAME_TYPE(decltype(sinf(0)), float);271 ASSERT_SAME_TYPE(decltype(sinl(0)), long double);272 ASSERT_SAME_TYPE(decltype(sin(Ambiguous())), Ambiguous);273 assert(sin(0) == 0);274}275 276void test_sinh() {277 ASSERT_SAME_TYPE(decltype(sinhf(0)), float);278 ASSERT_SAME_TYPE(decltype(sinhl(0)), long double);279 ASSERT_SAME_TYPE(decltype(sinh(Ambiguous())), Ambiguous);280 assert(sinh(0) == 0);281}282 283void test_sqrt() {284 ASSERT_SAME_TYPE(decltype(sqrtf(0)), float);285 ASSERT_SAME_TYPE(decltype(sqrtl(0)), long double);286 ASSERT_SAME_TYPE(decltype(sqrt(Ambiguous())), Ambiguous);287 assert(sqrt(4) == 2);288}289 290void test_tan() {291 ASSERT_SAME_TYPE(decltype(tanf(0)), float);292 ASSERT_SAME_TYPE(decltype(tanl(0)), long double);293 ASSERT_SAME_TYPE(decltype(tan(Ambiguous())), Ambiguous);294 assert(tan(0) == 0);295}296 297void test_tanh() {298 ASSERT_SAME_TYPE(decltype(tanhf(0)), float);299 ASSERT_SAME_TYPE(decltype(tanhl(0)), long double);300 ASSERT_SAME_TYPE(decltype(tanh(Ambiguous())), Ambiguous);301 assert(tanh(0) == 0);302}303 304void test_signbit() {305#ifdef signbit306#error signbit defined307#endif308 ASSERT_SAME_TYPE(decltype(signbit(Ambiguous())), Ambiguous);309 assert(signbit(-1.0) == true);310}311 312void test_fpclassify() {313#ifdef fpclassify314#error fpclassify defined315#endif316 ASSERT_SAME_TYPE(decltype(fpclassify(Ambiguous())), Ambiguous);317 assert(fpclassify(-1.0) == FP_NORMAL);318}319 320void test_isfinite() {321#ifdef isfinite322#error isfinite defined323#endif324 ASSERT_SAME_TYPE(decltype(isfinite(Ambiguous())), Ambiguous);325 assert(isfinite(-1.0) == true);326}327 328void test_isnormal() {329#ifdef isnormal330#error isnormal defined331#endif332 ASSERT_SAME_TYPE(decltype(isnormal(Ambiguous())), Ambiguous);333 assert(isnormal(-1.0) == true);334}335 336void test_isgreater() {337#ifdef isgreater338#error isgreater defined339#endif340 ASSERT_SAME_TYPE(decltype(isgreater(Ambiguous(), Ambiguous())), Ambiguous);341 assert(isgreater(-1.0, 0.F) == false);342}343 344void test_isgreaterequal() {345#ifdef isgreaterequal346#error isgreaterequal defined347#endif348 ASSERT_SAME_TYPE(decltype(isgreaterequal(Ambiguous(), Ambiguous())), Ambiguous);349 assert(isgreaterequal(-1.0, 0.F) == false);350}351 352void test_isinf() {353#ifdef isinf354#error isinf defined355#endif356 ASSERT_SAME_TYPE(decltype(isinf((float)0)), bool);357 358 typedef decltype(isinf((double)0)) DoubleRetType;359#ifndef __linux__360 ASSERT_SAME_TYPE(DoubleRetType, bool);361#else362 // GLIBC < 2.26 defines 'isinf(double)' with a return type of 'int' in363 // all C++ dialects. The test should tolerate this.364 // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439365 static_assert((std::is_same<DoubleRetType, bool>::value366 || std::is_same<DoubleRetType, int>::value), "");367#endif368 369 ASSERT_SAME_TYPE(decltype(isinf(0)), bool);370 ASSERT_SAME_TYPE(decltype(isinf((long double)0)), bool);371 assert(isinf(-1.0) == false);372}373 374void test_isless() {375#ifdef isless376#error isless defined377#endif378 ASSERT_SAME_TYPE(decltype(isless(Ambiguous(), Ambiguous())), Ambiguous);379 assert(isless(-1.0, 0.F) == true);380}381 382void test_islessequal() {383#ifdef islessequal384#error islessequal defined385#endif386 ASSERT_SAME_TYPE(decltype(islessequal(Ambiguous(), Ambiguous())), Ambiguous);387 assert(islessequal(-1.0, 0.F) == true);388}389 390void test_islessgreater() {391#ifdef islessgreater392#error islessgreater defined393#endif394 ASSERT_SAME_TYPE(decltype(islessgreater(Ambiguous(), Ambiguous())), Ambiguous);395 assert(islessgreater(-1.0, 0.F) == true);396}397 398void test_isnan() {399#ifdef isnan400#error isnan defined401#endif402 ASSERT_SAME_TYPE(decltype(isnan((float)0)), bool);403 404 typedef decltype(isnan((double)0)) DoubleRetType;405#ifndef __linux__406 ASSERT_SAME_TYPE(DoubleRetType, bool);407#else408 // GLIBC < 2.26 defines 'isnan(double)' with a return type of 'int' in409 // all C++ dialects. The test should tolerate this.410 // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439411 static_assert((std::is_same<DoubleRetType, bool>::value412 || std::is_same<DoubleRetType, int>::value), "");413#endif414 415 ASSERT_SAME_TYPE(decltype(isnan(0)), bool);416 ASSERT_SAME_TYPE(decltype(isnan((long double)0)), bool);417 assert(isnan(-1.0) == false);418}419 420void test_isunordered() {421#ifdef isunordered422#error isunordered defined423#endif424 ASSERT_SAME_TYPE(decltype(isunordered(Ambiguous(), Ambiguous())), Ambiguous);425 assert(isunordered(-1.0, 0.F) == false);426}427 428void test_acosh() {429 ASSERT_SAME_TYPE(decltype(acoshf(0)), float);430 ASSERT_SAME_TYPE(decltype(acoshl(0)), long double);431 ASSERT_SAME_TYPE(decltype(acosh(Ambiguous())), Ambiguous);432 assert(acosh(1) == 0);433}434 435void test_asinh() {436 ASSERT_SAME_TYPE(decltype(asinhf(0)), float);437 ASSERT_SAME_TYPE(decltype(asinhl(0)), long double);438 ASSERT_SAME_TYPE(decltype(asinh(Ambiguous())), Ambiguous);439 assert(asinh(0) == 0);440}441 442void test_atanh() {443 ASSERT_SAME_TYPE(decltype(atanhf(0)), float);444 ASSERT_SAME_TYPE(decltype(atanhl(0)), long double);445 ASSERT_SAME_TYPE(decltype(atanh(Ambiguous())), Ambiguous);446 assert(atanh(0) == 0);447}448 449void test_cbrt() {450 ASSERT_SAME_TYPE(decltype(cbrtf(0)), float);451 ASSERT_SAME_TYPE(decltype(cbrtl(0)), long double);452 ASSERT_SAME_TYPE(decltype(cbrt(Ambiguous())), Ambiguous);453 assert(truncate_fp(cbrt(1)) == 1);454}455 456void test_copysign() {457 ASSERT_SAME_TYPE(decltype(copysignf(0,0)), float);458 ASSERT_SAME_TYPE(decltype(copysignl(0,0)), long double);459 ASSERT_SAME_TYPE(decltype(copysign((int)0, (int)0)), double);460 ASSERT_SAME_TYPE(decltype(copysign(Ambiguous(), Ambiguous())), Ambiguous);461 assert(copysign(1,1) == 1);462}463 464void test_erf() {465 ASSERT_SAME_TYPE(decltype(erff(0)), float);466 ASSERT_SAME_TYPE(decltype(erfl(0)), long double);467 ASSERT_SAME_TYPE(decltype(erf(Ambiguous())), Ambiguous);468 assert(erf(0) == 0);469}470 471void test_erfc() {472 ASSERT_SAME_TYPE(decltype(erfcf(0)), float);473 ASSERT_SAME_TYPE(decltype(erfcl(0)), long double);474 ASSERT_SAME_TYPE(decltype(erfc(Ambiguous())), Ambiguous);475 assert(erfc(0) == 1);476}477 478void test_exp2() {479 ASSERT_SAME_TYPE(decltype(exp2f(0)), float);480 ASSERT_SAME_TYPE(decltype(exp2l(0)), long double);481 ASSERT_SAME_TYPE(decltype(exp2(Ambiguous())), Ambiguous);482 assert(exp2(1) == 2);483}484 485void test_expm1() {486 ASSERT_SAME_TYPE(decltype(expm1f(0)), float);487 ASSERT_SAME_TYPE(decltype(expm1l(0)), long double);488 ASSERT_SAME_TYPE(decltype(expm1(Ambiguous())), Ambiguous);489 assert(expm1(0) == 0);490}491 492void test_fdim() {493 ASSERT_SAME_TYPE(decltype(fdimf(0,0)), float);494 ASSERT_SAME_TYPE(decltype(fdiml(0,0)), long double);495 ASSERT_SAME_TYPE(decltype(fdim((int)0, (int)0)), double);496 ASSERT_SAME_TYPE(decltype(fdim(Ambiguous(), Ambiguous())), Ambiguous);497 assert(fdim(1,0) == 1);498}499 500void test_fma() {501 ASSERT_SAME_TYPE(decltype(fma((bool)0, (float)0, (float)0)), double);502 ASSERT_SAME_TYPE(decltype(fma((float)0, (float)0, (double)0)), double);503 ASSERT_SAME_TYPE(decltype(fma((float)0, (float)0, (long double)0)), long double);504 ASSERT_SAME_TYPE(decltype(fma((float)0, (float)0, (float)0)), float);505 506 ASSERT_SAME_TYPE(decltype(fma((bool)0, (double)0, (double)0)), double);507 ASSERT_SAME_TYPE(decltype(fma((double)0, (double)0, (float)0)), double);508 ASSERT_SAME_TYPE(decltype(fma((double)0, (double)0, (long double)0)), long double);509 ASSERT_SAME_TYPE(decltype(fma((double)0, (double)0, (double)0)), double);510 511 ASSERT_SAME_TYPE(decltype(fma((long double)0, (long double)0, (float)0)), long double);512 ASSERT_SAME_TYPE(decltype(fma((double)0, (long double)0, (long double)0)), long double);513 ASSERT_SAME_TYPE(decltype(fma((long double)0, (long double)0, (long double)0)), long double);514 515 ASSERT_SAME_TYPE(decltype(fmaf(0,0,0)), float);516 ASSERT_SAME_TYPE(decltype(fmal(0,0,0)), long double);517 ASSERT_SAME_TYPE(decltype(fma(Ambiguous(), Ambiguous(), Ambiguous())), Ambiguous);518 assert(fma(1,1,1) == 2);519}520 521void test_fmax() {522 ASSERT_SAME_TYPE(decltype(fmaxf(0,0)), float);523 ASSERT_SAME_TYPE(decltype(fmaxl(0,0)), long double);524 ASSERT_SAME_TYPE(decltype(fmax((int)0, (int)0)), double);525 ASSERT_SAME_TYPE(decltype(fmax(Ambiguous(), Ambiguous())), Ambiguous);526 assert(fmax(1,0) == 1);527}528 529void test_fmin() {530 ASSERT_SAME_TYPE(decltype(fminf(0,0)), float);531 ASSERT_SAME_TYPE(decltype(fminl(0,0)), long double);532 ASSERT_SAME_TYPE(decltype(fmin((int)0, (int)0)), double);533 ASSERT_SAME_TYPE(decltype(fmin(Ambiguous(), Ambiguous())), Ambiguous);534 assert(fmin(1,0) == 0);535}536 537void test_hypot() {538 ASSERT_SAME_TYPE(decltype(hypotf(0,0)), float);539 ASSERT_SAME_TYPE(decltype(hypotl(0,0)), long double);540 ASSERT_SAME_TYPE(decltype(hypot((int)0, (int)0)), double);541 ASSERT_SAME_TYPE(decltype(hypot(Ambiguous(), Ambiguous())), Ambiguous);542 assert(hypot(3,4) == 5);543}544 545void test_ilogb() {546 ASSERT_SAME_TYPE(decltype(ilogbf(0)), int);547 ASSERT_SAME_TYPE(decltype(ilogbl(0)), int);548 ASSERT_SAME_TYPE(decltype(ilogb(Ambiguous())), Ambiguous);549 assert(ilogb(1) == 0);550}551 552void test_lgamma() {553 ASSERT_SAME_TYPE(decltype(lgammaf(0)), float);554 ASSERT_SAME_TYPE(decltype(lgammal(0)), long double);555 ASSERT_SAME_TYPE(decltype(lgamma(Ambiguous())), Ambiguous);556 assert(lgamma(1) == 0);557}558 559void test_llrint() {560 ASSERT_SAME_TYPE(decltype(llrintf(0)), long long);561 ASSERT_SAME_TYPE(decltype(llrintl(0)), long long);562 ASSERT_SAME_TYPE(decltype(llrint(Ambiguous())), Ambiguous);563 assert(llrint(1) == 1LL);564}565 566void test_llround() {567 ASSERT_SAME_TYPE(decltype(llroundf(0)), long long);568 ASSERT_SAME_TYPE(decltype(llroundl(0)), long long);569 ASSERT_SAME_TYPE(decltype(llround(Ambiguous())), Ambiguous);570 assert(llround(1) == 1LL);571}572 573void test_log1p() {574 ASSERT_SAME_TYPE(decltype(log1pf(0)), float);575 ASSERT_SAME_TYPE(decltype(log1pl(0)), long double);576 ASSERT_SAME_TYPE(decltype(log1p(Ambiguous())), Ambiguous);577 assert(log1p(0) == 0);578}579 580void test_log2() {581 ASSERT_SAME_TYPE(decltype(log2f(0)), float);582 ASSERT_SAME_TYPE(decltype(log2l(0)), long double);583 ASSERT_SAME_TYPE(decltype(log2(Ambiguous())), Ambiguous);584 assert(log2(1) == 0);585}586 587void test_logb() {588 ASSERT_SAME_TYPE(decltype(logbf(0)), float);589 ASSERT_SAME_TYPE(decltype(logbl(0)), long double);590 ASSERT_SAME_TYPE(decltype(logb(Ambiguous())), Ambiguous);591 assert(logb(1) == 0);592}593 594void test_lrint() {595 ASSERT_SAME_TYPE(decltype(lrintf(0)), long);596 ASSERT_SAME_TYPE(decltype(lrintl(0)), long);597 ASSERT_SAME_TYPE(decltype(lrint(Ambiguous())), Ambiguous);598 assert(lrint(1) == 1L);599}600 601void test_lround() {602 ASSERT_SAME_TYPE(decltype(lroundf(0)), long);603 ASSERT_SAME_TYPE(decltype(lroundl(0)), long);604 ASSERT_SAME_TYPE(decltype(lround(Ambiguous())), Ambiguous);605 assert(lround(1) == 1L);606}607 608void test_nan() {609 ASSERT_SAME_TYPE(decltype(nan("")), double);610 ASSERT_SAME_TYPE(decltype(nanf("")), float);611 ASSERT_SAME_TYPE(decltype(nanl("")), long double);612}613 614void test_nearbyint() {615 ASSERT_SAME_TYPE(decltype(nearbyintf(0)), float);616 ASSERT_SAME_TYPE(decltype(nearbyintl(0)), long double);617 ASSERT_SAME_TYPE(decltype(nearbyint(Ambiguous())), Ambiguous);618 assert(nearbyint(1) == 1);619}620 621void test_nextafter() {622 ASSERT_SAME_TYPE(decltype(nextafterf(0,0)), float);623 ASSERT_SAME_TYPE(decltype(nextafterl(0,0)), long double);624 ASSERT_SAME_TYPE(decltype(nextafter((int)0, (int)0)), double);625 ASSERT_SAME_TYPE(decltype(nextafter(Ambiguous(), Ambiguous())), Ambiguous);626 assert(nextafter(0,1) == hexfloat<double>(0x1, 0, -1074));627}628 629void test_nexttoward() {630 ASSERT_SAME_TYPE(decltype(nexttoward((float)0, (long double)0)), float);631 ASSERT_SAME_TYPE(decltype(nexttoward((bool)0, (long double)0)), double);632 ASSERT_SAME_TYPE(decltype(nexttoward((unsigned short)0, (long double)0)), double);633 ASSERT_SAME_TYPE(decltype(nexttoward((int)0, (long double)0)), double);634 ASSERT_SAME_TYPE(decltype(nexttoward((unsigned int)0, (long double)0)), double);635 ASSERT_SAME_TYPE(decltype(nexttoward((long)0, (long double)0)), double);636 ASSERT_SAME_TYPE(decltype(nexttoward((unsigned long)0, (long double)0)), double);637 ASSERT_SAME_TYPE(decltype(nexttoward((long long)0, (long double)0)), double);638 ASSERT_SAME_TYPE(decltype(nexttoward((unsigned long long)0, (long double)0)), double);639 ASSERT_SAME_TYPE(decltype(nexttoward((double)0, (long double)0)), double);640 ASSERT_SAME_TYPE(decltype(nexttoward((long double)0, (long double)0)), long double);641 ASSERT_SAME_TYPE(decltype(nexttowardf(0, (long double)0)), float);642 ASSERT_SAME_TYPE(decltype(nexttowardl(0, (long double)0)), long double);643 ASSERT_SAME_TYPE(decltype(nexttoward(Ambiguous(), Ambiguous())), Ambiguous);644 assert(nexttoward(0, 1) == hexfloat<double>(0x1, 0, -1074));645}646 647void test_remainder() {648 ASSERT_SAME_TYPE(decltype(remainderf(0,0)), float);649 ASSERT_SAME_TYPE(decltype(remainderl(0,0)), long double);650 ASSERT_SAME_TYPE(decltype(remainder((int)0, (int)0)), double);651 ASSERT_SAME_TYPE(decltype(remainder(Ambiguous(), Ambiguous())), Ambiguous);652 assert(remainder(0.5,1) == 0.5);653}654 655void test_remquo() {656 int ip;657 ASSERT_SAME_TYPE(decltype(remquof(0,0, &ip)), float);658 ASSERT_SAME_TYPE(decltype(remquol(0,0, &ip)), long double);659 ASSERT_SAME_TYPE(decltype(remquo((int)0, (int)0, &ip)), double);660 ASSERT_SAME_TYPE(decltype(remquo(Ambiguous(), Ambiguous(), &ip)), Ambiguous);661 assert(remquo(0.5,1, &ip) == 0.5);662}663 664void test_rint() {665 ASSERT_SAME_TYPE(decltype(rintf(0)), float);666 ASSERT_SAME_TYPE(decltype(rintl(0)), long double);667 ASSERT_SAME_TYPE(decltype(rint(Ambiguous())), Ambiguous);668 assert(rint(1) == 1);669}670 671void test_round() {672 ASSERT_SAME_TYPE(decltype(roundf(0)), float);673 ASSERT_SAME_TYPE(decltype(roundl(0)), long double);674 ASSERT_SAME_TYPE(decltype(round(Ambiguous())), Ambiguous);675 assert(round(1) == 1);676}677 678void test_scalbln() {679 ASSERT_SAME_TYPE(decltype(scalbln((float)0, (long)0)), float);680 ASSERT_SAME_TYPE(decltype(scalbln((bool)0, (long)0)), double);681 ASSERT_SAME_TYPE(decltype(scalbln((unsigned short)0, (long)0)), double);682 ASSERT_SAME_TYPE(decltype(scalbln((int)0, (long)0)), double);683 ASSERT_SAME_TYPE(decltype(scalbln((unsigned int)0, (long)0)), double);684 ASSERT_SAME_TYPE(decltype(scalbln((long)0, (long)0)), double);685 ASSERT_SAME_TYPE(decltype(scalbln((unsigned long)0, (long)0)), double);686 ASSERT_SAME_TYPE(decltype(scalbln((long long)0, (long)0)), double);687 ASSERT_SAME_TYPE(decltype(scalbln((unsigned long long)0, (long)0)), double);688 ASSERT_SAME_TYPE(decltype(scalbln((double)0, (long)0)), double);689 ASSERT_SAME_TYPE(decltype(scalbln((long double)0, (long)0)), long double);690 ASSERT_SAME_TYPE(decltype(scalblnf(0, (long)0)), float);691 ASSERT_SAME_TYPE(decltype(scalblnl(0, (long)0)), long double);692 ASSERT_SAME_TYPE(decltype(scalbln(Ambiguous(), Ambiguous())), Ambiguous);693 assert(scalbln(1, 1) == 2);694}695 696void test_scalbn() {697 ASSERT_SAME_TYPE(decltype(scalbn((float)0, (int)0)), float);698 ASSERT_SAME_TYPE(decltype(scalbn((bool)0, (int)0)), double);699 ASSERT_SAME_TYPE(decltype(scalbn((unsigned short)0, (int)0)), double);700 ASSERT_SAME_TYPE(decltype(scalbn((int)0, (int)0)), double);701 ASSERT_SAME_TYPE(decltype(scalbn((unsigned int)0, (int)0)), double);702 ASSERT_SAME_TYPE(decltype(scalbn((long)0, (int)0)), double);703 ASSERT_SAME_TYPE(decltype(scalbn((unsigned long)0, (int)0)), double);704 ASSERT_SAME_TYPE(decltype(scalbn((long long)0, (int)0)), double);705 ASSERT_SAME_TYPE(decltype(scalbn((unsigned long long)0, (int)0)), double);706 ASSERT_SAME_TYPE(decltype(scalbn((double)0, (int)0)), double);707 ASSERT_SAME_TYPE(decltype(scalbn((long double)0, (int)0)), long double);708 ASSERT_SAME_TYPE(decltype(scalbnf(0, (int)0)), float);709 ASSERT_SAME_TYPE(decltype(scalbnl(0, (int)0)), long double);710 ASSERT_SAME_TYPE(decltype(scalbn(Ambiguous(), Ambiguous())), Ambiguous);711 assert(scalbn(1, 1) == 2);712}713 714void test_tgamma() {715 ASSERT_SAME_TYPE(decltype(tgammaf(0)), float);716 ASSERT_SAME_TYPE(decltype(tgammal(0)), long double);717 ASSERT_SAME_TYPE(decltype(tgamma(Ambiguous())), Ambiguous);718 assert(tgamma(1) == 1);719}720 721void test_trunc() {722 ASSERT_SAME_TYPE(decltype(truncf(0)), float);723 ASSERT_SAME_TYPE(decltype(truncl(0)), long double);724 ASSERT_SAME_TYPE(decltype(trunc(Ambiguous())), Ambiguous);725 assert(trunc(1) == 1);726}727 728template <class PromoteResult, class Arg = void>729struct test_single_arg {730 template <class T = Arg>731 void operator()() {732 ASSERT_SAME_TYPE(decltype(::acos(T())), PromoteResult);733 (void)::acos(T());734 ASSERT_SAME_TYPE(decltype(::asin(T())), PromoteResult);735 (void)::asin(T());736 ASSERT_SAME_TYPE(decltype(::atan(T())), PromoteResult);737 (void)::atan(T());738 ASSERT_SAME_TYPE(decltype(::ceil(T())), PromoteResult);739 (void)::ceil(T());740 ASSERT_SAME_TYPE(decltype(::cos(T())), PromoteResult);741 (void)::cos(T());742 ASSERT_SAME_TYPE(decltype(::cosh(T())), PromoteResult);743 (void)::cosh(T());744 ASSERT_SAME_TYPE(decltype(::exp(T())), PromoteResult);745 (void)::exp(T());746 ASSERT_SAME_TYPE(decltype(::fabs(T())), PromoteResult);747 (void)::fabs(T());748 ASSERT_SAME_TYPE(decltype(::floor(T())), PromoteResult);749 (void)::floor(T());750 int ip;751 ASSERT_SAME_TYPE(decltype(::frexp(T(), &ip)), PromoteResult);752 (void)::frexp(T(), &ip);753 ASSERT_SAME_TYPE(decltype(::ldexp(T(), ip)), PromoteResult);754 (void)::ldexp(T(), ip);755 ASSERT_SAME_TYPE(decltype(::log(T())), PromoteResult);756 (void)::log(T());757 ASSERT_SAME_TYPE(decltype(::log10(T())), PromoteResult);758 (void)::log10(T());759 ASSERT_SAME_TYPE(decltype(::sin(T())), PromoteResult);760 (void)::sin(T());761 ASSERT_SAME_TYPE(decltype(::sinh(T())), PromoteResult);762 (void)::sinh(T());763 ASSERT_SAME_TYPE(decltype(::sqrt(T())), PromoteResult);764 (void)::sqrt(T());765 ASSERT_SAME_TYPE(decltype(::tan(T())), PromoteResult);766 (void)::tan(T());767 ASSERT_SAME_TYPE(decltype(::tanh(T())), PromoteResult);768 (void)::tanh(T());769 ASSERT_SAME_TYPE(decltype(::signbit(T())), bool);770 (void)::signbit(T());771 ASSERT_SAME_TYPE(decltype(::fpclassify(T())), int);772 (void)::fpclassify(T());773 ASSERT_SAME_TYPE(decltype(::isfinite(T())), bool);774 (void)::isfinite(T());775 ASSERT_SAME_TYPE(decltype(::isnormal(T())), bool);776 (void)::isnormal(T());777 ASSERT_SAME_TYPE(decltype(::acosh(T())), PromoteResult);778 (void)::acosh(T());779 ASSERT_SAME_TYPE(decltype(::asinh(T())), PromoteResult);780 (void)::asinh(T());781 ASSERT_SAME_TYPE(decltype(::atanh(T())), PromoteResult);782 (void)::atanh(T());783 ASSERT_SAME_TYPE(decltype(::cbrt(T())), PromoteResult);784 (void)::cbrt(T());785 ASSERT_SAME_TYPE(decltype(::erf(T())), PromoteResult);786 (void)::erf(T());787 ASSERT_SAME_TYPE(decltype(::erfc(T())), PromoteResult);788 (void)::erfc(T());789 ASSERT_SAME_TYPE(decltype(::exp2(T())), PromoteResult);790 (void)::exp2(T());791 ASSERT_SAME_TYPE(decltype(::expm1(T())), PromoteResult);792 (void)::expm1(T());793 ASSERT_SAME_TYPE(decltype(::ilogb(T())), int);794 (void)::ilogb(T());795 ASSERT_SAME_TYPE(decltype(::lgamma(T())), PromoteResult);796 (void)::lgamma(T());797 ASSERT_SAME_TYPE(decltype(::llrint(T())), long long);798 (void)::llrint(T());799 ASSERT_SAME_TYPE(decltype(::llround(T())), long long);800 (void)::llround(T());801 ASSERT_SAME_TYPE(decltype(::log1p(T())), PromoteResult);802 (void)::log1p(T());803 ASSERT_SAME_TYPE(decltype(::log2(T())), PromoteResult);804 (void)::log2(T());805 ASSERT_SAME_TYPE(decltype(::logb(T())), PromoteResult);806 (void)::logb(T());807 ASSERT_SAME_TYPE(decltype(::lrint(T())), long);808 (void)::lrint(T());809 ASSERT_SAME_TYPE(decltype(::lround(T())), long);810 (void)::lround(T());811 ASSERT_SAME_TYPE(decltype(::nearbyint(T())), PromoteResult);812 (void)::nearbyint(T());813 ASSERT_SAME_TYPE(decltype(::rint(T())), PromoteResult);814 (void)::rint(T());815 ASSERT_SAME_TYPE(decltype(::round(T())), PromoteResult);816 (void)::round(T());817 ASSERT_SAME_TYPE(decltype(::trunc(T())), PromoteResult);818 (void)::trunc(T());819 ASSERT_SAME_TYPE(decltype(::tgamma(T())), PromoteResult);820 (void)::tgamma(T());821 }822};823 824template <class PromoteResult, class Arg1 = void, class Arg2 = void>825struct test_two_args {826 template <class T = Arg1, class U = Arg2>827 void operator()() {828 ASSERT_SAME_TYPE(decltype(::atan2(T(), U())), PromoteResult);829 (void)::atan2(T(), U());830 ASSERT_SAME_TYPE(decltype(::fmod(T(), U())), PromoteResult);831 (void)::fmod(T(), U());832 ASSERT_SAME_TYPE(decltype(::pow(T(), U())), PromoteResult);833 (void)::pow(T(), U());834 ASSERT_SAME_TYPE(decltype(::isgreater(T(), U())), bool);835 (void)::isgreater(T(), U());836 ASSERT_SAME_TYPE(decltype(::isgreaterequal(T(), U())), bool);837 (void)::isgreaterequal(T(), U());838 ASSERT_SAME_TYPE(decltype(::isless(T(), U())), bool);839 (void)::isless(T(), U());840 ASSERT_SAME_TYPE(decltype(::islessequal(T(), U())), bool);841 (void)::islessequal(T(), U());842 ASSERT_SAME_TYPE(decltype(::islessgreater(T(), U())), bool);843 (void)::islessgreater(T(), U());844 ASSERT_SAME_TYPE(decltype(::isunordered(T(), U())), bool);845 (void)::isunordered(T(), U());846 ASSERT_SAME_TYPE(decltype(::copysign(T(), U())), PromoteResult);847 (void)::copysign(T(), U());848 ASSERT_SAME_TYPE(decltype(::fdim(T(), U())), PromoteResult);849 (void)::fdim(T(), U());850 ASSERT_SAME_TYPE(decltype(::fmax(T(), U())), PromoteResult);851 (void)::fmax(T(), U());852 ASSERT_SAME_TYPE(decltype(::fmin(T(), U())), PromoteResult);853 (void)::fmin(T(), U());854 ASSERT_SAME_TYPE(decltype(::hypot(T(), U())), PromoteResult);855 (void)::hypot(T(), U());856 ASSERT_SAME_TYPE(decltype(::nextafter(T(), U())), PromoteResult);857 (void)::nextafter(T(), U());858 ASSERT_SAME_TYPE(decltype(::remainder(T(), U())), PromoteResult);859 (void)::remainder(T(), U());860 int ip;861 ASSERT_SAME_TYPE(decltype(::remquo(T(), U(), &ip)), PromoteResult);862 ::remquo(T(), U(), &ip);863 }864};865 866template <class PromoteResult, class Arg1 = void, class Arg2 = void, class Arg3 = void>867struct test_three_args {868 template <class T = Arg1, class U = Arg2, class V = Arg3>869 void operator()() {870 ASSERT_SAME_TYPE(decltype(::fma(T(), U(), V())), PromoteResult);871 (void)::fma(T(), U(), V());872 }873};874 875struct CallTwoArgs {876 using integral_float_double = types::concatenate_t<types::integral_types, types::type_list<float, double> >;877 878 template <class Arg2>879 void operator()() {880 types::for_each(integral_float_double(), test_two_args</*PromoteResult=*/double, /*Iterate*/void, Arg2>());881 }882};883 884template <class T>885struct CallThreeArgs {886 using integral_float_double = types::concatenate_t<types::integral_types, types::type_list<float, double> >;887 888 template <class Arg3>889 struct Helper {890 891 template <class Arg2>892 void operator()() {893 types::for_each(integral_float_double(), test_three_args</*PromoteResult=*/double, /*Iterate*/void, Arg2, Arg3>());894 }895 };896 897 template <class Arg3>898 void operator()() {899 types::for_each(integral_float_double(), Helper<Arg3>());900 }901};902 903int main(int, char**) {904 types::for_each(types::integral_types(), test_single_arg</*PromoteResult=*/double>());905 test_single_arg</*PromoteResult=*/float, /*Arg=*/float>();906 test_single_arg</*PromoteResult=*/double, /*Arg=*/double>();907 test_single_arg</*PromoteResult=*/long double, /*Arg=*/long double>();908 909 types::for_each(types::integral_types(), CallTwoArgs());910 911 types::for_each(912 types::integral_types(), test_two_args</*PromoteResult=*/long double, /*Arg1=*/void, /*Arg2=*/long double>());913 914 test_two_args</*PromoteResult=*/float, /*Args=*/float, float>();915 test_two_args</*PromoteResult=*/float, /*Args=*/double, double>();916 test_two_args</*PromoteResult=*/double, /*Args=*/float, double>();917 test_two_args</*PromoteResult=*/double, /*Args=*/double, double>();918 919 types::for_each(types::integral_types(), CallThreeArgs<double>());920 types::for_each(921 types::integral_types(), test_three_args</*PromoteResult=*/long double, /*Iterate*/ void, long double, double>());922 923 test_three_args</*PromoteResult=*/float, /*Args=*/float, float, float>();924 test_three_args</*PromoteResult=*/double, /*Args=*/double, double, double>();925 test_three_args</*PromoteResult=*/long double, /*Args=*/long double, long double, long double>();926 927 test_abs();928 test_acos();929 test_asin();930 test_atan();931 test_atan2();932 test_ceil();933 test_cos();934 test_cosh();935 test_exp();936 test_fabs();937 test_floor();938 test_fmod();939 test_frexp();940 test_ldexp();941 test_log();942 test_log10();943 test_modf();944 test_pow();945 test_sin();946 test_sinh();947 test_sqrt();948 test_tan();949 test_tanh();950 test_signbit();951 test_fpclassify();952 test_isfinite();953 test_isnormal();954 test_isgreater();955 test_isgreaterequal();956 test_isinf();957 test_isless();958 test_islessequal();959 test_islessgreater();960 test_isnan();961 test_isunordered();962 test_acosh();963 test_asinh();964 test_atanh();965 test_cbrt();966 test_copysign();967 test_erf();968 test_erfc();969 test_exp2();970 test_expm1();971 test_fdim();972 test_fma();973 test_fmax();974 test_fmin();975 test_hypot();976 test_ilogb();977 test_lgamma();978 test_llrint();979 test_llround();980 test_log1p();981 test_log2();982 test_logb();983 test_lrint();984 test_lround();985 test_nan();986 test_nearbyint();987 test_nextafter();988 test_nexttoward();989 test_remainder();990 test_remquo();991 test_rint();992 test_round();993 test_scalbln();994 test_scalbn();995 test_tgamma();996 test_trunc();997 998 return 0;999}1000