Skip to content

Commit df80612

Browse files
authored
[libc++][flat_set] Applied [[nodiscard]] (#169739)
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. - https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant
1 parent 682f292 commit df80612

File tree

3 files changed

+135
-43
lines changed

3 files changed

+135
-43
lines changed

libcxx/include/__flat_set/flat_set.h

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -339,38 +339,42 @@ class flat_set {
339339
}
340340

341341
// iterators
342-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
342+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
343343
return iterator(std::as_const(__keys_).begin());
344344
}
345-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
345+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
346346
return const_iterator(__keys_.begin());
347347
}
348-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
348+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
349349
return iterator(std::as_const(__keys_).end());
350350
}
351-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
351+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
352352
return const_iterator(__keys_.end());
353353
}
354354

355-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
355+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
356356
return reverse_iterator(end());
357357
}
358-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
358+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
359359
return const_reverse_iterator(end());
360360
}
361-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
361+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
362362
return reverse_iterator(begin());
363363
}
364-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
364+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
365365
return const_reverse_iterator(begin());
366366
}
367367

368-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
369-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
370-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
368+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
369+
return begin();
370+
}
371+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
372+
return end();
373+
}
374+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
371375
return const_reverse_iterator(end());
372376
}
373-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
377+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
374378
return const_reverse_iterator(begin());
375379
}
376380

@@ -379,9 +383,13 @@ class flat_set {
379383
return __keys_.empty();
380384
}
381385

382-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); }
386+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
387+
return __keys_.size();
388+
}
383389

384-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); }
390+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
391+
return __keys_.max_size();
392+
}
385393

386394
// [flat.set.modifiers], modifiers
387395
template <class... _Args>
@@ -466,7 +474,7 @@ class flat_set {
466474
insert(sorted_unique, __il.begin(), __il.end());
467475
}
468476

469-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
477+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
470478
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
471479
auto __ret = std::move(__keys_);
472480
return __ret;
@@ -528,111 +536,117 @@ class flat_set {
528536
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }
529537

530538
// observers
531-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
532-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; }
539+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
540+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
541+
return __compare_;
542+
}
533543

534544
// set operations
535-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
545+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
536546
return __find_impl(*this, __x);
537547
}
538548

539-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
549+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
540550
return __find_impl(*this, __x);
541551
}
542552

543553
template <class _Kp>
544554
requires __is_transparent_v<_Compare>
545-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
555+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
546556
return __find_impl(*this, __x);
547557
}
548558

549559
template <class _Kp>
550560
requires __is_transparent_v<_Compare>
551-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
561+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
552562
return __find_impl(*this, __x);
553563
}
554564

555-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
565+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
556566
return contains(__x) ? 1 : 0;
557567
}
558568

559569
template <class _Kp>
560570
requires __is_transparent_v<_Compare>
561-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
571+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
562572
return contains(__x) ? 1 : 0;
563573
}
564574

565-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
575+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
566576
return find(__x) != end();
567577
}
568578

569579
template <class _Kp>
570580
requires __is_transparent_v<_Compare>
571-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
581+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
572582
return find(__x) != end();
573583
}
574584

575-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
585+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
576586
const auto& __keys = __keys_;
577587
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
578588
}
579589

580-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
590+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
591+
lower_bound(const key_type& __x) const {
581592
return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
582593
}
583594

584595
template <class _Kp>
585596
requires __is_transparent_v<_Compare>
586-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
597+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
587598
const auto& __keys = __keys_;
588599
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
589600
}
590601

591602
template <class _Kp>
592603
requires __is_transparent_v<_Compare>
593-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
604+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
594605
return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
595606
}
596607

597-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
608+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
598609
const auto& __keys = __keys_;
599610
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
600611
}
601612

602-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
613+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
614+
upper_bound(const key_type& __x) const {
603615
return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
604616
}
605617

606618
template <class _Kp>
607619
requires __is_transparent_v<_Compare>
608-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
620+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
609621
const auto& __keys = __keys_;
610622
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
611623
}
612624

613625
template <class _Kp>
614626
requires __is_transparent_v<_Compare>
615-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
627+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
616628
return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
617629
}
618630

619-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
631+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
632+
equal_range(const key_type& __x) {
620633
return __equal_range_impl(*this, __x);
621634
}
622635

623-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
636+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
624637
equal_range(const key_type& __x) const {
625638
return __equal_range_impl(*this, __x);
626639
}
627640

628641
template <class _Kp>
629642
requires __is_transparent_v<_Compare>
630-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
643+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
644+
equal_range(const _Kp& __x) {
631645
return __equal_range_impl(*this, __x);
632646
}
633647
template <class _Kp>
634648
requires __is_transparent_v<_Compare>
635-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
649+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
636650
equal_range(const _Kp& __x) const {
637651
return __equal_range_impl(*this, __x);
638652
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// <flat_map>
1212

13-
// [[nodiscard]] bool empty() const noexcept;
13+
// Check that functions are marked [[nodiscard]]
1414

1515
#include <flat_map>
1616
#include <utility>

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

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,93 @@
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_set>
1212

13-
// [[nodiscard]] bool empty() const noexcept;
13+
// Check that functions are marked [[nodiscard]]
1414

1515
#include <flat_set>
16+
#include <utility>
1617

17-
void f() {
18-
std::flat_set<int> c;
19-
c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
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_set<int, TransparentCompare> fs;
46+
const std::flat_set<int, TransparentCompare> cfs;
47+
48+
fs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
49+
cfs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
50+
fs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
51+
cfs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
52+
fs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
53+
cfs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
54+
fs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
55+
cfs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
56+
cfs.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
57+
cfs.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
58+
cfs.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
59+
cfs.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
60+
61+
fs.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
62+
fs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
63+
fs.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
64+
65+
std::move(fs).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
66+
67+
fs.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
68+
fs.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
69+
70+
int key = 0;
71+
TransparentKey<int> tkey;
72+
73+
fs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
74+
cfs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
75+
fs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
76+
cfs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
77+
78+
fs.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
79+
fs.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
80+
81+
fs.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
82+
fs.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
83+
84+
fs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
85+
cfs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
86+
fs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
87+
cfs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
88+
89+
fs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
90+
cfs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
91+
fs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
92+
cfs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
93+
94+
fs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
95+
cfs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
96+
fs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
97+
cfs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
2098
}

0 commit comments

Comments
 (0)