This is a code snippet that I am going to use in order to check whether the variadic template types are unique:
template <typename...>
struct is_one_of;
template <typename F>
struct is_one_of<F> {
static constexpr bool value = false;
};
template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...> {
static constexpr bool value =
std::is_same<F, S>::value || is_one_of<F, T...>::value;
};
template <typename...>
struct is_unique;
template <>
struct is_unique<> {
static constexpr bool value = true;
};
template <typename F, typename... T>
struct is_unique<F, T...> {
static constexpr bool value =
is_unique<T...>::value && !is_one_of<F, T...>::value;
};
int main() {
constexpr bool b = is_unique<bool, int, double>::value;
constexpr bool c = is_unique<int, char, int>::value;
static_assert(b == true && c == false, "!");
}
Is there any way to make this code shorter and/or more concise using features introduced in C++14 and C++1z? Or is there a better way to achieve the same effect using the new features?
In the case of C++1z I mean: features that are already available in the newest versions of Clang and GCC.
We recently added std::disjunction to the C++1z draft, which can be used for is_one_of
(and it stops instantiating as soon as it finds a match, see the link for more details):
template <typename F, typename... T>
using is_one_of = std::disjunction<is_same<F, T>...>;
This is already implemented in GCC trunk. For older versions of GCC you can use the implementation detail __or_
instead:
template <typename F, typename... T>
using is_one_of = std::__or_<is_same<F, T>...>;
Or implement disjunction
by hand using C++11 facilities, as shown at the end of the proposal linked to above.
#include <type_traits>
template <typename F, typename... Ts>
constexpr bool is_one_of = (std::is_same<F, Ts>{} || ...);
template <typename...>
constexpr bool is_unique = true;
template <typename F, typename... Ts>
constexpr bool is_unique<F, Ts...> = is_unique<Ts...> && !is_one_of<F, Ts...>;
DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With