Date: Sun, 24 Sep 2023 16:05:38 +0200
Il giorno gio 7 set 2023 alle ore 23:56 Ben Crowhurst via
Std-Proposals <std-proposals_at_[hidden]> ha scritto:
>
> We propose a new range of conditional operators for C++:
>
> * [^] one-of
> * [&] all-of
> * [|] any-of
> * [!] none-of
[...]
For my own needs I came up with a "any_of" using template
metaprogramming, which allows one to write something like:
if (x == any_of(a, b, c)) { /*...*/ }
Where a, b and c are instances of potentially heterogeneous types.
Right now only operator== is implemented, that's what I needed, but
it's trivial to implement all the others, and following the same
pattern it's easy to see how to implement one_of, all_off, none_of as
well.
Here's the code (I am sure you guys will find many ways to improve upon it):
#include <type_traits>
#include <tuple>
template <typename T, typename U, typename = void>
struct equality_comparable: std::false_type{};
template <typename T, typename U>
struct equality_comparable<T, U, std::void_t<
decltype(std::declval<T>() == std::declval<U>(),
std::declval<U>() == std::declval<T>())>
> : std::true_type{};
template <typename... Ts>
struct any_of: std::tuple<Ts...> {
using std::tuple<Ts...>::tuple;
template <typename T>
constexpr bool operator ==(const T &rhs) const {
return impl(rhs, std::make_index_sequence<sizeof...(Ts)>());
}
private:
template <typename T, std::size_t... Is>
constexpr bool impl(const T &v, const std::index_sequence<Is...>&) const
{
auto check = [&v](const auto &e) {
using E = std::decay_t<decltype(e)>;
if constexpr (equality_comparable<T, E>::value) {
return v == e;
}
else {
return false;
}
};
return (check(std::get<Is>(*this)) || ...);
}
};
template <typename... Ts>
any_of(Ts &&... ts) -> any_of<Ts...>;
template <typename T, typename... Us>
constexpr bool operator==(T &&lhs, const any_of<Us...> &rhs)
{
return rhs == lhs;
}
It seems to be working fine, but comments and corrections are greatly welcome.
I'd love to see something like this standardized, however the names in
std:: are already taken. What do you guys say?
Fabio
Std-Proposals <std-proposals_at_[hidden]> ha scritto:
>
> We propose a new range of conditional operators for C++:
>
> * [^] one-of
> * [&] all-of
> * [|] any-of
> * [!] none-of
[...]
For my own needs I came up with a "any_of" using template
metaprogramming, which allows one to write something like:
if (x == any_of(a, b, c)) { /*...*/ }
Where a, b and c are instances of potentially heterogeneous types.
Right now only operator== is implemented, that's what I needed, but
it's trivial to implement all the others, and following the same
pattern it's easy to see how to implement one_of, all_off, none_of as
well.
Here's the code (I am sure you guys will find many ways to improve upon it):
#include <type_traits>
#include <tuple>
template <typename T, typename U, typename = void>
struct equality_comparable: std::false_type{};
template <typename T, typename U>
struct equality_comparable<T, U, std::void_t<
decltype(std::declval<T>() == std::declval<U>(),
std::declval<U>() == std::declval<T>())>
> : std::true_type{};
template <typename... Ts>
struct any_of: std::tuple<Ts...> {
using std::tuple<Ts...>::tuple;
template <typename T>
constexpr bool operator ==(const T &rhs) const {
return impl(rhs, std::make_index_sequence<sizeof...(Ts)>());
}
private:
template <typename T, std::size_t... Is>
constexpr bool impl(const T &v, const std::index_sequence<Is...>&) const
{
auto check = [&v](const auto &e) {
using E = std::decay_t<decltype(e)>;
if constexpr (equality_comparable<T, E>::value) {
return v == e;
}
else {
return false;
}
};
return (check(std::get<Is>(*this)) || ...);
}
};
template <typename... Ts>
any_of(Ts &&... ts) -> any_of<Ts...>;
template <typename T, typename... Us>
constexpr bool operator==(T &&lhs, const any_of<Us...> &rhs)
{
return rhs == lhs;
}
It seems to be working fine, but comments and corrections are greatly welcome.
I'd love to see something like this standardized, however the names in
std:: are already taken. What do you guys say?
Fabio
Received on 2023-09-24 14:05:51