Last active
February 24, 2021 00:31
-
-
Save foonathan/c4af6a66384dcd25bd19 to your computer and use it in GitHub Desktop.
Prime_number concept
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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