Implement P1425R4
Details
- Reviewers
• Quuxplusone ldionne Mordante - Group Reviewers
Restricted Project - Commits
- rGf3aed3698185: [libc++] Implement P1425R4 (Iterator pair constructors for std::stack and std…
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks for your contribution! It still needs some more work.
libcxx/include/queue | ||
---|---|---|
77 | This deduction guide has also been added. A quick scan it seems there are more deduction guides not added to the synopsis. | |
261 | Can you move the new constructors to this location, that seems more consistent. | |
libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp | ||
42 | I miss a test to validate the queue has the expected values. | |
44 | The deduction guides should be their own test, queue.cons/deduct.pass.cpp already contains test for the deduction guides, please add them there. | |
libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp | ||
29 | I think it would be good to test all elements in the queue to have the expected value. | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp | ||
42 | I miss a test to validate the queue has the expected values. | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp | ||
28 | I think it would be good to test all elements in the queue to have the expected value. |
- Added deduction guides to synopsis
- Moved queue constructors
- Moved deduction guide tests
- Checking elements
Thanks, this looks good, except for the style not matching the style of the surrounding code.
libcxx/include/queue | ||
---|---|---|
55 | Nits: please indent to match the surrounding style, and please last); // since C++23 (although I see you're aligning the comments, I don't think it's beneficial here). Also, please shuffle the order of these new constructors to match what's in the paper and/or Standard synopsis. The (first, last) one should be circa line 44, and the (first, last, const Alloc&) one down here. | |
81–83 | Here and line 79 also, please indent the second line by 2 spaces to match the surrounding style. | |
libcxx/include/stack | ||
188 | Ditto below. | |
libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp | ||
31–32 | ||
libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp | ||
25 | Testing that std::queue{it, it} produces a queue of ints rather than a queue of iterators is a good test, but it belongs in deduct.pass.cpp, not here. In this file, you should focus on the non-CTAD happy path, std::queue<int>(a.begin(), a.end()). Keep it simple: const int a[] = {4, 3, 2, 1}; std::queue<int> queue(a, a+4); assert(queue.front() == 4); // etc. | |
libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp | ||
159–164 ↗ | (On Diff #395297) | Let's use std::list<int> as our type here, since we do that above. Also, let's match the style of surrounding code. { typedef short T; typedef test_allocator<T> Alloc; std::list<T> source; { std::queue que(source.begin(), source.end()); static_assert(std::is_same_v<decltype(que), std::queue<T>>); } { std::queue que(source.begin(), source.end(), Alloc(2)); static_assert(std::is_same_v<decltype(que), std::queue<T, std::deque<T, Alloc>>>); } } |
libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp | ||
42 | I miss variable names that make it clear that the thing under test here is not a queue. ;) | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp | ||
163–168 ↗ | (On Diff #395297) | Same comments here as on the queue deduct.pass.cpp. |
libcxx/include/queue | ||
---|---|---|
390–397 | Yipes, almost missed this, except that the failing CI alerted me. All these deduction guides need to use __enable_if_t to disable themselves when _InputIterator is not an iterator or _Alloc is not an allocator. Look at the guides for deque or priority_queue and do as they do. Please also add some SFINAES_away tests to deduct.pass.cpp proving that the deduction guides indeed SFINAE away in those cases. |
libcxx/include/queue | ||
---|---|---|
267 | Does this overload need , __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0 similar to the below overloads? I suspect it does. (And then please add a regression test. The regression test will use SFINAE but not CTAD.) | |
390–397 | Please follow the pattern on lines 385–397 above (and in e.g. <vector>, which I assume is more or less where you copied these particular constraints from): template<class _InputIterator, class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > queue(_InputIterator, _InputIterator) -> queue<__iter_value_type<_InputIterator>>; template<class _InputIterator, class _Alloc, class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, class = enable_if_t<__is_allocator<_Alloc>::value> > queue(_InputIterator, _InputIterator, _Alloc) -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; Both for consistency, and because _LIBCPP_HAS_NO_CONCEPTS is still a thing. | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp | ||
24 | iter should now be just const int*, which means you don't need the typedef. | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp | ||
28–31 | This is okay, but personally I'd rather see lines 25,27,28,29,30 replaced with assert(stack.top() == 1); stack.pop(); assert(stack.top() == 2); stack.pop(); assert(stack.top() == 3); stack.pop(); assert(stack.top() == 4); stack.pop(); assert(stack.empty()); and then you can remove the include of <ranges>. And similarly in the queue test: assert(queue.front() == 4); queue.pop(); assert(queue.front() == 3); queue.pop(); assert(queue.front() == 2); queue.pop(); assert(queue.front() == 1); queue.pop(); assert(queue.empty()); | |
libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp | ||
19 ↗ | (On Diff #395315) | This can be removed again now. Ditto in queue.cons/ctor_iterators.pass.cpp. |
159 ↗ | (On Diff #395315) | Throw in <std::stack, NotIter, Iter> while you're here. |
libcxx/include/queue | ||
---|---|---|
267 | Actually even (hand-rolled) SFINAE is unnecessary. A regression test for this could be as simple as static_assert(!std::is_constructible_v<std::queue<int>, int, int, std::allocator<int>>); static_assert(!std::is_constructible_v<std::queue<int>, int*, int*, int>); static_assert( std::is_constructible_v<std::queue<int, std::deque<int, test_allocator<int>>>, int, int, test_allocator<int>>); static_assert(!std::is_constructible_v<std::queue<int, std::deque<int, test_allocator<int>>>, int, int, std::allocator<int>>); and likewise for stack. (Preemptive whitespace advice: These lines are long, but I wouldn't break them.) |
Getting there! Definitely wait for buildkite to be back online and green before landing this, though, because I can totally imagine buildkite not liking it.
libcxx/include/queue | ||
---|---|---|
219 | Why all of <memory>? (Same question below in stack.) | |
219 | Here and <stack>, <version> should be included now. | |
265 | Please linebreak before queue, for consistency. (Here and line 283, and presumably also in stack) | |
393 | ||
399–400 | ||
libcxx/include/stack | ||
259–268 | Please follow the enable_if_t pattern here as well. |
I haven't finished reviewing this in full yet, but do we need to use enable_if_t instead of concepts/requires since this is C++23 code? I.e. is our requirement of using older AppleClang version in C++23 mode an issue with this (and therefore we must use enable_if_t still)? The consistency argument is fine - I'm asking purely from a technical standpoint.
I think it could also be guarded with _LIBCPP_HAS_NO_CONCEPTS. libc++ still supports compilers where concepts are not working.
If you want it to be present in -std=c++2b mode, on old compilers without full concepts support, then it can't depend on full concepts support (although technically maybe those old compilers support enough of concepts that a simple requires-clause would be OK... but let's not go down that rabbit hole, let's just wait a couple more years). If you guard it under _LIBCPP_HAS_NO_CONCEPTS, then it won't be present on old compilers without full concepts support, so I don't think that would be a good idea either. Finally, you could provide two different implementations — one under _LIBCPP_HAS_NO_CONCEPTS and one not — but that would be twice the work, and require going down a rabbit hole involving "twice the tests," so let's not do that either.
libcxx/include/queue | ||
---|---|---|
82 | ||
219 | stack still includes <memory>; it probably shouldn't, right? | |
271 | This line shouldn't be here; and please add a regression test if possible. int a[10] = {}; std::pmr::queue<int> q(a, a+10, std::pmr::new_delete_resource()); // should be OK except that that'll be hard to put in a test since we don't support std::pmr. :P The deduction guides are appropriately constrained so that (if they don't take a Container parameter) Alloc must be an allocator; but the constructors are not so constrained. https://wg21.link/p1518r1 is related. | |
libcxx/include/stack | ||
195 | and regression-test |
IIRC the only compiler using _LIBCPP_HAS_NO_CONCEPTS is AppleClang. Unfortunately our CI isn't running the latest AppleClang yet so we need to support not concept builds.
LGTM, just make sure the Apple build failure isn't due to your changes.
CI failed with the same problems in D116691, so I don't think they are related to this patch.
The span.cons/initializer_list.pass.cpp failure is my fault, and I believe I just fixed it in 570ed38b6e387644c38561e0cb019c94d7b5c0bb. Feel free to poke CI again if you want, but I don't think it's necessary — I mean, if CI is "green except for span.cons/initializer_list.pass.cpp" on your most recent diff, then you can feel free to treat that as green.
Nits: please indent to match the surrounding style, and please last); // since C++23 (although I see you're aligning the comments, I don't think it's beneficial here).
Also, please shuffle the order of these new constructors to match what's in the paper and/or Standard synopsis. The (first, last) one should be circa line 44, and the (first, last, const Alloc&) one down here.