[libcxx-commits] [PATCH] D114761: [libc++][ranges] Implement [special.mem.concepts].
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Dec 1 08:10:10 PST 2021
Quuxplusone added inline comments.
================
Comment at: libcxx/test/std/algorithms/specialized.algorithms/special.mem.concepts/special.mem.concepts.compile.pass.cpp:38-42
+template <typename T = int>
+struct InputIterator_Proxy : MoveOnly, Incrementable<InputIterator_Proxy<T>>, HasIteratorConcept<> {
+ using value_type = T;
+ value_type operator*() const;
+};
----------------
var-const wrote:
> Quuxplusone wrote:
> > I believe this should be more like https://godbolt.org/z/PTce8axh5 :
> > ```
> > bool is_nothrow_input_iterator(std::ranges::__nothrow_input_iterator auto) { return true; }
> > bool is_nothrow_input_iterator(std::input_iterator auto) { return false; }
> >
> > int main() {
> > assert(!is_nothrow_input_iterator(InputIt{}));
> > assert(is_nothrow_input_iterator(NothrowInputIt{}));
> > }
> > ```
> > Also please take the `NothrowInputIt` and `InputIt` from that godbolt; they're pretty minimal.
> What's the advantage of using these functions? They add a layer of abstraction and, AFAICT, make this a runtime test rather than a compile-time test. Also, why define a custom `InputIt` when `test_iterators.h` already contains suitable classes?
Overloading like this is the pattern for testing subsumption relationships. The Standard says that If you have an overload set where one overload is constrained on `__nothrow_input_iterator` and another is constrained only on `input_iterator`, they won't be ambiguous overloads. So in general, when a subsumption relationship is mandated, we ought to have a test following this pattern somewhere.
However, in writing this comment, I realized that the Stupid C++ Trick I was thinking this enabled, isn't even legal. I was thinking that a sufficiently evil user could write https://godbolt.org/z/E4WT434xa
```
struct NotDC {
NotDC(int) {}
void uninitialized_default_construct(std::ranges::forward_range auto&& r) {}
};
int main() {
NotDC a[3] = {1, 2, 3};
using std::ranges::uninitialized_default_construct;
uninitialized_default_construct(a);
}
```
But in fact subsumption is completely irrelevant to that code. It won't work because `std::ranges::uninitialized_default_construct` is a niebloid and so there is no overload set here at all. Conclusion: the subsumption relationship //is// mandated, but I no longer think that any user could possibly observe it, so we probably don't need to test it.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D114761/new/
https://reviews.llvm.org/D114761
More information about the libcxx-commits
mailing list