Skip to content

Instantly share code, notes, and snippets.

@foonathan

foonathan/concept.cpp

Last active Feb 24, 2021
Embed
What would you like to do?
Prime_number concept
#include <type_traits>
//=== basic integer stuff ==//
template <typename T>
concept bool Integer = requires(T) {typename T::value_type; T::value;};
template <Integer A, typename A::value_type B>
concept bool Equal_to = A::value == B;
template <Integer A, Integer B>
concept bool Equal_integers = A::value == B::value;
template <Integer A, Integer B>
concept bool Dividable_integers = A::value % B::value == 0;
template <Integer A, typename A::value_type B>
concept bool Dividable_by_constant = A::value % B == 0;
template <Integer I>
using increment_by_2 = std::integral_constant<typename I::value_type, I::value + 2>;
//=== actual prime stuff ===//
template <Integer A, Integer B>
concept bool Prime_loop_end = B::value * B::value > A::value; // end condition in divisor check
template <Integer A, Integer B> requires !Prime_loop_end<A, B> && !Dividable_integers<A, B>
concept bool Prime_helper = Prime_helper<A, increment_by_2<B>>; // not finished and no divisor found
template <Integer A, Integer B> requires !Prime_loop_end<A, B> && Dividable_integers<A, B>
concept bool Prime_helper = false; // not finished but divisor found
template <Integer A, Integer B> requires Prime_loop_end<A, B>
concept bool Prime_helper = true; // divisor found
template <Integer I>
concept bool Trivial_prime = Equal_to<I, 2>; // 2 is prime
template <Integer I>
concept bool Trivial_nonprime = Equal_to<I, 1> || Dividable_by_constant<I, 2>; // 1 or even numbers are not prime
template <Integer I>
concept bool Other_prime = Prime_helper<I, std::integral_constant<typename I::value_type, 3>>; // other numbers search divisors
template <Integer I>
concept bool Prime_number = Trivial_prime<I> || (Trivial_nonprime<I> ? false : Other_prime<I>); // actual prime concept
//=== testing ===//
template <int I>
using Int = std::integral_constant<int, I>;
int main()
{
static_assert(Integer<Int<1>>);
static_assert(!Prime_number<Int<1>>);
static_assert( Prime_number<Int<2>>);
static_assert( Prime_number<Int<3>>);
static_assert(!Prime_number<Int<4>>);
static_assert( Prime_number<Int<29>>);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment