-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[libc++][flat_multimap] Applied [[nodiscard]]
#169986
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?
[libc++][flat_multimap] Applied [[nodiscard]]
#169986
Conversation
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. - https://libcxx.llvm.org/CodingGuidelines.htm - https://wg21.link/map
|
@llvm/pr-subscribers-libcxx Author: Hristo Hristov (H-G-Hristov) Changes
Full diff: https://github.com/llvm/llvm-project/pull/169986.diff 2 Files Affected:
diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h
index 6a608723da1ba..3db669066ba97 100644
--- a/libcxx/include/__flat_map/flat_multimap.h
+++ b/libcxx/include/__flat_map/flat_multimap.h
@@ -408,41 +408,45 @@ class flat_multimap {
}
// iterators
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
return iterator(__containers_.keys.begin(), __containers_.values.begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
return iterator(__containers_.keys.end(), __containers_.values.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
return const_iterator(__containers_.keys.end(), __containers_.values.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
return reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
return reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
+ return begin();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
+ return end();
+ }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(begin());
}
@@ -451,11 +455,11 @@ class flat_multimap {
return __containers_.keys.empty();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
return __containers_.keys.size();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
}
@@ -578,7 +582,7 @@ class flat_multimap {
insert(sorted_equivalent, __il.begin(), __il.end());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
auto __ret = std::move(__containers_);
return __ret;
@@ -644,118 +648,123 @@ class flat_multimap {
}
// observers
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
return value_compare(__compare_);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
return __containers_.keys;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type&
+ values() const noexcept {
return __containers_.values;
}
// map operations
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
return __find_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
return __find_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
auto [__first, __last] = equal_range(__x);
return __last - __first;
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
auto [__first, __last] = equal_range(__x);
return __last - __first;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
return find(__x) != end();
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
return find(__x) != end();
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
return __lower_bound<iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ lower_bound(const key_type& __x) const {
return __lower_bound<const_iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
return __lower_bound<iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
return __lower_bound<const_iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
return __upper_bound<iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ upper_bound(const key_type& __x) const {
return __upper_bound<const_iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
return __upper_bound<iterator>(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
return __upper_bound<const_iterator>(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const key_type& __x) {
return __equal_range_impl(*this, __x);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
+ equal_range(const _Kp& __x) {
return __equal_range_impl(*this, __x);
}
template <class _Kp>
requires __is_compare_transparent
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const _Kp& __x) const {
return __equal_range_impl(*this, __x);
}
diff --git a/libcxx/test/libcxx/diagnostics/flat_multimap.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/flat_multimap.nodiscard.verify.cpp
index 9b7b827c9bec8..66d6c99aed70c 100644
--- a/libcxx/test/libcxx/diagnostics/flat_multimap.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/flat_multimap.nodiscard.verify.cpp
@@ -6,17 +6,97 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: std-at-least-c++23
// <flat_map>
-// class flat_multimap
-
-// [[nodiscard]] bool empty() const noexcept;
+// Check that functions are marked [[nodiscard]]
#include <flat_map>
+#include <utility>
+
+template <typename T>
+struct TransparentKey {
+ T t;
+
+ constexpr explicit operator T() const { return t; }
+};
+
+struct TransparentCompare {
+ using is_transparent = void; // This makes the comparator transparent
+
+ template <typename T>
+ constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const {
+ return t < transparent.t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const {
+ return transparent.t < t;
+ }
+
+ template <typename T>
+ constexpr bool operator()(const T& t1, const T& t2) const {
+ return t1 < t2;
+ }
+};
+
+void test() {
+ std::flat_multimap<int, int, TransparentCompare> mm;
+ const std::flat_multimap<int, int, TransparentCompare> cmm;
+
+ mm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ cmm.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.keys(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.values(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ int key = 0;
+ TransparentKey<int> tkey;
+
+ mm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ mm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-void f() {
- std::flat_multimap<int, int> c;
- c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ mm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cmm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> | ||
| equal_range(const _Kp& __x) const { | ||
| return __equal_range_impl(*this, __x); | ||
| } |
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.
is there a reason why operator== and <=> are not marked?
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.
The compiler is already issuing a diagnostic, so we decided not to mark the operators.
[[nodiscard]]should be applied to functions where discarding the return value is most likely a correctness issue.