Add ranges::in_in_out_result
Details
- Reviewers
• Quuxplusone Mordante var-const - Group Reviewers
Restricted Project - Commits
- rGf3514af492ee: [libc++][ranges] Add ranges::in_in_out_result
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
36 | The third convertible_to constraint is missing here, which indicates a lack of test coverage. |
LGTM % test comments, but I'll request changes anyway.
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
28–32 | Some whitespace issues here. Ditto below. | |
libcxx/test/std/algorithms/algorithms.results/in_in_out_result.pass.cpp | ||
1 | I don't see a CTAD test. How are we doing CTAD tests for these types? deduct.pass.cpp, or dump it in here, or what? | |
79 | I don't think this buys you anything over a simple std::ranges::in_in_out_result<long, float, int> res2 = res; assert(res2.in1 == 10L); ~~~ (Also, moot point now, but ConstructibleFrom would be the wrong name for something that's implicitly convertible from; ConvertibleFrom would have been a better name.) | |
84–89 | Since it was originally the constraint on _O1 that was missing, I think it makes sense to test all of the positions here. This can be as simple as { std::ranges::in_in_out_result<MoveOnly, int, int> res{MoveOnly(1), 0, 0}; auto res2 = std::ranges::in_in_out_result<MoveOnly, int, int>(std::move(res)); assert(res.in1.get() == 0); // it was moved-from assert(res2.in1.get() == 1); static_assert( std::is_constructible_v<std::ranges::in_in_out_result<MoveOnly, MoveOnly, MoveOnly>, std::ranges::in_in_out_result<int, int, int>&>); static_assert( std::is_move_constructible_v<std::ranges::in_in_out_result<MoveOnly, int, int>>); static_assert( std::is_move_constructible_v<std::ranges::in_in_out_result<int, MoveOnly, int>>); static_assert( std::is_move_constructible_v<std::ranges::in_in_out_result<int, int, MoveOnly>>); // Non-copyability of any element makes the whole thing non-copyable. static_assert(!std::is_copy_constructible_v<std::ranges::in_in_out_result<MoveOnly, int, int>>); static_assert(!std::is_copy_constructible_v<std::ranges::in_in_out_result<int, MoveOnly, int>>); static_assert(!std::is_copy_constructible_v<std::ranges::in_in_out_result<int, int, MoveOnly>>); } | |
90–93 | Please wrap these four lines in { } too, for consistency. |
libcxx/test/std/algorithms/algorithms.results/in_in_out_result.pass.cpp | ||
---|---|---|
1 | This is still unaddressed, right? ASSERT_SAME_TYPE(decltype(std::ranges::in_in_result(1, 'x')), std::ranges::in_in_result<int, char>); ASSERT_SAME_TYPE(decltype(std::ranges::in_in_out_result(1, 'x', 1.f)), std::ranges::in_in_result<int, char, float>); etc. | |
35–42 | FWIW, I think lines 35-36 should just be B(int); — I don't see any realistic way for the behavior to differ between these two overload sets. | |
79 | Ah; consider removing it from both places here or in a followup. :) | |
99 | You can remove [[maybe_unused]] now that the variable is used. (In general, [[maybe_unused]] hides missing assertions, so I'd advise, as a first approximation, never using it.) | |
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
33–35 | I predict this getting cumbersome to read; I'd still rather see == 2 here, and ditto on line 28: basically pre-constant-fold everything we know to be a constant 1. |
In general it looks good but some minor issues.
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
23 | Nit, since there's only one out I would prefer to remove the 1 for the output. That also matches the wording of the Standard. Same for the rest of this header. | |
libcxx/test/std/algorithms/algorithms.results/in_in_out_result.pass.cpp | ||
51 | Do we need to test this? I don't see a requirement the conversion is noexcept(false). | |
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
34 | Based on http://eel.is/c++draft/basic.memobj#intro.object-9 I expect 1 to be an valid answer. Actually I wonder how portable these answers are. The Standard states Two objects … may have the same address is uses may and not shall. This makes sense since compilers are allowed to ignore attributes. So I think this test should be moved from its current location to libcxx/test/libcxx/algorithms/algorithms.results/no_unique_address.compile.pass.cpp |
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
23 | FWIW I'm cool with either way, but you can't use just _O because we don't do that. You could use _Out, I think would be the best option. | |
libcxx/test/std/algorithms/algorithms.results/in_in_out_result.pass.cpp | ||
51 | Good point, libraries are allowed to strengthen noexcept at will. Strike this (and similar lines throughout). | |
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
34 | That's not a test/libcxx/ issue, though; that's a REQUIRES: clang issue! And we handle that by // XFAIL: msvc at the top of this file. So I think that's fine. (The presence of the attribute on the data member itself is mandated for every conforming library, even if the MSVC compiler ignores the attribute.) |
- Remove noexcept checks
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
23 | I made it _O1 to be consistent between in_in_result, in_in_out_result and in_out_out_result. I didn't write in_out_result, so that one is not consistent. |
libcxx/include/__algorithm/in_in_out_result.h | ||
---|---|---|
23 | I think I read there will be some "cleanup" patch to unify all these result types correct? | |
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
34 | I agree the adding of the attribute is required. But there's no portable way to check it since compilers are free to ignore attributes. I also am suspicious of the size of this specific object. Both Clang and GCC agree on 2 and due to ABI I don't expect it to change. But I can't see anything preventing another compiler to decide 1 is a nice size in this case. The two Empty types don't share the same address when sizeof(std::ranges::in_in_out_result<Empty, char, Empty>) == 1 |
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
---|---|---|
34 |
Hmm, I don't think the compiler is permitted to lay out the second Empty object (or any object) at offset 1 if the sizeof the entire thing is also 1. However, I'm also aware that my mental model of [[no_unique_address]] is not yet correct, so I'm not sure you're wrong. |
LGTM!
libcxx/test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp | ||
---|---|---|
34 | Sounds fair. It's at least very unlikely GCC and Clang change, since the change would be an ABI-break. Once MSVC supports [[no_unique_address]] we can evaluate the proper value for their implementation. |
Nit, since there's only one out I would prefer to remove the 1 for the output. That also matches the wording of the Standard. Same for the rest of this header.