vendredi 30 juin 2017

Statically assert that variadic template's nested value is unique

I have a class that receive variadic templates of the same type. Each of these types have a nested value that should be unique:

template <SomeEnum _se, int _val>
struct Pack
{
  enum {val_se = _se};
  enum {val = _val};
};

int main()
{
  TypeMe<Pack<A_SE, 1>, Pack<B_SE, 2>, Pack<C_SE, 3>> tm_abc; // OK
  TypeMe<Pack<A_SE, 1>, Pack<B_SE, 2>, Pack<A_SE, 3>> tm_aba; // Should fail (first and last Pack are templated with A_SE)

  (void)tm_abc;
  (void)tm_aba;
  return (0);
}

The entire test code :

#include <cstdio>

template <typename ... ArgPacks>
class TypeMe
{
public:
  TypeMe();
private:
  template <typename ... APs>
  void cycleAPs();

  template <typename AP>
  void cycleAP();
};

template <typename ... ArgPacks>
TypeMe<ArgPacks...>::TypeMe()
{
  // Maybe the static assertion should go here
  cycleAPs<ArgPacks...>();
}

template <typename ... ArgPacks>
template <typename ... APs>
void TypeMe<ArgPacks...>::cycleAPs()
{
  int _[] = {0, (cycleAP<APs>(), 0)...};
  (void)_;
  return ;
}

template <typename ... ArgPacks>
template <typename AP>
void TypeMe<ArgPacks...>::cycleAP()
{
  printf("SomeEnum = %d, Val = %d\n", static_cast<int>(AP::val_se), AP::val);
  return ;
}

enum SomeEnum
{
  A_SE,
  B_SE,
  C_SE,
  MAX
};

template <SomeEnum _se, int _val>
struct Pack
{
  enum {val_se = _se};
  enum {val = _val};
};

int main()
{
  TypeMe<Pack<A_SE, 1>, Pack<B_SE, 2>, Pack<C_SE, 3>> tm_abc; // OK
  TypeMe<Pack<A_SE, 1>, Pack<B_SE, 2>, Pack<A_SE, 3>> tm_aba; // Should fail (first and last Pack are templated with A_SE)

  (void)tm_abc;
  (void)tm_aba;
  return (0);
}

Is there a way, in C++0x, to check at compile time that each of the Pack::val_se are different ? or with C++11 ?

Thanks for reading

Aucun commentaire:

Enregistrer un commentaire