// GMP extra and inexact operations
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Warning: GNU GMP C++ is licensed under GPL/LGPL.
//
// Angelos Mantzaflaris, 2015-2016

#ifndef EIGEN_MPQCLASSEXTRA_MODULE_H
#define EIGEN_MPQCLASSEXTRA_MODULE_H

#include <cmath>

inline bool isfinite(const mpq_class&) { return true; }
inline bool isinf(const mpq_class&)    { return false; }
inline bool isnan(const mpq_class&)    { return false; }

template <class U, class V>
inline mpq_class (max)(const __gmp_expr<mpq_t, U> & a,
                       const __gmp_expr<mpq_t, V> & b)
{return mpq_class(a < b ? b : a);}

template <class U, class V>
inline mpq_class (min)(const __gmp_expr<mpq_t, U> & a,
                       const __gmp_expr<mpq_t, V> & b)
{return mpq_class(a < b ? a : b);}

template <class U, class Z> inline
mpq_class pow(const __gmp_expr<mpq_t, U> & a, const Z & b)
{return std::pow(mpq_class(a).get_d(), b);}

#define GMP_EXTRA_STD_UNARY_FUNCTION(std_fun) template <class U> \
inline mpq_class std_fun(const __gmp_expr<mpq_t, U> & expr)      \
{return std::std_fun(mpq_class(expr).get_d());}
#define GMP_EXTRA_STD_BINARY_FUNCTION(std_fun) template <class U, class V>              \
inline mpq_class std_fun(const __gmp_expr<mpq_t, U> & a,const __gmp_expr<mpq_t, V> & b) \
{return std::std_fun(mpq_class(a).get_d(), mpq_class(b).get_d());}
GMP_EXTRA_STD_UNARY_FUNCTION (sqrt )
GMP_EXTRA_STD_UNARY_FUNCTION (exp  )
GMP_EXTRA_STD_UNARY_FUNCTION (log  )
GMP_EXTRA_STD_UNARY_FUNCTION (floor)
GMP_EXTRA_STD_UNARY_FUNCTION (ceil )
GMP_EXTRA_STD_BINARY_FUNCTION(pow  )
GMP_EXTRA_STD_UNARY_FUNCTION (sin  )
GMP_EXTRA_STD_UNARY_FUNCTION (asin )
GMP_EXTRA_STD_UNARY_FUNCTION (sinh )
GMP_EXTRA_STD_UNARY_FUNCTION (cos  )
GMP_EXTRA_STD_UNARY_FUNCTION (acos )
GMP_EXTRA_STD_UNARY_FUNCTION (cosh )
GMP_EXTRA_STD_UNARY_FUNCTION (tan  )
GMP_EXTRA_STD_UNARY_FUNCTION (atan )
GMP_EXTRA_STD_UNARY_FUNCTION (tanh )
GMP_EXTRA_STD_BINARY_FUNCTION(atan2)
#undef GMP_EXTRA_STD_UNARY_FUNCTION
#undef GMP_EXTRA_STD_BINARY_FUNCTION

#endif
