1 // 2 // tgmath.h 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // The type-generic math library. 7 // 8 #pragma once 9 #ifndef _TGMATH 10 #define _TGMATH 11 12 #include <corecrt.h> 13 14 #if (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_TGMATH_H) 15 16 #include <ctgmath> 17 18 #else // ^^^^ /std:c++17 ^^^^ // vvvv _CRT_USE_C_TGMATH_H vvvv 19 20 #include <math.h> 21 #include <complex.h> 22 23 #if _CRT_HAS_C11 == 0 24 25 #ifndef _CRT_SILENCE_NONCONFORMING_TGMATH_H 26 27 #pragma message(_CRT_WARNING_MESSAGE("UCRT4000", \ 28 "This header does not conform to the C99 standard. " \ 29 "C99 functionality is available when compiling in C11 mode or higher (/std:c11). " \ 30 "Functionality equivalent to the type-generic functions provided by tgmath.h is available " \ 31 "in <ctgmath> when compiling as C++. " \ 32 "If compiling in C++17 mode or higher (/std:c++17), this header will automatically include <ctgmath> instead. " \ 33 "You can define _CRT_SILENCE_NONCONFORMING_TGMATH_H to acknowledge that you have received this warning.")) 34 35 #endif // _CRT_SILENCE_NONCONFORMING_TGMATH_H 36 37 #else // ^^^^ Default C Support ^^^^ // vvvv C11 Support vvvv 38 39 #pragma warning(push) 40 #pragma warning(disable: _UCRT_DISABLED_WARNINGS) 41 _UCRT_DISABLE_CLANG_WARNINGS 42 _CRT_BEGIN_C_HEADER 43 44 #define __tgmath_resolve_real_binary_op(X, Y) _Generic((X), \ 45 long double: 0.0l, \ 46 \ 47 default: _Generic((Y), \ 48 long double: 0.0l, \ 49 default: 0.0 \ 50 ), \ 51 \ 52 float: _Generic((Y), \ 53 long double: 0.0l, \ 54 default: 0.0, \ 55 float: 0.0f \ 56 ) \ 57 ) 58 59 #define fabs(X) _Generic((X), \ 60 _Lcomplex: cabsl, \ 61 _Fcomplex: cabsf, \ 62 _Dcomplex: cabs, \ 63 long double: fabsl, \ 64 float: fabsf, \ 65 default: fabs \ 66 )(X) 67 68 #define exp(X) _Generic((X), \ 69 _Lcomplex: cexpl, \ 70 _Fcomplex: cexpf, \ 71 _Dcomplex: cexp, \ 72 long double: expl, \ 73 float: expf, \ 74 default: exp \ 75 )(X) 76 77 #define log(X) _Generic((X), \ 78 _Lcomplex: clogl, \ 79 _Fcomplex: clogf, \ 80 _Dcomplex: clog, \ 81 long double: logl, \ 82 float: logf, \ 83 default: log \ 84 )(X) 85 86 // C99 Complex types currently not supported. Complex types do not cast/promote implicitly - need inline helper functions. 87 88 inline _Lcomplex __cpowl_lc_dc(_Lcomplex const __lc, _Dcomplex const __dc) 89 { 90 return cpowl(__lc, _LCbuild(__dc._Val[0], __dc._Val[1])); 91 } 92 93 inline _Lcomplex __cpowl_dc_lc(_Dcomplex const __dc, _Lcomplex const __lc) 94 { 95 return cpowl(_LCbuild(__dc._Val[0], __dc._Val[1]), __lc); 96 } 97 98 inline _Lcomplex __cpowl_lc_fc(_Lcomplex const __lc, _Fcomplex const __fc) 99 { 100 return cpowl(__lc, _LCbuild(__fc._Val[0], __fc._Val[1])); 101 } 102 103 inline _Lcomplex __cpowl_fc_lc(_Fcomplex const __fc, _Lcomplex const __lc) 104 { 105 return cpowl(_LCbuild(__fc._Val[0], __fc._Val[1]), __lc); 106 } 107 108 inline _Lcomplex __cpowl_lc_l(_Lcomplex const __lc, long double const __l) 109 { 110 return cpowl(__lc, _LCbuild(__l, 0.0)); 111 } 112 113 inline _Lcomplex __cpowl_l_lc(long double const __l, _Lcomplex const __lc) 114 { 115 return cpowl(_LCbuild(__l, 0.0), __lc); 116 } 117 118 inline _Lcomplex __cpowl_lc_d(_Lcomplex const __lc, double const __d) 119 { 120 return cpowl(__lc, _LCbuild(__d, 0.0)); 121 } 122 123 inline _Lcomplex __cpowl_d_lc(double const __d, _Lcomplex const __lc) 124 { 125 return cpowl(_LCbuild(__d, 0.0), __lc); 126 } 127 128 inline _Lcomplex __cpowl_lc_f(_Lcomplex const __lc, float const __f) 129 { 130 return cpowl(__lc, _LCbuild(__f, 0.0)); 131 } 132 133 inline _Lcomplex __cpowl_f_lc(float const __f, _Lcomplex const __lc) 134 { 135 return cpowl(_LCbuild(__f, 0.0), __lc); 136 } 137 138 inline _Lcomplex __cpowl_dc_l(_Dcomplex const __dc, long double const __l) 139 { 140 return cpowl(_LCbuild(__dc._Val[0], __dc._Val[1]), _LCbuild(__l, 0.0)); 141 } 142 143 inline _Lcomplex __cpowl_l_dc(long double const __l, _Dcomplex const __dc) 144 { 145 return cpowl(_LCbuild(__l, 0.0), _LCbuild(__dc._Val[0], __dc._Val[1])); 146 } 147 148 inline _Lcomplex __cpowl_fc_l(_Fcomplex const __fc, long double const __l) 149 { 150 return cpowl(_LCbuild(__fc._Val[0], __fc._Val[1]), _LCbuild(__l, 0.0)); 151 } 152 153 inline _Lcomplex __cpowl_l_fc(long double const __l, _Fcomplex const __fc) 154 { 155 return cpowl(_LCbuild(__l, 0.0), _LCbuild(__fc._Val[0], __fc._Val[1])); 156 } 157 158 inline _Dcomplex __cpow_dc_fc(_Dcomplex const __dc, _Fcomplex const __fc) 159 { 160 return cpow(__dc, _Cbuild(__fc._Val[0], __fc._Val[1])); 161 } 162 163 inline _Dcomplex __cpow_fc_dc(_Fcomplex const __fc, _Dcomplex const __dc) 164 { 165 return cpow(_Cbuild(__fc._Val[0], __fc._Val[1]), __dc); 166 } 167 168 inline _Dcomplex __cpow_dc_d(_Dcomplex const __dc, double const __d) 169 { 170 return cpow(__dc, _Cbuild(__d, 0.0)); 171 } 172 173 inline _Dcomplex __cpow_d_dc(double const __d, _Dcomplex const __dc) 174 { 175 return cpow(_Cbuild(__d, 0.0), __dc); 176 } 177 178 inline _Dcomplex __cpow_dc_f(_Dcomplex const __dc, float const __f) 179 { 180 return cpow(__dc, _Cbuild(__f, 0.0)); 181 } 182 183 inline _Dcomplex __cpow_f_dc(float const __f, _Dcomplex const __dc) 184 { 185 return cpow(_Cbuild(__f, 0.0), __dc); 186 } 187 188 inline _Dcomplex __cpow_fc_d(_Fcomplex const __fc, double const __d) 189 { 190 return cpow(_Cbuild(__fc._Val[0], __fc._Val[1]), _Cbuild(__d, 0.0)); 191 } 192 193 inline _Dcomplex __cpow_d_fc(double const __d, _Fcomplex const __fc) 194 { 195 return cpow(_Cbuild(__d, 0.0), _Cbuild(__fc._Val[0], __fc._Val[1])); 196 } 197 198 inline _Fcomplex __cpowf_fc_f(_Fcomplex const __fc, float const __f) 199 { 200 return cpowf(__fc, _FCbuild(__f, 0.0f)); 201 } 202 203 inline _Fcomplex __cpowf_f_fc(float const __f, _Fcomplex const __fc) 204 { 205 return cpowf(_FCbuild(__f, 0.0f), __fc); 206 } 207 208 #define pow(X, Y) _Generic((X), \ 209 _Lcomplex: _Generic((Y), \ 210 _Lcomplex: cpowl, \ 211 _Fcomplex: __cpowl_lc_fc, \ 212 _Dcomplex: __cpowl_lc_dc, \ 213 long double: __cpowl_lc_l, \ 214 default: __cpowl_lc_d, \ 215 float: __cpowl_lc_f \ 216 ), \ 217 \ 218 _Fcomplex: _Generic((Y), \ 219 _Lcomplex: __cpowl_fc_lc, \ 220 _Fcomplex: cpowf, \ 221 _Dcomplex: __cpow_fc_dc, \ 222 long double: __cpowl_fc_l, \ 223 default: __cpow_fc_d, \ 224 float: __cpowf_fc_f \ 225 ), \ 226 \ 227 _Dcomplex: _Generic((Y), \ 228 _Lcomplex: __cpowl_dc_lc, \ 229 _Fcomplex: __cpow_dc_fc, \ 230 _Dcomplex: cpow, \ 231 long double: __cpowl_dc_l, \ 232 default: __cpow_dc_d, \ 233 float: __cpow_dc_f \ 234 ), \ 235 \ 236 long double: _Generic((Y), \ 237 _Lcomplex: __cpowl_l_lc, \ 238 _Fcomplex: __cpowl_l_fc, \ 239 _Dcomplex: __cpowl_l_dc, \ 240 default: powl \ 241 ), \ 242 \ 243 float: _Generic((Y), \ 244 _Lcomplex: __cpowl_f_lc, \ 245 _Fcomplex: __cpowf_f_fc, \ 246 _Dcomplex: __cpow_f_dc, \ 247 long double: powl, \ 248 default: pow, \ 249 float: powf \ 250 ), \ 251 \ 252 default: _Generic((Y), \ 253 _Lcomplex: __cpowl_d_lc, \ 254 _Fcomplex: __cpow_d_fc, \ 255 _Dcomplex: __cpow_d_dc, \ 256 long double: powl, \ 257 default: pow \ 258 ) \ 259 )(X, Y) 260 261 #define sqrt(X) _Generic((X), \ 262 _Lcomplex: csqrtl, \ 263 _Fcomplex: csqrtf, \ 264 _Dcomplex: csqrt, \ 265 long double: sqrtl, \ 266 float: sqrtf, \ 267 default: sqrt \ 268 )(X) 269 270 #define sin(X) _Generic((X), \ 271 _Lcomplex: csinl, \ 272 _Fcomplex: csinf, \ 273 _Dcomplex: csin, \ 274 long double: sinl, \ 275 float: sinf, \ 276 default: sin \ 277 )(X) 278 279 #define cos(X) _Generic((X), \ 280 _Lcomplex: ccosl, \ 281 _Fcomplex: ccosf, \ 282 _Dcomplex: ccos, \ 283 long double: cosl, \ 284 float: cosf, \ 285 default: cos \ 286 )(X) 287 288 #define tan(X) _Generic((X), \ 289 _Lcomplex: ctanl, \ 290 _Fcomplex: ctanf, \ 291 _Dcomplex: ctan, \ 292 long double: tanl, \ 293 float: tanf, \ 294 default: tan \ 295 )(X) 296 297 #define asin(X) _Generic((X), \ 298 _Lcomplex: casinl, \ 299 _Fcomplex: casinf, \ 300 _Dcomplex: casin, \ 301 long double: asinl, \ 302 float: asinf, \ 303 default: asin \ 304 )(X) 305 306 #define acos(X) _Generic((X), \ 307 _Lcomplex: cacosl, \ 308 _Fcomplex: cacosf, \ 309 _Dcomplex: cacos, \ 310 long double: acosl, \ 311 float: acosf, \ 312 default: acos \ 313 )(X) 314 315 #define atan(X) _Generic((X), \ 316 _Lcomplex: catanl, \ 317 _Fcomplex: catanf, \ 318 _Dcomplex: catan, \ 319 long double: atanl, \ 320 float: atanf, \ 321 default: atan \ 322 )(X) 323 324 #define asinh(X) _Generic((X), \ 325 _Lcomplex: casinhl, \ 326 _Fcomplex: casinhf, \ 327 _Dcomplex: casinh, \ 328 long double: asinhl, \ 329 float: asinhf, \ 330 default: asinh \ 331 )(X) 332 333 #define acosh(X) _Generic((X), \ 334 _Lcomplex: cacoshl, \ 335 _Fcomplex: cacoshf, \ 336 _Dcomplex: cacosh, \ 337 long double: acoshl, \ 338 float: acoshf, \ 339 default: acosh \ 340 )(X) 341 342 #define atanh(X) _Generic((X), \ 343 _Lcomplex: catanhl, \ 344 _Fcomplex: catanhf, \ 345 _Dcomplex: catanh, \ 346 long double: atanhl, \ 347 float: atanhf, \ 348 default: atanh \ 349 )(X) 350 351 #define atan2(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 352 long double: atan2l, \ 353 float: atan2f, \ 354 default: atan2 \ 355 )(X, Y) 356 357 #define cbrt(X) _Generic((X), \ 358 long double: cbrtl, \ 359 float: cbrtf, \ 360 default: cbrt \ 361 )(X) 362 363 #define ceil(X) _Generic((X), \ 364 long double: ceill, \ 365 float: ceilf, \ 366 default: ceil \ 367 )(X) 368 369 #define copysign(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 370 long double: copysignl, \ 371 float: copysignf, \ 372 default: copysign \ 373 )(X, Y) 374 375 #define erf(X) _Generic((X), \ 376 long double: erfl, \ 377 float: erff, \ 378 default: erf \ 379 )(X) 380 381 #define erfc(X) _Generic((X), \ 382 long double: erfcl, \ 383 float: erfcf, \ 384 default: erfc \ 385 )(X) 386 387 #define exp2(X) _Generic((X), \ 388 long double: exp2l, \ 389 float: exp2f, \ 390 default: exp2 \ 391 )(X) 392 393 #define expm1(X) _Generic((X), \ 394 long double: expm1l, \ 395 float: expm1f, \ 396 default: expm1 \ 397 )(X) 398 399 #define fdim(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 400 long double: fdiml, \ 401 float: fdimf, \ 402 default: fdim \ 403 )(X, Y) 404 405 #define floor(X) _Generic((X), \ 406 long double: floorl, \ 407 float: floorf, \ 408 default: floor \ 409 )(X) 410 411 #define fma(X, Y, Z) _Generic(__tgmath_resolve_real_binary_op((X), __tgmath_resolve_real_binary_op((Y), (Z))), \ 412 long double: fmal, \ 413 float: fmaf, \ 414 default: fma \ 415 )(X, Y, Z) 416 417 #define fmax(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 418 long double: fmaxl, \ 419 float: fmaxf, \ 420 default: fmax \ 421 )(X, Y) 422 423 #define fmin(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 424 long double: fminl, \ 425 float: fminf, \ 426 default: fmin \ 427 )(X, Y) 428 429 #define fmod(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 430 long double: fmodl, \ 431 float: fmodf, \ 432 default: fmod \ 433 )(X, Y) 434 435 #define frexp(X, INT_PTR) _Generic((X), \ 436 long double: frexpl, \ 437 float: frexpf, \ 438 default: frexp \ 439 )(X, INT_PTR) 440 441 #define hypot(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 442 long double: hypotl, \ 443 float: hypotf, \ 444 default: hypot \ 445 )(X, Y) 446 447 #define ilogb(X) _Generic((X), \ 448 long double: ilogbl, \ 449 float: ilogbf, \ 450 default: ilogb \ 451 )(X) 452 453 #define ldexp(X, INT) _Generic((X), \ 454 long double: ldexpl, \ 455 float: ldexpf, \ 456 default: ldexp \ 457 )(X, INT) 458 459 #define lgamma(X) _Generic((X), \ 460 long double: lgammal, \ 461 float: lgammaf, \ 462 default: lgamma \ 463 )(X) 464 465 #define llrint(X) _Generic((X), \ 466 long double: llrintl, \ 467 float: llrintf, \ 468 default: llrint \ 469 )(X) 470 471 #define llround(X) _Generic((X), \ 472 long double: llroundl, \ 473 float: llroundf, \ 474 default: llround \ 475 )(X) 476 477 #define log10(X) _Generic((X), \ 478 long double: log10l, \ 479 float: log10f, \ 480 default: log10 \ 481 )(X) 482 483 #define log1p(X) _Generic((X), \ 484 long double: log1pl, \ 485 float: log1pf, \ 486 default: log1p \ 487 )(X) 488 489 #define log2(X) _Generic((X), \ 490 long double: log2l, \ 491 float: log2f, \ 492 default: log2 \ 493 )(X) 494 495 #define logb(X) _Generic((X), \ 496 long double: logbl, \ 497 float: logbf, \ 498 default: logb \ 499 )(X) 500 501 #define lrint(X) _Generic((X), \ 502 long double: lrintl, \ 503 float: lrintf, \ 504 default: lrint \ 505 )(X) 506 507 #define lround(X) _Generic((X), \ 508 long double: lroundl, \ 509 float: lroundf, \ 510 default: lround \ 511 )(X) 512 513 #define nearbyint(X) _Generic((X), \ 514 long double: nearbyintl, \ 515 float: nearbyintf, \ 516 default: nearbyint \ 517 )(X) 518 519 #define nextafter(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 520 long double: nextafterl, \ 521 float: nextafterf, \ 522 default: nextafter \ 523 )(X, Y) 524 525 #define nexttoward(X, LONG_DOUBLE) _Generic((X), \ 526 long double: nexttowardl, \ 527 float: nexttowardf, \ 528 default: nexttoward \ 529 )(X, LONG_DOUBLE) 530 531 #define remainder(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 532 long double: remainderl, \ 533 float: remainderf, \ 534 default: remainder \ 535 )(X, Y) 536 537 #define remquo(X, Y, INT_PTR) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ 538 long double: remquol, \ 539 float: remquof, \ 540 default: remquo \ 541 )(X, Y, INT_PTR) 542 543 #define rint(X) _Generic((X), \ 544 long double: rintl, \ 545 float: rintf, \ 546 default: rint \ 547 )(X) 548 549 #define round(X) _Generic((X), \ 550 long double: roundl, \ 551 float: roundf, \ 552 default: round \ 553 )(X) 554 555 #define scalbln(X, LONG) _Generic((X), \ 556 long double: scalblnl, \ 557 float: scalblnf, \ 558 default: scalbln \ 559 )(X, LONG) 560 561 #define scalbn(X, INT) _Generic((X), \ 562 long double: scalbnl, \ 563 float: scalbnf, \ 564 default: scalbn \ 565 )(X, INT) 566 567 #define tgamma(X) _Generic((X), \ 568 long double: tgammal, \ 569 float: tgammaf, \ 570 default: tgamma \ 571 )(X) 572 573 #define trunc(X) _Generic((X), \ 574 long double: truncl, \ 575 float: truncf, \ 576 default: trunc \ 577 )(X) 578 579 inline double __carg_d(double const __d) 580 { 581 return carg(_Cbuild(__d, 0.0)); 582 } 583 584 #define carg(X) _Generic((X), \ 585 _Lcomplex: cargl, \ 586 _Fcomplex: cargf, \ 587 _Dcomplex: carg, \ 588 default: __carg_d \ 589 )(X) 590 591 inline _Dcomplex __conj_d(double const __d) 592 { 593 return conj(_Cbuild(__d, 0.0)); 594 } 595 596 #define conj(X) _Generic((X), \ 597 _Lcomplex: conjl, \ 598 _Fcomplex: conjf, \ 599 _Dcomplex: conj, \ 600 default: __conj_d \ 601 )(X) 602 603 inline double __creal_d(double const __d) 604 { 605 // The real part of a double casted to a double complex is just the double value. 606 return __d; 607 } 608 609 #define creal(X) _Generic((X), \ 610 _Lcomplex: creall, \ 611 _Fcomplex: crealf, \ 612 _Dcomplex: creal, \ 613 default: __creal_d \ 614 )(X) 615 616 inline double __cimag_d(double const __d) 617 { 618 // The imaginary part of a double casted to a double complex is 0. 619 (void) __d; 620 return 0.0; 621 } 622 623 #define cimag(X) _Generic((X), \ 624 _Lcomplex: cimagl, \ 625 _Fcomplex: cimagf, \ 626 _Dcomplex: cimag, \ 627 default: __cimag_d \ 628 )(X) 629 630 inline _Dcomplex __cproj_d(double const __d) 631 { 632 return cproj(_Cbuild(__d, 0.0)); 633 } 634 635 #define cproj(X) _Generic((X), \ 636 _Lcomplex: cprojl, \ 637 _Fcomplex: cprojf, \ 638 _Dcomplex: cproj, \ 639 default: __cproj_d \ 640 )(X) 641 642 _CRT_END_C_HEADER 643 _UCRT_RESTORE_CLANG_WARNINGS 644 #pragma warning(pop) // _UCRT_DISABLED_WARNINGS 645 646 #endif // _CRT_HAS_C11 == 0 647 648 #endif // (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_TGMATH_H) 649 650 #endif // _TGMATH 651