Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 51 additions & 37 deletions libcxx/include/__flat_set/flat_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,38 +339,42 @@ class flat_set {
}

// 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(std::as_const(__keys_).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(__keys_.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(std::as_const(__keys_).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(__keys_.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());
}

Expand All @@ -379,9 +383,13 @@ class flat_set {
return __keys_.empty();
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
return __keys_.size();
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
return __keys_.max_size();
}

// [flat.set.modifiers], modifiers
template <class... _Args>
Expand Down Expand Up @@ -466,7 +474,7 @@ class flat_set {
insert(sorted_unique, __il.begin(), __il.end());
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
auto __ret = std::move(__keys_);
return __ret;
Expand Down Expand Up @@ -528,111 +536,117 @@ class flat_set {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }

// 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 { return __compare_; }
[[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 __compare_;
}

// set 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_transparent_v<_Compare>
_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_transparent_v<_Compare>
_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 {
return contains(__x) ? 1 : 0;
}

template <class _Kp>
requires __is_transparent_v<_Compare>
_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 {
return contains(__x) ? 1 : 0;
}

_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_transparent_v<_Compare>
_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) {
const auto& __keys = __keys_;
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
}

_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 const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}

template <class _Kp>
requires __is_transparent_v<_Compare>
_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) {
const auto& __keys = __keys_;
return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
}

template <class _Kp>
requires __is_transparent_v<_Compare>
_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 const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}

_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) {
const auto& __keys = __keys_;
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
}

_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 const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}

template <class _Kp>
requires __is_transparent_v<_Compare>
_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) {
const auto& __keys = __keys_;
return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
}

template <class _Kp>
requires __is_transparent_v<_Compare>
_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 const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
}

_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_transparent_v<_Compare>
_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_transparent_v<_Compare>
_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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

// <flat_map>

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

#include <flat_map>
#include <utility>
Expand Down
88 changes: 83 additions & 5 deletions libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,93 @@
//
//===----------------------------------------------------------------------===//

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

// <flat_set>

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

#include <flat_set>
#include <utility>

void f() {
std::flat_set<int> c;
c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
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_set<int, TransparentCompare> fs;
const std::flat_set<int, TransparentCompare> cfs;

fs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::move(fs).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

int key = 0;
TransparentKey<int> tkey;

fs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

fs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
fs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
cfs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
Loading