Skip to content

Commit 6804808

Browse files
committed
[libc++][flat_multimap] Applied [[nodiscard]]
`[[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
1 parent f5742c4 commit 6804808

File tree

2 files changed

+135
-46
lines changed

2 files changed

+135
-46
lines changed

libcxx/include/__flat_map/flat_multimap.h

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -408,41 +408,45 @@ class flat_multimap {
408408
}
409409

410410
// iterators
411-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
411+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
412412
return iterator(__containers_.keys.begin(), __containers_.values.begin());
413413
}
414414

415-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
415+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
416416
return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
417417
}
418418

419-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
419+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
420420
return iterator(__containers_.keys.end(), __containers_.values.end());
421421
}
422422

423-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
423+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
424424
return const_iterator(__containers_.keys.end(), __containers_.values.end());
425425
}
426426

427-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
427+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
428428
return reverse_iterator(end());
429429
}
430-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
430+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
431431
return const_reverse_iterator(end());
432432
}
433-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
433+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
434434
return reverse_iterator(begin());
435435
}
436-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
436+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
437437
return const_reverse_iterator(begin());
438438
}
439439

440-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
441-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
442-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
440+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
441+
return begin();
442+
}
443+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
444+
return end();
445+
}
446+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
443447
return const_reverse_iterator(end());
444448
}
445-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
449+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
446450
return const_reverse_iterator(begin());
447451
}
448452

@@ -451,11 +455,11 @@ class flat_multimap {
451455
return __containers_.keys.empty();
452456
}
453457

454-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
458+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
455459
return __containers_.keys.size();
456460
}
457461

458-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
462+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
459463
return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
460464
}
461465

@@ -578,7 +582,7 @@ class flat_multimap {
578582
insert(sorted_equivalent, __il.begin(), __il.end());
579583
}
580584

581-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
585+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
582586
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
583587
auto __ret = std::move(__containers_);
584588
return __ret;
@@ -644,118 +648,123 @@ class flat_multimap {
644648
}
645649

646650
// observers
647-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
648-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
651+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
652+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
649653
return value_compare(__compare_);
650654
}
651655

652-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
656+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
653657
return __containers_.keys;
654658
}
655-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept {
659+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type&
660+
values() const noexcept {
656661
return __containers_.values;
657662
}
658663

659664
// map operations
660-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
665+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
661666
return __find_impl(*this, __x);
662667
}
663668

664-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
669+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
665670
return __find_impl(*this, __x);
666671
}
667672

668673
template <class _Kp>
669674
requires __is_compare_transparent
670-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
675+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
671676
return __find_impl(*this, __x);
672677
}
673678

674679
template <class _Kp>
675680
requires __is_compare_transparent
676-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
681+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
677682
return __find_impl(*this, __x);
678683
}
679684

680-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
685+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
681686
auto [__first, __last] = equal_range(__x);
682687
return __last - __first;
683688
}
684689

685690
template <class _Kp>
686691
requires __is_compare_transparent
687-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
692+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
688693
auto [__first, __last] = equal_range(__x);
689694
return __last - __first;
690695
}
691696

692-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
697+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
693698
return find(__x) != end();
694699
}
695700

696701
template <class _Kp>
697702
requires __is_compare_transparent
698-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
703+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
699704
return find(__x) != end();
700705
}
701706

702-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
707+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
703708
return __lower_bound<iterator>(*this, __x);
704709
}
705710

706-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
711+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
712+
lower_bound(const key_type& __x) const {
707713
return __lower_bound<const_iterator>(*this, __x);
708714
}
709715

710716
template <class _Kp>
711717
requires __is_compare_transparent
712-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
718+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
713719
return __lower_bound<iterator>(*this, __x);
714720
}
715721

716722
template <class _Kp>
717723
requires __is_compare_transparent
718-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
724+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
719725
return __lower_bound<const_iterator>(*this, __x);
720726
}
721727

722-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
728+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
723729
return __upper_bound<iterator>(*this, __x);
724730
}
725731

726-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
732+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
733+
upper_bound(const key_type& __x) const {
727734
return __upper_bound<const_iterator>(*this, __x);
728735
}
729736

730737
template <class _Kp>
731738
requires __is_compare_transparent
732-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
739+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
733740
return __upper_bound<iterator>(*this, __x);
734741
}
735742

736743
template <class _Kp>
737744
requires __is_compare_transparent
738-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
745+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
739746
return __upper_bound<const_iterator>(*this, __x);
740747
}
741748

742-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
749+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
750+
equal_range(const key_type& __x) {
743751
return __equal_range_impl(*this, __x);
744752
}
745753

746-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
754+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
747755
equal_range(const key_type& __x) const {
748756
return __equal_range_impl(*this, __x);
749757
}
750758

751759
template <class _Kp>
752760
requires __is_compare_transparent
753-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
761+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
762+
equal_range(const _Kp& __x) {
754763
return __equal_range_impl(*this, __x);
755764
}
756765
template <class _Kp>
757766
requires __is_compare_transparent
758-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
767+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
759768
equal_range(const _Kp& __x) const {
760769
return __equal_range_impl(*this, __x);
761770
}

libcxx/test/libcxx/diagnostics/flat_multimap.nodiscard.verify.cpp

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,97 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9+
// REQUIRES: std-at-least-c++23
1010

1111
// <flat_map>
1212

13-
// class flat_multimap
14-
15-
// [[nodiscard]] bool empty() const noexcept;
13+
// Check that functions are marked [[nodiscard]]
1614

1715
#include <flat_map>
16+
#include <utility>
17+
18+
template <typename T>
19+
struct TransparentKey {
20+
T t;
21+
22+
constexpr explicit operator T() const { return t; }
23+
};
24+
25+
struct TransparentCompare {
26+
using is_transparent = void; // This makes the comparator transparent
27+
28+
template <typename T>
29+
constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const {
30+
return t < transparent.t;
31+
}
32+
33+
template <typename T>
34+
constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const {
35+
return transparent.t < t;
36+
}
37+
38+
template <typename T>
39+
constexpr bool operator()(const T& t1, const T& t2) const {
40+
return t1 < t2;
41+
}
42+
};
43+
44+
void test() {
45+
std::flat_multimap<int, int, TransparentCompare> mm;
46+
const std::flat_multimap<int, int, TransparentCompare> cmm;
47+
48+
mm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
49+
cmm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
50+
mm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
51+
cmm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
52+
53+
mm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
54+
cmm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
55+
mm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
56+
cmm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
57+
58+
cmm.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
59+
cmm.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
60+
cmm.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
61+
cmm.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
62+
63+
mm.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
64+
mm.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
65+
mm.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
66+
67+
mm.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
68+
mm.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
69+
mm.keys(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
70+
mm.values(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
71+
72+
int key = 0;
73+
TransparentKey<int> tkey;
74+
75+
mm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
76+
cmm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
77+
mm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
78+
cmm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
79+
80+
mm.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
81+
mm.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
82+
83+
mm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
84+
cmm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
85+
mm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
86+
cmm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
87+
88+
mm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
89+
cmm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
90+
mm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
91+
cmm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
92+
93+
mm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
94+
cmm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
95+
mm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
96+
cmm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1897

19-
void f() {
20-
std::flat_multimap<int, int> c;
21-
c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
98+
mm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
99+
cmm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
100+
mm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
101+
cmm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
22102
}

0 commit comments

Comments
 (0)