29 #ifndef PIRANHA_POW_HPP 30 #define PIRANHA_POW_HPP 34 #include <type_traits> 37 #include <piranha/mp_integer.hpp> 51 template <
typename T,
typename U,
typename =
void>
60 template <
typename T,
typename U>
61 using pow_fp_arith_enabler
62 = enable_if_t<conjunction<std::is_arithmetic<T>, std::is_arithmetic<U>,
63 disjunction<std::is_floating_point<T>, std::is_floating_point<U>>>::value>;
74 template <
typename T,
typename U>
75 struct pow_impl<T, U, pow_fp_arith_enabler<T, U>> {
85 auto operator()(
const T &x,
const U &y)
const -> decltype(std::pow(x, y))
87 return std::pow(x, y);
96 template <
typename T,
typename U>
97 using math_pow_t_ = decltype(math::pow_impl<T, U>{}(std::declval<const T &>(), std::declval<const U &>()));
99 template <
typename T,
typename U>
100 using math_pow_t = enable_if_t<is_returnable<math_pow_t_<T, U>>::value, math_pow_t_<T, U>>;
125 template <
typename T,
typename U>
126 inline math_pow_t<T, U>
pow(
const T &x,
const U &y)
132 inline namespace impl
136 template <
typename T,
typename U>
137 using integer_pow_enabler
138 = enable_if_t<disjunction<conjunction<is_mp_integer<T>, mppp::mppp_impl::is_supported_interop<U>>,
139 conjunction<is_mp_integer<U>, mppp::mppp_impl::is_supported_interop<T>>,
140 conjunction<std::is_integral<T>, std::is_integral<U>>, is_same_mp_integer<T, U>>::value>;
143 template <
typename T,
typename U>
144 inline auto mp_integer_pow_wrapper(
const T &base,
const U &exp) -> decltype(pow(base, exp))
146 return pow(base, exp);
170 template <
typename T,
typename U>
174 template <
typename T2,
typename U2,
175 enable_if_t<conjunction<std::is_integral<T2>, std::is_integral<U2>>::value,
int> = 0>
176 static integer impl(
const T2 &b,
const U2 &e)
178 return mp_integer_pow_wrapper(
integer{b}, e);
181 template <
typename T2,
typename U2,
182 enable_if_t<negation<conjunction<std::is_integral<T2>, std::is_integral<U2>>>::value,
int> = 0>
183 static auto impl(
const T2 &b,
const U2 &e) -> decltype(mp_integer_pow_wrapper(b, e))
185 return mp_integer_pow_wrapper(b, e);
187 using ret_type = decltype(impl(std::declval<const T &>(), std::declval<const U &>()));
206 inline namespace impl
210 template <
typename Base,
typename Expo>
211 using pow_t = decltype(
math::pow(std::declval<const Base &>(), std::declval<const Expo &>()));
219 template <
typename T,
typename U>
222 static const bool implementation_defined = is_detected<pow_t, T, U>::value;
226 static const bool value = implementation_defined;
230 template <
typename T,
typename U>
math_pow_t< T, U > pow(const T &x, const U &y)
Exponentiation.
Multiprecision integer class.
Type trait for exponentiable types.
Default functor for the implementation of piranha::math::pow().
static const bool value
Value of the type trait.
ret_type operator()(const T &b, const U &e) const
Call operator.
auto operator()(const T &x, const U &y) const -> decltype(std::pow(x, y))
Call operator.