Can I play too?
The following is my solution, heavely based on partial template specialization.
#include <iostream>
using IType = int; // or long? or unsigned? or size_t?
template <typename IT, IT ...>
struct intSeq
{ };
template <typename, typename, std::size_t>
struct no_more_than_val;
template <typename IT, IT I0, std::size_t M, IT Val, IT ... Is>
struct no_more_than_val<intSeq<IT, I0, Is...>, intSeq<IT, Val>, M>
{ static constexpr bool value
{ no_more_than_val<intSeq<IT, Is...>, intSeq<IT, Val>, M>::value }; };
template <typename IT, IT Val, std::size_t M, IT ... Is>
struct no_more_than_val<intSeq<IT, Val, Is...>, intSeq<IT, Val>, M>
{ static constexpr bool value
{ no_more_than_val<intSeq<IT, Is...>, intSeq<IT, Val>, M-1U>::value }; };
template <typename IT, IT I0, IT ... Is>
struct no_more_than_val<intSeq<IT, I0, Is...>, intSeq<IT, I0>, 0U>
{ static constexpr bool value { false }; };
template <typename IT, std::size_t M, IT Val>
struct no_more_than_val<intSeq<IT>, intSeq<IT, Val>, M>
{ static constexpr bool value { true }; };
template <typename, std::size_t>
struct no_more_than_list;
template <typename IT, std::size_t M>
struct no_more_than_list<intSeq<IT>, M>
{ static constexpr bool value { true }; };
template <typename IT, IT I0, IT ... Is>
struct no_more_than_list<intSeq<IT, I0, Is...>, 0U>
{ static constexpr bool value { false }; };
template <typename IT, std::size_t M, IT I0, IT ... Is>
struct no_more_than_list<intSeq<IT, I0, Is...>, M>
{
static constexpr bool value
{ no_more_than_val<intSeq<IT, Is...>, intSeq<IT, I0>, M-1U>::value
&& no_more_than_list<intSeq<IT, Is...>, M>::value };
};
template <IType ... Is>
struct appearance
: public no_more_than_list<intSeq<IType, Is...>, 2U>
{ };
int main()
{
std::cout << appearance<0,1,0,1>::value << std::endl; // print 1
std::cout << appearance<2,0,1,2,2>::value << std::endl; // print 0
std::cout << appearance<5,5,5>::value << std::endl; // print 0
}
If you can use C++14, you can use std::integer_sequence
instead of intSeq
. Anyway, you can use std::integral_constant<IT, Val>
instead of intSeq<IT, Val>
.