123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #pragma once
- #include <cmath>
- #if (defined(__ANDROID__) && __ANDROID_API__ < 21 && defined(__GLIBCXX__)) || \
- defined(__NEWLIB__)
- #include <stdexcept>
- namespace std {
- using ::acosh;
- using ::asinh;
- using ::atanh;
- using ::erf;
- using ::erfc;
- using ::expm1;
- using ::lgamma;
- using ::log1p;
- using ::nearbyint;
- using ::round;
- using ::tgamma;
- using ::trunc;
- using ::truncf;
- inline float acosh(float x) {
- return __builtin_acoshf(x);
- }
- inline float asinh(float x) {
- return __builtin_asinhf(x);
- }
- inline float atanh(float x) {
- return __builtin_atanhf(x);
- }
- inline float copysign(float x, float y) {
- return __builtin_copysignf(x, y);
- }
- inline float erf(float x) {
- return __builtin_erff(x);
- }
- inline float erfc(float x) {
- return __builtin_erfcf(x);
- }
- inline float expm1(float x) {
- return __builtin_expm1f(x);
- }
- inline float fmax(float x, float y) {
- return __builtin_fmaxf(x, y);
- }
- inline float fmin(float x, float y) {
- return __builtin_fminf(x, y);
- }
- inline float lgamma(float x) {
- return __builtin_lgammaf(x);
- }
- inline float log1p(float x) {
- return __builtin_log1pf(x);
- }
- inline float nearbyint(float x) {
- return __builtin_nearbyintf(x);
- }
- inline float remainder(float x, float y) {
- return __builtin_remainderf(x, y);
- }
- inline float round(float x) {
- return __builtin_roundf(x);
- }
- inline float tgamma(float x) {
- return __builtin_tgammaf(x);
- }
- inline float trunc(float x) {
- return __builtin_truncf(x);
- }
- inline float nexttoward(float x, long double y) {
- throw std::runtime_error("std::nexttoward is not present on older Android");
- }
- inline double nexttoward(double x, long double y) {
- throw std::runtime_error("std::nexttoward is not present on older Android");
- }
- #if !defined(__NEWLIB__)
- inline float hypot(float x, float y) {
- throw std::runtime_error("std::hypot is not implemented on older Android");
- }
- inline double hypot(double x, double y) {
- throw std::runtime_error("std::hypot is not implemented on older Android");
- }
- #else
- inline float hypot(float x, float y) {
- return hypot((double)x, (double)y);
- }
- #endif
- inline float igamma(float x, float y) {
- throw std::runtime_error("igamma is not implemented on older Android");
- }
- inline double igamma(double x, double y) {
- throw std::runtime_error("igamma is not implemented on older Android");
- }
- inline float igammac(float x, float y) {
- throw std::runtime_error("igammac is not implemented on older Android");
- }
- inline double igammac(double x, double y) {
- throw std::runtime_error("igammac is not implemented on older Android");
- }
- inline bool signbit(float x) {
- return x < 0;
- }
- inline bool signbit(double x) {
- return x < 0;
- }
- inline bool signbit(long double x) {
- return x < 0;
- }
- #if !defined(__NEWLIB__)
- inline float nextafter(float x, float y) {
- throw std::runtime_error(
- "std::nextafter is not implemented on older Android");
- }
- inline double nextafter(double x, double y) {
- throw std::runtime_error(
- "std::nextafter is not implemented on older Android");
- }
- #else
- inline float nextafter(float x, float y) {
- return nextafter((double)x, (double)y);
- }
- #endif
- #if !defined(__NEWLIB__)
- inline float exp2(float x) {
- throw std::runtime_error("std::exp2 is not implemented on older Android");
- }
- inline double exp2(double x) {
- throw std::runtime_error("std::exp2 is not implemented on older Android");
- }
- #else
- inline float exp2(float x) {
- return exp2((double)x);
- }
- #endif
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type acosh(T x) {
- return __builtin_acosh(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type asinh(T x) {
- return __builtin_asinh(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type atanh(T x) {
- return __builtin_atanh(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type erf(T x) {
- return __builtin_erf(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type erfc(T x) {
- return __builtin_erfc(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type expm1(T x) {
- return __builtin_expm1(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type lgamma(T x) {
- return __builtin_lgamma(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type log1p(T x) {
- return __builtin_log1p(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type nearbyint(
- T x) {
- return __builtin_nearbyint(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type round(T x) {
- return __builtin_round(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type tgamma(T x) {
- return __builtin_tgamma(x);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type trunc(T x) {
- return __builtin_trunc(x);
- }
- template <typename T, typename U>
- typename __gnu_cxx::__promote_2<T, U>::__type fmax(T x, U y) {
- typedef typename __gnu_cxx::__promote_2<T, U>::__type type;
- return fmax(type(x), type(y));
- }
- template <typename T, typename U>
- typename __gnu_cxx::__promote_2<T, U>::__type fmin(T x, U y) {
- typedef typename __gnu_cxx::__promote_2<T, U>::__type type;
- return fmin(type(x), type(y));
- }
- template <typename T, typename U>
- typename __gnu_cxx::__promote_2<T, U>::__type copysign(T x, U y) {
- typedef typename __gnu_cxx::__promote_2<T, U>::__type type;
- return copysign(type(x), type(y));
- }
- template <typename T, typename U>
- typename __gnu_cxx::__promote_2<T, U>::__type remainder(T x, U y) {
- typedef typename __gnu_cxx::__promote_2<T, U>::__type type;
- return remainder(type(x), type(y));
- }
- inline float log2(float arg) {
- return ::log(arg) / ::log(2.0);
- }
- #if !defined(__NEWLIB__)
- inline double log2(double arg) {
- return ::log(arg) / ::log(2.0);
- }
- #endif
- inline long double log2(long double arg) {
- return ::log(arg) / ::log(2.0);
- }
- template <typename T>
- typename std::enable_if<std::is_integral<T>::value, double>::type log2(T x) {
- return ::log(x) / ::log(2.0);
- }
- }
- #endif
|