Skip to content

Instantly share code, notes, and snippets.

@pnck
Created December 15, 2018 10:38
Show Gist options
  • Save pnck/e15224ae64f0126a54bbad2994af9043 to your computer and use it in GitHub Desktop.
Save pnck/e15224ae64f0126a54bbad2994af9043 to your computer and use it in GitHub Desktop.
a compile-time set type with elements unique check
#include <tuple>
using ElementType = size_t;
template<ElementType ... es>
class SetValidator {
protected:
static inline constexpr auto cs_ = std::make_tuple(es...);
template<size_t _i, size_t _j>
static constexpr bool cmp_() {
if constexpr (_j == _i) {
return false;
} else {
return std::get<_i>(cs_) == std::get<_j>(cs_);
}
}
template<size_t _i, size_t ... Indices>
static constexpr bool is_unique() {
if constexpr ((0 || ... || cmp_<_i, Indices>())) {
return false;
} else {
return true;
}
}
template<size_t ... I>
static constexpr bool helper(std::index_sequence<I...>) {
if constexpr ((1 && ... && is_unique<I, I...>())) {
return true;
} else {
return false;
}
}
public:
static constexpr bool valid() {
return helper(std::make_index_sequence<sizeof...(es)>{});
}
};
template<ElementType ... es>
class RawSet : public SetValidator<es...> {};
template<ElementType ... es>
struct RawNSet : public SetValidator<es...> {}; // negative set, exlude elements
template<typename T, bool _ = T::valid()> struct NiceSetError;
template<template<ElementType ...> class SetType, ElementType ...es>
struct NiceSetError<SetType<es...>, false> {
static constexpr auto try_() {
static_assert(SetType<es...>::valid(), "there is dupplicated elements");
return SetType<es...>{};
};
using type = decltype(try_());
};
template<template<ElementType ...> class SetType, ElementType ...es>
struct NiceSetError<SetType<es...>, true> {
using type = SetType<es...>;
};
template<ElementType ... es>
using Set = typename NiceSetError<RawSet<es...>>::type;
template<ElementType ... es>
using NSet = typename NiceSetError<RawNSet<es...>>::type;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment