Skip to content

Instantly share code, notes, and snippets.

@derrickturk
Created March 11, 2014 20:42
Show Gist options
  • Save derrickturk/9494559 to your computer and use it in GitHub Desktop.
Save derrickturk/9494559 to your computer and use it in GitHub Desktop.
Good lord. Can we please have recursive access to function template names in -> decltype(...) and function template partial specialization for C++14? I'm tired of writing stupid traits/impl class templates.
#include <iostream>
#include "tpow.hpp"
int main()
{
static_assert(noexcept(tpow<5>(5)), "tpow<int, N> not noexcept");
std::cout << "5^5 = " << tpow<5>(5) << '\n';
static_assert(noexcept(tpow<4>(2.3)), "tpow<double, N> not noexcept");
std::cout << "2.3^4 = " << tpow<4>(2.3) << '\n';
}
#ifndef TPOW_HPP
#include <utility>
#include <type_traits>
namespace {
template<unsigned N, class T>
struct pow_traits {
using pow_type =
decltype(std::declval<T>()
* std::declval<typename pow_traits<N-1, T>::pow_type>());
constexpr static bool is_noexcept = noexcept(std::declval<T>()
* std::declval<typename pow_traits<N-1, T>::pow_type>());
static constexpr pow_type pow_impl(const T& x) noexcept(is_noexcept)
{
return x * pow_traits<N-1, T>::pow_impl(x);
}
};
template<class T>
struct pow_traits<1, T> {
using pow_type = typename std::remove_reference<T>::type;
constexpr static bool is_noexcept = noexcept(T(std::declval<T>()));
static constexpr pow_type pow_impl(const T& x) noexcept(is_noexcept)
{
return x;
}
};
template<class T>
struct pow_traits<0, T> {
// deliberately empty
};
}
template<unsigned N, class T>
inline constexpr
typename pow_traits<N, T>::pow_type tpow(const T& x)
noexcept(pow_traits<N, T>::is_noexcept)
{
return pow_traits<N, T>::pow_impl(x);
}
#define TPOW_HPP
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment