Reactos
at master 650 lines 19 kB view raw
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 88inline _Lcomplex __cpowl_lc_dc(_Lcomplex const __lc, _Dcomplex const __dc) 89{ 90 return cpowl(__lc, _LCbuild(__dc._Val[0], __dc._Val[1])); 91} 92 93inline _Lcomplex __cpowl_dc_lc(_Dcomplex const __dc, _Lcomplex const __lc) 94{ 95 return cpowl(_LCbuild(__dc._Val[0], __dc._Val[1]), __lc); 96} 97 98inline _Lcomplex __cpowl_lc_fc(_Lcomplex const __lc, _Fcomplex const __fc) 99{ 100 return cpowl(__lc, _LCbuild(__fc._Val[0], __fc._Val[1])); 101} 102 103inline _Lcomplex __cpowl_fc_lc(_Fcomplex const __fc, _Lcomplex const __lc) 104{ 105 return cpowl(_LCbuild(__fc._Val[0], __fc._Val[1]), __lc); 106} 107 108inline _Lcomplex __cpowl_lc_l(_Lcomplex const __lc, long double const __l) 109{ 110 return cpowl(__lc, _LCbuild(__l, 0.0)); 111} 112 113inline _Lcomplex __cpowl_l_lc(long double const __l, _Lcomplex const __lc) 114{ 115 return cpowl(_LCbuild(__l, 0.0), __lc); 116} 117 118inline _Lcomplex __cpowl_lc_d(_Lcomplex const __lc, double const __d) 119{ 120 return cpowl(__lc, _LCbuild(__d, 0.0)); 121} 122 123inline _Lcomplex __cpowl_d_lc(double const __d, _Lcomplex const __lc) 124{ 125 return cpowl(_LCbuild(__d, 0.0), __lc); 126} 127 128inline _Lcomplex __cpowl_lc_f(_Lcomplex const __lc, float const __f) 129{ 130 return cpowl(__lc, _LCbuild(__f, 0.0)); 131} 132 133inline _Lcomplex __cpowl_f_lc(float const __f, _Lcomplex const __lc) 134{ 135 return cpowl(_LCbuild(__f, 0.0), __lc); 136} 137 138inline _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 143inline _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 148inline _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 153inline _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 158inline _Dcomplex __cpow_dc_fc(_Dcomplex const __dc, _Fcomplex const __fc) 159{ 160 return cpow(__dc, _Cbuild(__fc._Val[0], __fc._Val[1])); 161} 162 163inline _Dcomplex __cpow_fc_dc(_Fcomplex const __fc, _Dcomplex const __dc) 164{ 165 return cpow(_Cbuild(__fc._Val[0], __fc._Val[1]), __dc); 166} 167 168inline _Dcomplex __cpow_dc_d(_Dcomplex const __dc, double const __d) 169{ 170 return cpow(__dc, _Cbuild(__d, 0.0)); 171} 172 173inline _Dcomplex __cpow_d_dc(double const __d, _Dcomplex const __dc) 174{ 175 return cpow(_Cbuild(__d, 0.0), __dc); 176} 177 178inline _Dcomplex __cpow_dc_f(_Dcomplex const __dc, float const __f) 179{ 180 return cpow(__dc, _Cbuild(__f, 0.0)); 181} 182 183inline _Dcomplex __cpow_f_dc(float const __f, _Dcomplex const __dc) 184{ 185 return cpow(_Cbuild(__f, 0.0), __dc); 186} 187 188inline _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 193inline _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 198inline _Fcomplex __cpowf_fc_f(_Fcomplex const __fc, float const __f) 199{ 200 return cpowf(__fc, _FCbuild(__f, 0.0f)); 201} 202 203inline _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 579inline 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 591inline _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 603inline 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 616inline 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 630inline _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