10b57cec5SDimitry Andric // -*- C++ -*-
2349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric //
40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #ifndef _LIBCPP_MATH_H
110b57cec5SDimitry Andric #  define _LIBCPP_MATH_H
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric /*
140b57cec5SDimitry Andric     math.h synopsis
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric Macros:
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric     HUGE_VAL
190b57cec5SDimitry Andric     HUGE_VALF               // C99
200b57cec5SDimitry Andric     HUGE_VALL               // C99
210b57cec5SDimitry Andric     INFINITY                // C99
220b57cec5SDimitry Andric     NAN                     // C99
230b57cec5SDimitry Andric     FP_INFINITE             // C99
240b57cec5SDimitry Andric     FP_NAN                  // C99
250b57cec5SDimitry Andric     FP_NORMAL               // C99
260b57cec5SDimitry Andric     FP_SUBNORMAL            // C99
270b57cec5SDimitry Andric     FP_ZERO                 // C99
280b57cec5SDimitry Andric     FP_FAST_FMA             // C99
290b57cec5SDimitry Andric     FP_FAST_FMAF            // C99
300b57cec5SDimitry Andric     FP_FAST_FMAL            // C99
310b57cec5SDimitry Andric     FP_ILOGB0               // C99
320b57cec5SDimitry Andric     FP_ILOGBNAN             // C99
330b57cec5SDimitry Andric     MATH_ERRNO              // C99
340b57cec5SDimitry Andric     MATH_ERREXCEPT          // C99
350b57cec5SDimitry Andric     math_errhandling        // C99
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric Types:
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric     float_t                 // C99
400b57cec5SDimitry Andric     double_t                // C99
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric // C90
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric floating_point abs(floating_point x);
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric floating_point acos (arithmetic x);
470b57cec5SDimitry Andric float          acosf(float x);
480b57cec5SDimitry Andric long double    acosl(long double x);
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric floating_point asin (arithmetic x);
510b57cec5SDimitry Andric float          asinf(float x);
520b57cec5SDimitry Andric long double    asinl(long double x);
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric floating_point atan (arithmetic x);
550b57cec5SDimitry Andric float          atanf(float x);
560b57cec5SDimitry Andric long double    atanl(long double x);
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric floating_point atan2 (arithmetic y, arithmetic x);
590b57cec5SDimitry Andric float          atan2f(float y, float x);
600b57cec5SDimitry Andric long double    atan2l(long double y, long double x);
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric floating_point ceil (arithmetic x);
630b57cec5SDimitry Andric float          ceilf(float x);
640b57cec5SDimitry Andric long double    ceill(long double x);
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric floating_point cos (arithmetic x);
670b57cec5SDimitry Andric float          cosf(float x);
680b57cec5SDimitry Andric long double    cosl(long double x);
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric floating_point cosh (arithmetic x);
710b57cec5SDimitry Andric float          coshf(float x);
720b57cec5SDimitry Andric long double    coshl(long double x);
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric floating_point exp (arithmetic x);
750b57cec5SDimitry Andric float          expf(float x);
760b57cec5SDimitry Andric long double    expl(long double x);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric floating_point fabs (arithmetic x);
790b57cec5SDimitry Andric float          fabsf(float x);
800b57cec5SDimitry Andric long double    fabsl(long double x);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric floating_point floor (arithmetic x);
830b57cec5SDimitry Andric float          floorf(float x);
840b57cec5SDimitry Andric long double    floorl(long double x);
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric floating_point fmod (arithmetic x, arithmetic y);
870b57cec5SDimitry Andric float          fmodf(float x, float y);
880b57cec5SDimitry Andric long double    fmodl(long double x, long double y);
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric floating_point frexp (arithmetic value, int* exp);
910b57cec5SDimitry Andric float          frexpf(float value, int* exp);
920b57cec5SDimitry Andric long double    frexpl(long double value, int* exp);
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric floating_point ldexp (arithmetic value, int exp);
950b57cec5SDimitry Andric float          ldexpf(float value, int exp);
960b57cec5SDimitry Andric long double    ldexpl(long double value, int exp);
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric floating_point log (arithmetic x);
990b57cec5SDimitry Andric float          logf(float x);
1000b57cec5SDimitry Andric long double    logl(long double x);
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric floating_point log10 (arithmetic x);
1030b57cec5SDimitry Andric float          log10f(float x);
1040b57cec5SDimitry Andric long double    log10l(long double x);
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric floating_point modf (floating_point value, floating_point* iptr);
1070b57cec5SDimitry Andric float          modff(float value, float* iptr);
1080b57cec5SDimitry Andric long double    modfl(long double value, long double* iptr);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric floating_point pow (arithmetic x, arithmetic y);
1110b57cec5SDimitry Andric float          powf(float x, float y);
1120b57cec5SDimitry Andric long double    powl(long double x, long double y);
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric floating_point sin (arithmetic x);
1150b57cec5SDimitry Andric float          sinf(float x);
1160b57cec5SDimitry Andric long double    sinl(long double x);
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric floating_point sinh (arithmetic x);
1190b57cec5SDimitry Andric float          sinhf(float x);
1200b57cec5SDimitry Andric long double    sinhl(long double x);
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric floating_point sqrt (arithmetic x);
1230b57cec5SDimitry Andric float          sqrtf(float x);
1240b57cec5SDimitry Andric long double    sqrtl(long double x);
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric floating_point tan (arithmetic x);
1270b57cec5SDimitry Andric float          tanf(float x);
1280b57cec5SDimitry Andric long double    tanl(long double x);
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric floating_point tanh (arithmetic x);
1310b57cec5SDimitry Andric float          tanhf(float x);
1320b57cec5SDimitry Andric long double    tanhl(long double x);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric //  C99
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric bool signbit(arithmetic x);
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric int fpclassify(arithmetic x);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric bool isfinite(arithmetic x);
1410b57cec5SDimitry Andric bool isinf(arithmetic x);
1420b57cec5SDimitry Andric bool isnan(arithmetic x);
1430b57cec5SDimitry Andric bool isnormal(arithmetic x);
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric bool isgreater(arithmetic x, arithmetic y);
1460b57cec5SDimitry Andric bool isgreaterequal(arithmetic x, arithmetic y);
1470b57cec5SDimitry Andric bool isless(arithmetic x, arithmetic y);
1480b57cec5SDimitry Andric bool islessequal(arithmetic x, arithmetic y);
1490b57cec5SDimitry Andric bool islessgreater(arithmetic x, arithmetic y);
1500b57cec5SDimitry Andric bool isunordered(arithmetic x, arithmetic y);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric floating_point acosh (arithmetic x);
1530b57cec5SDimitry Andric float          acoshf(float x);
1540b57cec5SDimitry Andric long double    acoshl(long double x);
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric floating_point asinh (arithmetic x);
1570b57cec5SDimitry Andric float          asinhf(float x);
1580b57cec5SDimitry Andric long double    asinhl(long double x);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric floating_point atanh (arithmetic x);
1610b57cec5SDimitry Andric float          atanhf(float x);
1620b57cec5SDimitry Andric long double    atanhl(long double x);
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric floating_point cbrt (arithmetic x);
1650b57cec5SDimitry Andric float          cbrtf(float x);
1660b57cec5SDimitry Andric long double    cbrtl(long double x);
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric floating_point copysign (arithmetic x, arithmetic y);
1690b57cec5SDimitry Andric float          copysignf(float x, float y);
1700b57cec5SDimitry Andric long double    copysignl(long double x, long double y);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric floating_point erf (arithmetic x);
1730b57cec5SDimitry Andric float          erff(float x);
1740b57cec5SDimitry Andric long double    erfl(long double x);
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric floating_point erfc (arithmetic x);
1770b57cec5SDimitry Andric float          erfcf(float x);
1780b57cec5SDimitry Andric long double    erfcl(long double x);
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric floating_point exp2 (arithmetic x);
1810b57cec5SDimitry Andric float          exp2f(float x);
1820b57cec5SDimitry Andric long double    exp2l(long double x);
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric floating_point expm1 (arithmetic x);
1850b57cec5SDimitry Andric float          expm1f(float x);
1860b57cec5SDimitry Andric long double    expm1l(long double x);
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric floating_point fdim (arithmetic x, arithmetic y);
1890b57cec5SDimitry Andric float          fdimf(float x, float y);
1900b57cec5SDimitry Andric long double    fdiml(long double x, long double y);
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric floating_point fma (arithmetic x, arithmetic y, arithmetic z);
1930b57cec5SDimitry Andric float          fmaf(float x, float y, float z);
1940b57cec5SDimitry Andric long double    fmal(long double x, long double y, long double z);
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric floating_point fmax (arithmetic x, arithmetic y);
1970b57cec5SDimitry Andric float          fmaxf(float x, float y);
1980b57cec5SDimitry Andric long double    fmaxl(long double x, long double y);
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric floating_point fmin (arithmetic x, arithmetic y);
2010b57cec5SDimitry Andric float          fminf(float x, float y);
2020b57cec5SDimitry Andric long double    fminl(long double x, long double y);
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric floating_point hypot (arithmetic x, arithmetic y);
2050b57cec5SDimitry Andric float          hypotf(float x, float y);
2060b57cec5SDimitry Andric long double    hypotl(long double x, long double y);
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric int ilogb (arithmetic x);
2090b57cec5SDimitry Andric int ilogbf(float x);
2100b57cec5SDimitry Andric int ilogbl(long double x);
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric floating_point lgamma (arithmetic x);
2130b57cec5SDimitry Andric float          lgammaf(float x);
2140b57cec5SDimitry Andric long double    lgammal(long double x);
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric long long llrint (arithmetic x);
2170b57cec5SDimitry Andric long long llrintf(float x);
2180b57cec5SDimitry Andric long long llrintl(long double x);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric long long llround (arithmetic x);
2210b57cec5SDimitry Andric long long llroundf(float x);
2220b57cec5SDimitry Andric long long llroundl(long double x);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric floating_point log1p (arithmetic x);
2250b57cec5SDimitry Andric float          log1pf(float x);
2260b57cec5SDimitry Andric long double    log1pl(long double x);
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric floating_point log2 (arithmetic x);
2290b57cec5SDimitry Andric float          log2f(float x);
2300b57cec5SDimitry Andric long double    log2l(long double x);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric floating_point logb (arithmetic x);
2330b57cec5SDimitry Andric float          logbf(float x);
2340b57cec5SDimitry Andric long double    logbl(long double x);
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric long lrint (arithmetic x);
2370b57cec5SDimitry Andric long lrintf(float x);
2380b57cec5SDimitry Andric long lrintl(long double x);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric long lround (arithmetic x);
2410b57cec5SDimitry Andric long lroundf(float x);
2420b57cec5SDimitry Andric long lroundl(long double x);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric double      nan (const char* str);
2450b57cec5SDimitry Andric float       nanf(const char* str);
2460b57cec5SDimitry Andric long double nanl(const char* str);
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric floating_point nearbyint (arithmetic x);
2490b57cec5SDimitry Andric float          nearbyintf(float x);
2500b57cec5SDimitry Andric long double    nearbyintl(long double x);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric floating_point nextafter (arithmetic x, arithmetic y);
2530b57cec5SDimitry Andric float          nextafterf(float x, float y);
2540b57cec5SDimitry Andric long double    nextafterl(long double x, long double y);
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric floating_point nexttoward (arithmetic x, long double y);
2570b57cec5SDimitry Andric float          nexttowardf(float x, long double y);
2580b57cec5SDimitry Andric long double    nexttowardl(long double x, long double y);
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric floating_point remainder (arithmetic x, arithmetic y);
2610b57cec5SDimitry Andric float          remainderf(float x, float y);
2620b57cec5SDimitry Andric long double    remainderl(long double x, long double y);
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric floating_point remquo (arithmetic x, arithmetic y, int* pquo);
2650b57cec5SDimitry Andric float          remquof(float x, float y, int* pquo);
2660b57cec5SDimitry Andric long double    remquol(long double x, long double y, int* pquo);
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric floating_point rint (arithmetic x);
2690b57cec5SDimitry Andric float          rintf(float x);
2700b57cec5SDimitry Andric long double    rintl(long double x);
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric floating_point round (arithmetic x);
2730b57cec5SDimitry Andric float          roundf(float x);
2740b57cec5SDimitry Andric long double    roundl(long double x);
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric floating_point scalbln (arithmetic x, long ex);
2770b57cec5SDimitry Andric float          scalblnf(float x, long ex);
2780b57cec5SDimitry Andric long double    scalblnl(long double x, long ex);
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric floating_point scalbn (arithmetic x, int ex);
2810b57cec5SDimitry Andric float          scalbnf(float x, int ex);
2820b57cec5SDimitry Andric long double    scalbnl(long double x, int ex);
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric floating_point tgamma (arithmetic x);
2850b57cec5SDimitry Andric float          tgammaf(float x);
2860b57cec5SDimitry Andric long double    tgammal(long double x);
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric floating_point trunc (arithmetic x);
2890b57cec5SDimitry Andric float          truncf(float x);
2900b57cec5SDimitry Andric long double    truncl(long double x);
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric */
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric #  include <__config>
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2970b57cec5SDimitry Andric #    pragma GCC system_header
2980b57cec5SDimitry Andric #  endif
2990b57cec5SDimitry Andric 
300bdd1243dSDimitry Andric #  if __has_include_next(<math.h>)
3010b57cec5SDimitry Andric #    include_next <math.h>
302bdd1243dSDimitry Andric #  endif
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric #  ifdef __cplusplus
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric // We support including .h headers inside 'extern "C"' contexts, so switch
3070b57cec5SDimitry Andric // back to C++ linkage before including these C++ headers.
3080b57cec5SDimitry Andric extern "C++" {
3090b57cec5SDimitry Andric 
310bdd1243dSDimitry Andric #    ifdef fpclassify
311bdd1243dSDimitry Andric #      undef fpclassify
312bdd1243dSDimitry Andric #    endif
313bdd1243dSDimitry Andric 
314bdd1243dSDimitry Andric #    ifdef signbit
315bdd1243dSDimitry Andric #      undef signbit
316bdd1243dSDimitry Andric #    endif
317bdd1243dSDimitry Andric 
318bdd1243dSDimitry Andric #    ifdef isfinite
319bdd1243dSDimitry Andric #      undef isfinite
320bdd1243dSDimitry Andric #    endif
321bdd1243dSDimitry Andric 
322bdd1243dSDimitry Andric #    ifdef isinf
323bdd1243dSDimitry Andric #      undef isinf
324bdd1243dSDimitry Andric #    endif
325bdd1243dSDimitry Andric 
326bdd1243dSDimitry Andric #    ifdef isnan
327bdd1243dSDimitry Andric #      undef isnan
328bdd1243dSDimitry Andric #    endif
329bdd1243dSDimitry Andric 
330bdd1243dSDimitry Andric #    ifdef isnormal
331bdd1243dSDimitry Andric #      undef isnormal
332bdd1243dSDimitry Andric #    endif
333bdd1243dSDimitry Andric 
334bdd1243dSDimitry Andric #    ifdef isgreater
335bdd1243dSDimitry Andric #      undef isgreater
336bdd1243dSDimitry Andric #    endif
337bdd1243dSDimitry Andric 
338bdd1243dSDimitry Andric #    ifdef isgreaterequal
339bdd1243dSDimitry Andric #      undef isgreaterequal
340bdd1243dSDimitry Andric #    endif
341bdd1243dSDimitry Andric 
342bdd1243dSDimitry Andric #    ifdef isless
343bdd1243dSDimitry Andric #      undef isless
344bdd1243dSDimitry Andric #    endif
345bdd1243dSDimitry Andric 
346bdd1243dSDimitry Andric #    ifdef islessequal
347bdd1243dSDimitry Andric #      undef islessequal
348bdd1243dSDimitry Andric #    endif
349bdd1243dSDimitry Andric 
350bdd1243dSDimitry Andric #    ifdef islessgreater
351bdd1243dSDimitry Andric #      undef islessgreater
352bdd1243dSDimitry Andric #    endif
353bdd1243dSDimitry Andric 
354bdd1243dSDimitry Andric #    ifdef isunordered
355bdd1243dSDimitry Andric #      undef isunordered
356bdd1243dSDimitry Andric #    endif
3570b57cec5SDimitry Andric 
3585f757f3fSDimitry Andric #    include <__math/abs.h>
3595f757f3fSDimitry Andric #    include <__math/copysign.h>
3605f757f3fSDimitry Andric #    include <__math/error_functions.h>
3615f757f3fSDimitry Andric #    include <__math/exponential_functions.h>
3625f757f3fSDimitry Andric #    include <__math/fdim.h>
3635f757f3fSDimitry Andric #    include <__math/fma.h>
3645f757f3fSDimitry Andric #    include <__math/gamma.h>
3655f757f3fSDimitry Andric #    include <__math/hyperbolic_functions.h>
3665f757f3fSDimitry Andric #    include <__math/hypot.h>
3675f757f3fSDimitry Andric #    include <__math/inverse_hyperbolic_functions.h>
3685f757f3fSDimitry Andric #    include <__math/inverse_trigonometric_functions.h>
3695f757f3fSDimitry Andric #    include <__math/logarithms.h>
3705f757f3fSDimitry Andric #    include <__math/min_max.h>
3715f757f3fSDimitry Andric #    include <__math/modulo.h>
3725f757f3fSDimitry Andric #    include <__math/remainder.h>
3735f757f3fSDimitry Andric #    include <__math/roots.h>
3745f757f3fSDimitry Andric #    include <__math/rounding_functions.h>
3755f757f3fSDimitry Andric #    include <__math/traits.h>
3765f757f3fSDimitry Andric #    include <__math/trigonometric_functions.h>
3775f757f3fSDimitry Andric #    include <__type_traits/enable_if.h>
3785f757f3fSDimitry Andric #    include <__type_traits/is_floating_point.h>
3795f757f3fSDimitry Andric #    include <__type_traits/is_integral.h>
3805f757f3fSDimitry Andric #    include <stdlib.h>
3810b57cec5SDimitry Andric 
3825f757f3fSDimitry Andric // fpclassify relies on implementation-defined constants, so we can't move it to a detail header
3835f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
3840b57cec5SDimitry Andric 
3855f757f3fSDimitry Andric namespace __math {
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric // fpclassify
3880b57cec5SDimitry Andric 
3895f757f3fSDimitry Andric // template on non-double overloads to make them weaker than same overloads from MSVC runtime
3905f757f3fSDimitry Andric template <class = int>
fpclassify(float __x)3915f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(float __x) _NOEXCEPT {
3925f757f3fSDimitry Andric   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
3935f757f3fSDimitry Andric }
3945f757f3fSDimitry Andric 
3955f757f3fSDimitry Andric template <class = int>
fpclassify(double __x)3965f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(double __x) _NOEXCEPT {
3975f757f3fSDimitry Andric   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
3985f757f3fSDimitry Andric }
3995f757f3fSDimitry Andric 
4005f757f3fSDimitry Andric template <class = int>
fpclassify(long double __x)4015f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(long double __x) _NOEXCEPT {
402bdd1243dSDimitry Andric   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
405bdd1243dSDimitry Andric template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value, int> = 0>
fpclassify(_A1 __x)406bdd1243dSDimitry Andric _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
407bdd1243dSDimitry Andric   return __x == 0 ? FP_ZERO : FP_NORMAL;
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
4105f757f3fSDimitry Andric } // namespace __math
4115f757f3fSDimitry Andric 
4125f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_STD
4135f757f3fSDimitry Andric 
4145f757f3fSDimitry Andric using std::__math::fpclassify;
4155f757f3fSDimitry Andric using std::__math::signbit;
4165f757f3fSDimitry Andric 
417bdd1243dSDimitry Andric // The MSVC runtime already provides these functions as templates
418bdd1243dSDimitry Andric #    ifndef _LIBCPP_MSVCRT
4195f757f3fSDimitry Andric using std::__math::isfinite;
4205f757f3fSDimitry Andric using std::__math::isgreater;
4215f757f3fSDimitry Andric using std::__math::isgreaterequal;
4225f757f3fSDimitry Andric using std::__math::isinf;
4235f757f3fSDimitry Andric using std::__math::isless;
4245f757f3fSDimitry Andric using std::__math::islessequal;
4255f757f3fSDimitry Andric using std::__math::islessgreater;
4265f757f3fSDimitry Andric using std::__math::isnan;
4275f757f3fSDimitry Andric using std::__math::isnormal;
4285f757f3fSDimitry Andric using std::__math::isunordered;
429bdd1243dSDimitry Andric #    endif // _LIBCPP_MSVCRT
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric // abs
4325ffd83dbSDimitry Andric //
4335ffd83dbSDimitry Andric // handled in stdlib.h
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric // div
4365ffd83dbSDimitry Andric //
4375ffd83dbSDimitry Andric // handled in stdlib.h
4380b57cec5SDimitry Andric 
439bdd1243dSDimitry Andric // We have to provide double overloads for <math.h> to work on platforms that don't provide the full set of math
440bdd1243dSDimitry Andric // functions. To make the overload set work with multiple functions that take the same arguments, we make our overloads
441bdd1243dSDimitry Andric // templates. Functions are preferred over function templates during overload resolution, which means that our overload
442bdd1243dSDimitry Andric // will only be selected when the C library doesn't provide one.
443bdd1243dSDimitry Andric 
4445f757f3fSDimitry Andric using std::__math::acos;
445cb14a3feSDimitry Andric using std::__math::acosh;
4465f757f3fSDimitry Andric using std::__math::asin;
447cb14a3feSDimitry Andric using std::__math::asinh;
4485f757f3fSDimitry Andric using std::__math::atan;
4495f757f3fSDimitry Andric using std::__math::atan2;
450cb14a3feSDimitry Andric using std::__math::atanh;
4515f757f3fSDimitry Andric using std::__math::cbrt;
4525f757f3fSDimitry Andric using std::__math::ceil;
4535f757f3fSDimitry Andric using std::__math::copysign;
4545f757f3fSDimitry Andric using std::__math::cos;
4555f757f3fSDimitry Andric using std::__math::cosh;
4565f757f3fSDimitry Andric using std::__math::erf;
4575f757f3fSDimitry Andric using std::__math::erfc;
4585f757f3fSDimitry Andric using std::__math::exp;
4595f757f3fSDimitry Andric using std::__math::exp2;
4605f757f3fSDimitry Andric using std::__math::expm1;
4615f757f3fSDimitry Andric using std::__math::fabs;
4625f757f3fSDimitry Andric using std::__math::fdim;
4635f757f3fSDimitry Andric using std::__math::floor;
4645f757f3fSDimitry Andric using std::__math::fma;
4655f757f3fSDimitry Andric using std::__math::fmax;
4665f757f3fSDimitry Andric using std::__math::fmin;
4675f757f3fSDimitry Andric using std::__math::fmod;
4685f757f3fSDimitry Andric using std::__math::frexp;
4695f757f3fSDimitry Andric using std::__math::hypot;
4705f757f3fSDimitry Andric using std::__math::ilogb;
4715f757f3fSDimitry Andric using std::__math::ldexp;
4725f757f3fSDimitry Andric using std::__math::lgamma;
4735f757f3fSDimitry Andric using std::__math::llrint;
4745f757f3fSDimitry Andric using std::__math::llround;
4755f757f3fSDimitry Andric using std::__math::log;
4765f757f3fSDimitry Andric using std::__math::log10;
4775f757f3fSDimitry Andric using std::__math::log1p;
4785f757f3fSDimitry Andric using std::__math::log2;
4795f757f3fSDimitry Andric using std::__math::logb;
480cb14a3feSDimitry Andric using std::__math::lrint;
481cb14a3feSDimitry Andric using std::__math::lround;
4825f757f3fSDimitry Andric using std::__math::modf;
4835f757f3fSDimitry Andric using std::__math::nearbyint;
4845f757f3fSDimitry Andric using std::__math::nextafter;
4855f757f3fSDimitry Andric using std::__math::nexttoward;
4865f757f3fSDimitry Andric using std::__math::pow;
4875f757f3fSDimitry Andric using std::__math::remainder;
4885f757f3fSDimitry Andric using std::__math::remquo;
4895f757f3fSDimitry Andric using std::__math::rint;
4905f757f3fSDimitry Andric using std::__math::round;
4915f757f3fSDimitry Andric using std::__math::scalbln;
4925f757f3fSDimitry Andric using std::__math::scalbn;
4935f757f3fSDimitry Andric using std::__math::signbit;
4945f757f3fSDimitry Andric using std::__math::sin;
4955f757f3fSDimitry Andric using std::__math::sinh;
4965f757f3fSDimitry Andric using std::__math::sqrt;
4975f757f3fSDimitry Andric using std::__math::tan;
4985f757f3fSDimitry Andric using std::__math::tanh;
4995f757f3fSDimitry Andric using std::__math::tgamma;
5005f757f3fSDimitry Andric using std::__math::trunc;
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric } // extern "C++"
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric #  endif // __cplusplus
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric #else // _LIBCPP_MATH_H
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric // This include lives outside the header guard in order to support an MSVC
5090b57cec5SDimitry Andric // extension which allows users to do:
5100b57cec5SDimitry Andric //
5110b57cec5SDimitry Andric // #define _USE_MATH_DEFINES
5120b57cec5SDimitry Andric // #include <math.h>
5130b57cec5SDimitry Andric //
5140b57cec5SDimitry Andric // and receive the definitions of mathematical constants, even if <math.h>
5150b57cec5SDimitry Andric // has previously been included.
5160b57cec5SDimitry Andric #  if defined(_LIBCPP_MSVCRT) && defined(_USE_MATH_DEFINES)
5170b57cec5SDimitry Andric #    include_next <math.h>
5180b57cec5SDimitry Andric #  endif
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric #endif // _LIBCPP_MATH_H
521