GuillaumeDua / CppShelf

Collection of powerfuls - C++ Single-Header Libraries Files
https://guillaumedua.github.io/CppShelf/
MIT License
9 stars 1 forks source link

[mp] unique, duplicates #208

Open GuillaumeDua opened 6 months ago

GuillaumeDua commented 6 months ago

Update: see https://github.com/fmtlib/fmt/pull/2457#issuecomment-904129006 for a most efficient algorithm (avoid full lookup)


template <typename ... ttps>
struct has_duplicates : std::bool_constant<
    (false and ... and (count_v<ttps, ttps...> not_eq 1))
>{};
template <typename ... ttps>
constexpr auto has_duplicates_v = has_duplicates<ttps...>::value;

With unique == not has_duplicates

or - plain API -

template <typename T, typename... ttps>
struct count : std::integral_constant<std::size_t, (std::size_t{0} + ... + std::size_t{std::is_same_v<T, ttps>})> {};
template <typename T, template <typename...> typename pack, typename... ttps>
struct count<T, pack<ttps...>> : count<T, ttps...> {};
template <typename T, typename... ttps>
constexpr std::size_t count_v = count<T, ttps...>::value;

template <typename... Ts>
struct has_duplicates : std::bool_constant<(false or ... or (count_v<Ts, pack<Ts...>> not_eq 1))>{};

naming: has_duplicates -> is_unique

template <typename... Ts>
struct is_unique : std::bool_constant<(true and ... and (count_v<Ts, pack<Ts...>> == 1))>{};
template<typename... Ts>
constexpr inline static bool is_unique_v = is_unique<Ts...>::value;

template <typename... Ts>
struct has_duplicates : std::negation<is_unique<Ts...>>{};
template<typename... Ts>
constexpr inline static bool has_duplicates_v = has_duplicates<Ts...>::value;

demo: https://godbolt.org/z/s3Kceznzn