Info
-
Did you know that C++20's
no_unique_address
can be used to find unique types?
Example
template<class> struct box{};
struct unique {
[[no_unique_address]] box<int> _1;
[[no_unique_address]] box<bool> _2;
};
static_assert(sizeof(unique)==1);
struct no_unique {
[[no_unique_address]] box<int> _1;
[[no_unique_address]] box<int> _2;
};
static_assert(sizeof(no_unique)!=1);
Puzzle
- Can you implement generic version of
is_unique
leveraging described concept?
template <class... Ts>
constexpr auto is_unique = false; // TODO
static_assert(is_unique<int, bool, char, double, float>);
static_assert(not is_unique<int, bool, char, double, float, int>);
Solutions
template <class T> struct box {};
template <class... Ts> struct unique;
template <>
struct unique<> {};
template <class T, class ...Args>
struct unique<T, Args ...> : public unique<Args ...> {
constexpr explicit unique(T&& t, Args&&... args) : unique<Args...>(args ...) {
}
[[no_unique_address]] box<T> t_;
};
template <class... Ts>
constexpr auto is_unique = (sizeof(unique<Ts...>) == 1);
template <class>
struct box {
box() = delete;
};
template <class... Ts>
struct S;
template <>
struct S<> {};
template <class T, class... Ts>
struct S<T, Ts...> : S<Ts...> {
[[no_unique_address]] box<T> _;
};
template <class... Ts>
constexpr auto is_unique = sizeof(S<Ts...>) == 1;