C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Manifold comparison operator

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Sun, 24 Sep 2023 17:26:15 +0300
On Sun, 24 Sept 2023 at 17:05, Fabio Alemagna via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> 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.

Beaufiful. But why isn't it using a tuple of references?

> I'd love to see something like this standardized, however the names in
> std:: are already taken. What do you guys say?

Well.. I'm sure there's lots of useful tuple algorithms, but maybe
they should remain
in Boost::Hana, separate from the standard library.

Received on 2023-09-24 14:26:28