Skip to content

Instantly share code, notes, and snippets.

@shardator
Created March 16, 2022 16:31
Show Gist options
  • Save shardator/1d71526ebc5887452d475bea13be9282 to your computer and use it in GitHub Desktop.
Save shardator/1d71526ebc5887452d475bea13be9282 to your computer and use it in GitHub Desktop.
C++ Metaprogrammed GCD
namespace detail {
template<size_t M, size_t N>
struct gcd_impl {
static constexpr size_t R = (N == 0) ? 0 : (M % N);
static constexpr size_t value = (R == 0) ? N : gcd_impl<N,R>::value;
};
template<size_t M> struct gcd_impl<M,0> { static constexpr size_t value = M; };
template<size_t N> struct gcd_impl<0,N> { static constexpr size_t value = 0; };
template<> struct gcd_impl<0,0> { static constexpr size_t value = 0; };
template<size_t M, size_t N>
struct gcd_2 {
static constexpr size_t value1 = (M > N) ? M : N;
static constexpr size_t value2 = (M == value1) ? N : M;
static constexpr size_t value = detail::gcd_impl<value1,value2>::value;
};
} // namespace detail
template<size_t... rest>
struct gcd {};
template<size_t M, size_t N, size_t... rest>
struct gcd<M,N,rest...> {
static constexpr size_t value = gcd<detail::gcd_2<M,N>::value, rest...>::value;
};
template<size_t M, size_t N>
struct gcd<M,N> : public detail::gcd_2<M,N> {};
template<size_t M>
struct gcd<M> { static constexpr size_t value = M; };
template<size_t... rest>
static constexpr size_t gcd_v = gcd<rest...>::value;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment