//Standard C++ math declarations

#pragma once

#include <math.h>

// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
#undef asin
#undef atan
#undef atan2
#undef ceil
#undef cos
#undef cosh
#undef exp
#undef fabs
#undef floor
#undef fmod
#undef frexp
#undef ldexp
#undef log
#undef log10
#undef modf
#undef pow
#undef sin
#undef sinh
#undef sqrt
#undef tan
#undef tanh

namespace std
{
  // Forward declaration of a helper function.  This really should be
  // an `exported' forward declaration.
  template<typename _Tp>
    _Tp __cmath_power(_Tp, unsigned int);

  template<typename _Tp>
    inline _Tp
    __pow_helper(_Tp __x, int __n)
    {
      return __n < 0
        ? _Tp(1)/__cmath_power(__x, -__n)
        : __cmath_power(__x, __n);
    }

  inline double
  abs(double __x)
  { return fabs(__x); }

  inline float
  abs(float __x)
  { return fabsf(__x); }

  inline long double
  abs(long double __x)
  { return fabsl(__x); }

  using ::acos;

  inline float
  acos(float __x)
  { return acosf(__x); }

  inline long double
  acos(long double __x)
  { return acosl(__x); }

  using ::asin;

  inline float
  asin(float __x)
  { return asinf(__x); }

  inline long double
  asin(long double __x)
  { return asinl(__x); }

  using ::atan;

  inline float
  atan(float __x)
  { return atanf(__x); }

  inline long double
  atan(long double __x)
  { return atanl(__x); }

  using ::atan2;

  inline float
  atan2(float __y, float __x)
  { return atan2f(__y, __x); }

  inline long double
  atan2(long double __y, long double __x)
  { return atan2l(__y, __x); }

  using ::ceil;

  inline float
  ceil(float __x)
  { return ceilf(__x); }

  inline long double
  ceil(long double __x)
  { return ceill(__x); }

  using ::cos;

  inline float
  cos(float __x)
  { return cosf(__x); }

  inline long double
  cos(long double __x)
  { return cosl(__x); }

  using ::cosh;

  inline float
  cosh(float __x)
  { return coshf(__x); }

  inline long double
  cosh(long double __x)
  { return coshl(__x); }

  using ::exp;

  inline float
  exp(float __x)
  { return expf(__x); }

  inline long double
  exp(long double __x)
  { return expl(__x); }

  using ::fabs;

  inline float
  fabs(float __x)
  { return fabsf(__x); }

  inline long double
  fabs(long double __x)
  { return fabsl(__x); }

  using ::floor;

  inline float
  floor(float __x)
  { return floorf(__x); }

  inline long double
  floor(long double __x)
  { return floorl(__x); }

  using ::fmod;

  inline float
  fmod(float __x, float __y)
  { return fmodf(__x, __y); }

  inline long double
  fmod(long double __x, long double __y)
  { return fmodl(__x, __y); }

  using ::frexp;

  inline float
  frexp(float __x, int* __exp)
  { return frexpf(__x, __exp); }

  inline long double
  frexp(long double __x, int* __exp)
  { return frexpl(__x, __exp); }

  using ::ldexp;

  inline float
  ldexp(float __x, int __exp)
  { return ldexpf(__x, __exp); }

  inline long double
  ldexp(long double __x, int __exp)
  { return ldexpl(__x, __exp); }

  using ::log;

  inline float
  log(float __x)
  { return logf(__x); }

  inline long double
  log(long double __x)
  { return logl(__x); }

  using ::log10;

  inline float
  log10(float __x)
  { return log10f(__x); }

  inline long double
  log10(long double __x)
  { return log10l(__x); }

  using ::modf;

  inline float
  modf(float __x, float* __iptr)
  { return modff(__x, __iptr); }

  inline long double
  modf(long double __x, long double* __iptr)
  { return modfl(__x, __iptr); }

  using ::pow;

  inline float
  pow(float __x, float __y)
  { return powf(__x, __y); }

  inline long double
  pow(long double __x, long double __y)
  { return powl(__x, __y); }

  inline double
  pow(double __x, int __i)
  { return pow(__x, static_cast<double>(__i)); }

  inline float
  pow(float __x, int __n)
  { return powf(__x, static_cast<float>(__n)); }

  inline long double
  pow(long double __x, int __n)
  { return powl(__x, static_cast<long double>(__n)); }

  using ::sin;

  inline float
  sin(float __x)
  { return sinf(__x); }

  inline long double
  sin(long double __x)
  { return sinl(__x); }

  using ::sinh;

  inline float
  sinh(float __x)
  { return sinhf(__x); }

  inline long double
  sinh(long double __x)
  { return sinhl(__x); }

  using ::sqrt;

  inline float
  sqrt(float __x)
  { return sqrtf(__x); }

  inline long double
  sqrt(long double __x)
  { return sqrtl(__x); }

  using ::tan;

  inline float
  tan(float __x)
  { return tanf(__x); }

  inline long double
  tan(long double __x)
  { return tanl(__x); }

  using ::tanh;

  inline float
  tanh(float __x)
  { return tanhf(__x); }

  inline long double
  tanh(long double __x)
  { return tanhl(__x); }
}
