-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[libc++] Make sure flat_{multi}map::key_compare handle boolean-testable correctly
#132621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
flat_map:: key_compare handle boolean-testable correctlyflat_map::key_compare handle boolean-testable correctly
|
@llvm/pr-subscribers-libcxx Author: Hewill Kang (hewillk) ChangesThis is sibling of #69378. Full diff: https://github.com/llvm/llvm-project/pull/132621.diff 1 Files Affected:
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index a0594ed9dc411..2f32497ab20d3 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -846,7 +846,7 @@ class flat_map {
__compare_(std::forward<_CompArg>(__comp)...) {}
_LIBCPP_HIDE_FROM_ABI bool __is_sorted_and_unique(auto&& __key_container) const {
- auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); };
+ auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) -> bool { return !__compare_(__x, __y); };
return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
}
@@ -870,7 +870,7 @@ class flat_map {
auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
auto __append_start_offset = __containers_.keys.size() - __num_of_appended;
auto __end = __zv.end();
- auto __compare_key = [this](const auto& __p1, const auto& __p2) {
+ auto __compare_key = [this](const auto& __p1, const auto& __p2) -> bool {
return __compare_(std::get<0>(__p1), std::get<0>(__p2));
};
if constexpr (!_WasSorted) {
|
flat_map::key_compare handle boolean-testable correctlyflat_{multi}map::key_compare handle boolean-testable correctly
|
|
||
| _LIBCPP_HIDE_FROM_ABI bool __is_sorted_and_unique(auto&& __key_container) const { | ||
| auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; | ||
| auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) -> bool { return !__compare_(__x, __y); }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's expected that decltype(__compare_(__x, __y)) already model boolean-testable (or even is exactly bool in most normal usages).
If the standard were already so requiring, we wouldn't need to change these lambdas. But I haven't found such a requirement...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I was likely to be wrong. But are such conversions already performed in algorithms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I was likely to be wrong. But are such conversions already performed in algorithms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. It's the nature of lambda expression without trailing return type that unfortunately decay-copies the result.
Perhaps there should be some test cases for this, with types in boolean_testable.h reused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps there should be some test cases for this, with types in
boolean_testable.hreused?
I don't have a local repository for llvm, co-working is welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recalled that the current standard wording doesn't actually require the result type of Predicate of erase_if for flat_meow to model boolean-testable. The boolean-testablity requirements seem only imposed for erase_if for sequence containers.
For flat_meow, the current wording uses explicit cast to bool. So should we use bool(__compare_(...)) instead, or open an LWG issue for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recalled that the current standard wording doesn't actually require the result type of
Predicateoferase_ifforflat_meowto modelboolean-testable. The boolean-testablity requirements seem only imposed forerase_iffor sequence containers.
I mainly referred to https://eel.is/c++draft/algorithms#requirements-6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recalled that the current standard wording doesn't actually require the result type of
Predicateoferase_ifforflat_meowto modelboolean-testable. The boolean-testablity requirements seem only imposed forerase_iffor sequence containers.I mainly referred to https://eel.is/c++draft/algorithms#requirements-6
I meant that such requirement doesn't seem properly propagated to erase_if for non-sequence containers and container adaptors. (And possibly hive?)
- For
basic_string,deque,inplace_vector, andvector, the requirements are propagated via equivalent-to code that usesstd::remove_if. - For
forward_listandlist, the requirements are propagated via [forward.list.ops], [list.ops] and equivalent-to code that uses memberremove_if.
But for other containers and container adaptors, there doesn't seem such requirement propagation. For hive it's quite weird that [hive.operations] propagates the requirements, but erase_if isn't in that subclause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for other containers and container adaptors, there doesn't seem such requirement propagation. For
hiveit's quite weird that [hive.operations] propagates the requirements, buterase_ifisn't in that subclause.
In any case, std::erase_if can be argued to be an algorithm.
"When not otherwise constrained, the Predicate parameter is used whenever an algorithm expects a function object..." should also apply IMHO.
ldionne
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add tests similarly to what we do in libcxx/test/std/algorithms/ranges_robust_against_nonbool.compile.pass.cpp?
No problem, I can handle this when I have the time . |
|
thanks for the patch. if you are not familiar with libc++ tests, i can certainly help with the testing for this patch. let me know if you want me to add the test to your branch |
|
@huixie90 Would you be able to make the testing changes here? |
|
Added Unit Tests to your branch |
libcxx/test/std/containers/container.adaptors/flat.map/robust_against_nonbool.compile.pass.cpp
Outdated
Show resolved
Hide resolved
…against_nonbool.compile.pass.cpp Co-authored-by: A. Jiang <de34@live.cn>
This is sibling of #69378.