[libcxx-commits] [PATCH] D116268: [libc++][ranges] Add indirectly_comparable concept
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Dec 26 13:48:35 PST 2021
Quuxplusone added inline comments.
================
Comment at: libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.compile.pass.cpp:18-19
+
+#include "__iterator/readable_traits.h"
+#include "indirectly_readable.h"
+#include "test_iterators.h"
----------------
philnik wrote:
> Quuxplusone wrote:
> > Direct inclusion of `<__iterator/readable_traits.h>` will fail the modules build.
> > I've never seen `libcxx/test/support/indirectly_readable.h` before but it looks crazy complicated; can we avoid using it here? I think all you actually need for this test would be something like
> > ```
> > struct Deref {
> > int operator()(int*) const;
> > };
> >
> > static_assert(!std::indirectly_comparable<int, int, std::less<int>>); // not dereferenceable
> > static_assert(!std::indirectly_comparable<int*, int*, int>); // not a predicate
> > static_assert( std::indirectly_comparable<int*, int*, std::less<int>>);
> > static_assert(!std::indirectly_comparable<int**, int*, std::less<int>>);
> > static_assert( std::indirectly_comparable<int**, int*, std::less<int>, Deref>);
> > static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, Deref, Deref>);
> > static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, std::identity, Deref>);
> > static_assert( std::indirectly_comparable<int*, int**, std::less<int>, std::identity, Deref>);
> > ```
> > And then a subsumption test in each direction:
> > ```
> > template<class F> requires std::indirectly_comparable<int*, char*, F> && true
> > constexpr bool subsumes(F f) { return true; }
> >
> > template<class F> requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>>
> > void subsumes(F f);
> >
> > template<class F> requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>> && true
> > constexpr bool is_subsumed(F f) { return true; }
> >
> > template<class F> requires std::indirectly_comparable<int*, char*, F>
> > void is_subsumed(F f);
> >
> > static_assert(subsumes(std::less<int>()));
> > static_assert(is_subsumed(std::less<int>()));
> > ```
> > https://godbolt.org/z/c9rEh8e8c
> Why does it make a difference if there is the `&& true` at the end? Is there some "this has more requirements, so it must be stricter"?
Yep. See circa 20m–35m in my ["Concepts As She Is Spoke"](https://www.youtube.com/watch?v=CXn02MPkn8Y) (CppCon 2018). The idea here is that `subsumes #2` is constrained by a bunch of stuff, and then `subsumes #1` is constrained by all that same stuff plus one additional atomic constraint of "`true` (line 1, column 73)." So `subsumes #1` is strictly more constrained.
Note that Concepts does //not// treat the keywords `true` and `false` as magic.
FWIW, I find the linebreak positions on lines 30–31 and 39–40 to be weird. Doesn't really matter, though.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D116268/new/
https://reviews.llvm.org/D116268
More information about the libcxx-commits
mailing list