Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#include <iostream>
#include <type_traits>
#include <string>
// primality test
template<int N, int M>
struct divides
{
enum { value = ((N%M) == 0) || divides<N, M-1>::value };
};
template<int N>
struct divides<N, 1>
{
enum { value = 0 };
};
template<int N>
struct is_prime
{
enum { value = divides<N, N-1>::value == 0 };
};
template<> struct is_prime<0> { enum { value = 0 }; };
template<> struct is_prime<1> { enum { value = 0 }; };
// fibonacci test
template<int N1, int N2, int M, bool done>
struct fib_check
{
enum { fib = N1+N2, value = (M == fib) || fib_check<N2,fib,M,(fib>M)>::value };
};
template<int N1, int N2, int M>
struct fib_check<N1, N2, M, true>
{
enum { value = 0 };
};
template<int N>
struct is_fib
{
enum { value = N == 0 || fib_check<0, 1, N, false>::value };
};
template<int>
struct fib_type { typedef std::string type; };
template<>
struct fib_type<1> { typedef int type; };
// fibonacci type check
template<int N, class... T>
struct typecheck;
template<int N, class T, class... Rest>
struct typecheck<N, T, Rest...>
{
enum { value =
std::is_convertible<T, typename fib_type<is_fib<N>::value>::type>::value &&
typecheck<N+1, Rest...>::value };
};
template<int N> struct typecheck<N> { enum { value = 1 }; };
// and finally function
template<class... T>
void fun(T... args)
{
static_assert(is_prime<sizeof...(T)>::value, "must have a prime number of args!");
static_assert(typecheck<0, T...>::value, "type mismatch");
}
int main()
{
// some valid calls
fun(0,1);
fun(0,1,2,3,"four");
fun(0,1,2,3,"four",5,"six","seven",8,"nine","ten");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment