From 20c087a795638e904792c471d8de158cc97c208a Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 3 May 2023 09:56:12 -0700 Subject: Add lifetimebound attribute to some Abseil containers PiperOrigin-RevId: 529119690 Change-Id: If585274c409e2a344c8d60759da6f8f990023d29 --- absl/container/internal/btree.h | 71 ++++++++++++++++++----------- absl/container/internal/btree_container.h | 66 ++++++++++++++++----------- absl/container/internal/raw_hash_map.h | 53 ++++++++++++++-------- absl/container/internal/raw_hash_set.h | 74 ++++++++++++++++++++----------- 4 files changed, 168 insertions(+), 96 deletions(-) (limited to 'absl/container/internal') diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 6071247c..e927c44a 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -1444,43 +1444,54 @@ class btree { btree &operator=(const btree &other); btree &operator=(btree &&other) noexcept; - iterator begin() { return iterator(leftmost()); } - const_iterator begin() const { return const_iterator(leftmost()); } - iterator end() { return iterator(rightmost(), rightmost()->finish()); } - const_iterator end() const { + iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return iterator(leftmost()); + } + const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return const_iterator(leftmost()); + } + iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return iterator(rightmost(), rightmost()->finish()); + } + const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_iterator(rightmost(), rightmost()->finish()); } - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { + reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { + reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(begin()); } // Finds the first element whose key is not less than `key`. template - iterator lower_bound(const K &key) { + iterator lower_bound(const K &key) ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_lower_bound(key).value); } template - const_iterator lower_bound(const K &key) const { + const_iterator lower_bound(const K &key) const ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_lower_bound(key).value); } // Finds the first element whose key is not less than `key` and also returns // whether that element is equal to `key`. template - std::pair lower_bound_equal(const K &key) const; + std::pair lower_bound_equal(const K &key) const + ABSL_ATTRIBUTE_LIFETIME_BOUND; // Finds the first element whose key is greater than `key`. template - iterator upper_bound(const K &key) { + iterator upper_bound(const K &key) ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_upper_bound(key)); } template - const_iterator upper_bound(const K &key) const { + const_iterator upper_bound(const K &key) const ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_upper_bound(key)); } @@ -1488,9 +1499,11 @@ class btree { // the returned pair is equal to lower_bound(key). The second member of the // pair is equal to upper_bound(key). template - std::pair equal_range(const K &key); + std::pair equal_range(const K &key) + ABSL_ATTRIBUTE_LIFETIME_BOUND; template - std::pair equal_range(const K &key) const { + std::pair equal_range(const K &key) const + ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_cast(this)->equal_range(key); } @@ -1499,7 +1512,8 @@ class btree { // Requirement: if `key` already exists in the btree, does not consume `args`. // Requirement: `key` is never referenced after consuming `args`. template - std::pair insert_unique(const K &key, Args &&...args); + std::pair insert_unique(const K &key, Args &&...args) + ABSL_ATTRIBUTE_LIFETIME_BOUND; // Inserts with hint. Checks to see if the value should be placed immediately // before `position` in the tree. If so, then the insertion will take @@ -1509,7 +1523,8 @@ class btree { // Requirement: `key` is never referenced after consuming `args`. template std::pair insert_hint_unique(iterator position, const K &key, - Args &&...args); + Args &&...args) + ABSL_ATTRIBUTE_LIFETIME_BOUND; // Insert a range of values into the btree. // Note: the first overload avoids constructing a value_type if the key @@ -1526,11 +1541,12 @@ class btree { // Inserts a value into the btree. template - iterator insert_multi(const key_type &key, ValueType &&v); + iterator insert_multi(const key_type &key, + ValueType &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND; // Inserts a value into the btree. template - iterator insert_multi(ValueType &&v) { + iterator insert_multi(ValueType &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_multi(params_type::key(v), std::forward(v)); } @@ -1539,30 +1555,33 @@ class btree { // amortized constant time. If not, the insertion will take amortized // logarithmic time as if a call to insert_multi(v) were made. template - iterator insert_hint_multi(iterator position, ValueType &&v); + iterator insert_hint_multi(iterator position, + ValueType &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND; // Insert a range of values into the btree. template - void insert_iterator_multi(InputIterator b, InputIterator e); + void insert_iterator_multi(InputIterator b, + InputIterator e); // Erase the specified iterator from the btree. The iterator must be valid // (i.e. not equal to end()). Return an iterator pointing to the node after // the one that was erased (or end() if none exists). // Requirement: does not read the value at `*iter`. - iterator erase(iterator iter); + iterator erase(iterator iter) ABSL_ATTRIBUTE_LIFETIME_BOUND; // Erases range. Returns the number of keys erased and an iterator pointing // to the element after the last erased element. - std::pair erase_range(iterator begin, iterator end); + std::pair erase_range(iterator begin, iterator end) + ABSL_ATTRIBUTE_LIFETIME_BOUND; // Finds an element with key equivalent to `key` or returns `end()` if `key` // is not present. template - iterator find(const K &key) { + iterator find(const K &key) ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_find(key)); } template - const_iterator find(const K &key) const { + const_iterator find(const K &key) const ABSL_ATTRIBUTE_LIFETIME_BOUND { return internal_end(internal_find(key)); } @@ -1572,7 +1591,7 @@ class btree { // Swaps the contents of `this` and `other`. void swap(btree &other); - const key_compare &key_comp() const noexcept { + const key_compare &key_comp() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return rightmost_.template get<0>(); } template diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 2bff11db..3c404500 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -434,37 +434,43 @@ class btree_map_container : public btree_set_container { // Note: the nullptr template arguments and extra `const M&` overloads allow // for supporting bitfield arguments. template - std::pair insert_or_assign(const key_arg &k, - const M &obj) { + std::pair insert_or_assign(const key_arg &k, const M &obj) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(k, obj); } template - std::pair insert_or_assign(key_arg &&k, const M &obj) { + std::pair insert_or_assign(key_arg &&k, const M &obj) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(std::forward(k), obj); } template - std::pair insert_or_assign(const key_arg &k, M &&obj) { + std::pair insert_or_assign(const key_arg &k, M &&obj) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(k, std::forward(obj)); } template - std::pair insert_or_assign(key_arg &&k, M &&obj) { + std::pair insert_or_assign(key_arg &&k, M &&obj) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(std::forward(k), std::forward(obj)); } template iterator insert_or_assign(const_iterator hint, const key_arg &k, - const M &obj) { + const M &obj) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_hint_impl(hint, k, obj); } template - iterator insert_or_assign(const_iterator hint, key_arg &&k, const M &obj) { + iterator insert_or_assign(const_iterator hint, key_arg &&k, + const M &obj) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_hint_impl(hint, std::forward(k), obj); } template - iterator insert_or_assign(const_iterator hint, const key_arg &k, M &&obj) { + iterator insert_or_assign(const_iterator hint, const key_arg &k, + M &&obj) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_hint_impl(hint, k, std::forward(obj)); } template - iterator insert_or_assign(const_iterator hint, key_arg &&k, M &&obj) { + iterator insert_or_assign(const_iterator hint, key_arg &&k, + M &&obj) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_hint_impl(hint, std::forward(k), std::forward(obj)); } @@ -472,44 +478,48 @@ class btree_map_container : public btree_set_container { template ::value, int> = 0> - std::pair try_emplace(const key_arg &k, Args &&... args) { + std::pair try_emplace(const key_arg &k, Args &&...args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_impl(k, std::forward(args)...); } template ::value, int> = 0> - std::pair try_emplace(key_arg &&k, Args &&... args) { + std::pair try_emplace(key_arg &&k, Args &&...args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_impl(std::forward(k), std::forward(args)...); } template iterator try_emplace(const_iterator hint, const key_arg &k, - Args &&... args) { + Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_hint_impl(hint, k, std::forward(args)...); } template - iterator try_emplace(const_iterator hint, key_arg &&k, Args &&... args) { + iterator try_emplace(const_iterator hint, key_arg &&k, + Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_hint_impl(hint, std::forward(k), std::forward(args)...); } template - mapped_type &operator[](const key_arg &k) { + mapped_type &operator[](const key_arg &k) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace(k).first->second; } template - mapped_type &operator[](key_arg &&k) { + mapped_type &operator[](key_arg &&k) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace(std::forward(k)).first->second; } template - mapped_type &at(const key_arg &key) { + mapped_type &at(const key_arg &key) ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = this->find(key); if (it == this->end()) base_internal::ThrowStdOutOfRange("absl::btree_map::at"); return it->second; } template - const mapped_type &at(const key_arg &key) const { + const mapped_type &at(const key_arg &key) const + ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = this->find(key); if (it == this->end()) base_internal::ThrowStdOutOfRange("absl::btree_map::at"); @@ -600,14 +610,18 @@ class btree_multiset_container : public btree_container { : btree_multiset_container(init.begin(), init.end(), alloc) {} // Insertion routines. - iterator insert(const value_type &v) { return this->tree_.insert_multi(v); } - iterator insert(value_type &&v) { + iterator insert(const value_type &v) ABSL_ATTRIBUTE_LIFETIME_BOUND { + return this->tree_.insert_multi(v); + } + iterator insert(value_type &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return this->tree_.insert_multi(std::move(v)); } - iterator insert(const_iterator hint, const value_type &v) { + iterator insert(const_iterator hint, + const value_type &v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return this->tree_.insert_hint_multi(iterator(hint), v); } - iterator insert(const_iterator hint, value_type &&v) { + iterator insert(const_iterator hint, + value_type &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return this->tree_.insert_hint_multi(iterator(hint), std::move(v)); } template @@ -618,21 +632,22 @@ class btree_multiset_container : public btree_container { this->tree_.insert_iterator_multi(init.begin(), init.end()); } template - iterator emplace(Args &&... args) { + iterator emplace(Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { // Use a node handle to manage a temp slot. auto node = CommonAccess::Construct(this->get_allocator(), std::forward(args)...); return this->tree_.insert_multi(CommonAccess::GetSlot(node)); } template - iterator emplace_hint(const_iterator hint, Args &&... args) { + iterator emplace_hint(const_iterator hint, + Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { // Use a node handle to manage a temp slot. auto node = CommonAccess::Construct(this->get_allocator(), std::forward(args)...); return this->tree_.insert_hint_multi(iterator(hint), CommonAccess::GetSlot(node)); } - iterator insert(node_type &&node) { + iterator insert(node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND { if (!node) return this->end(); iterator res = this->tree_.insert_multi(params_type::key(CommonAccess::GetSlot(node)), @@ -640,7 +655,8 @@ class btree_multiset_container : public btree_container { CommonAccess::Destroy(&node); return res; } - iterator insert(const_iterator hint, node_type &&node) { + iterator insert(const_iterator hint, + node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND { if (!node) return this->end(); iterator res = this->tree_.insert_hint_multi( iterator(hint), diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index c7df2efc..2d5a8710 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -71,43 +71,51 @@ class raw_hash_map : public raw_hash_set { // m.insert_or_assign(n, n); template - std::pair insert_or_assign(key_arg&& k, V&& v) { + std::pair insert_or_assign(key_arg&& k, V&& v) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(std::forward(k), std::forward(v)); } template - std::pair insert_or_assign(key_arg&& k, const V& v) { + std::pair insert_or_assign(key_arg&& k, const V& v) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(std::forward(k), v); } template - std::pair insert_or_assign(const key_arg& k, V&& v) { + std::pair insert_or_assign(const key_arg& k, V&& v) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(k, std::forward(v)); } template - std::pair insert_or_assign(const key_arg& k, const V& v) { + std::pair insert_or_assign(const key_arg& k, const V& v) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign_impl(k, v); } template - iterator insert_or_assign(const_iterator, key_arg&& k, V&& v) { + iterator insert_or_assign(const_iterator, key_arg&& k, + V&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign(std::forward(k), std::forward(v)).first; } template - iterator insert_or_assign(const_iterator, key_arg&& k, const V& v) { + iterator insert_or_assign(const_iterator, key_arg&& k, + const V& v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign(std::forward(k), v).first; } template - iterator insert_or_assign(const_iterator, const key_arg& k, V&& v) { + iterator insert_or_assign(const_iterator, const key_arg& k, + V&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign(k, std::forward(v)).first; } template - iterator insert_or_assign(const_iterator, const key_arg& k, const V& v) { + iterator insert_or_assign(const_iterator, const key_arg& k, + const V& v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert_or_assign(k, v).first; } @@ -118,29 +126,33 @@ class raw_hash_map : public raw_hash_set { typename std::enable_if< !std::is_convertible::value, int>::type = 0, K* = nullptr> - std::pair try_emplace(key_arg&& k, Args&&... args) { + std::pair try_emplace(key_arg&& k, Args&&... args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_impl(std::forward(k), std::forward(args)...); } template ::value, int>::type = 0> - std::pair try_emplace(const key_arg& k, Args&&... args) { + std::pair try_emplace(const key_arg& k, Args&&... args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace_impl(k, std::forward(args)...); } template - iterator try_emplace(const_iterator, key_arg&& k, Args&&... args) { + iterator try_emplace(const_iterator, key_arg&& k, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace(std::forward(k), std::forward(args)...).first; } template - iterator try_emplace(const_iterator, const key_arg& k, Args&&... args) { + iterator try_emplace(const_iterator, const key_arg& k, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return try_emplace(k, std::forward(args)...).first; } template - MappedReference

at(const key_arg& key) { + MappedReference

at(const key_arg& key) ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = this->find(key); if (it == this->end()) { base_internal::ThrowStdOutOfRange( @@ -150,7 +162,8 @@ class raw_hash_map : public raw_hash_set { } template - MappedConstReference

at(const key_arg& key) const { + MappedConstReference

at(const key_arg& key) const + ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = this->find(key); if (it == this->end()) { base_internal::ThrowStdOutOfRange( @@ -160,18 +173,21 @@ class raw_hash_map : public raw_hash_set { } template - MappedReference

operator[](key_arg&& key) { + MappedReference

operator[](key_arg&& key) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return Policy::value(&*try_emplace(std::forward(key)).first); } template - MappedReference

operator[](const key_arg& key) { + MappedReference

operator[](const key_arg& key) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return Policy::value(&*try_emplace(key).first); } private: template - std::pair insert_or_assign_impl(K&& k, V&& v) { + std::pair insert_or_assign_impl(K&& k, V&& v) + ABSL_ATTRIBUTE_LIFETIME_BOUND { auto res = this->find_or_prepare_insert(k); if (res.second) this->emplace_at(res.first, std::forward(k), std::forward(v)); @@ -181,7 +197,8 @@ class raw_hash_map : public raw_hash_set { } template - std::pair try_emplace_impl(K&& k, Args&&... args) { + std::pair try_emplace_impl(K&& k, Args&&... args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { auto res = this->find_or_prepare_insert(k); if (res.second) this->emplace_at(res.first, std::piecewise_construct, diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 93d3680e..df7ff793 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1828,19 +1828,25 @@ class raw_hash_set { infoz().Unregister(); } - iterator begin() { + iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = iterator_at(0); it.skip_empty_or_deleted(); return it; } - iterator end() { return iterator(common().generation_ptr()); } + iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return iterator(common().generation_ptr()); + } - const_iterator begin() const { + const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_cast(this)->begin(); } - const_iterator end() const { return iterator(common().generation_ptr()); } - const_iterator cbegin() const { return begin(); } - const_iterator cend() const { return end(); } + const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return iterator(common().generation_ptr()); + } + const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return begin(); + } + const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); } bool empty() const { return !size(); } size_t size() const { return common().size_; } @@ -1887,7 +1893,7 @@ class raw_hash_set { template = 0, class T2 = T, typename std::enable_if::value, int>::type = 0, T* = nullptr> - std::pair insert(T&& value) { + std::pair insert(T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(std::forward(value)); } @@ -1905,7 +1911,8 @@ class raw_hash_set { template < class T, RequiresInsertable = 0, typename std::enable_if::value, int>::type = 0> - std::pair insert(const T& value) { + std::pair insert(const T& value) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(value); } @@ -1914,7 +1921,8 @@ class raw_hash_set { // // flat_hash_map s; // s.insert({"abc", 42}); - std::pair insert(init_type&& value) { + std::pair insert(init_type&& value) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(std::move(value)); } @@ -1923,18 +1931,20 @@ class raw_hash_set { template = 0, class T2 = T, typename std::enable_if::value, int>::type = 0, T* = nullptr> - iterator insert(const_iterator, T&& value) { + iterator insert(const_iterator, T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert(std::forward(value)).first; } template < class T, RequiresInsertable = 0, typename std::enable_if::value, int>::type = 0> - iterator insert(const_iterator, const T& value) { + iterator insert(const_iterator, + const T& value) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert(value).first; } - iterator insert(const_iterator, init_type&& value) { + iterator insert(const_iterator, + init_type&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert(std::move(value)).first; } @@ -1952,7 +1962,7 @@ class raw_hash_set { insert(ilist.begin(), ilist.end()); } - insert_return_type insert(node_type&& node) { + insert_return_type insert(node_type&& node) ABSL_ATTRIBUTE_LIFETIME_BOUND { if (!node) return {end(), false, node_type()}; const auto& elem = PolicyTraits::element(CommonAccess::GetSlot(node)); auto res = PolicyTraits::apply( @@ -1966,7 +1976,8 @@ class raw_hash_set { } } - iterator insert(const_iterator, node_type&& node) { + iterator insert(const_iterator, + node_type&& node) ABSL_ATTRIBUTE_LIFETIME_BOUND { auto res = insert(std::move(node)); node = std::move(res.node); return res.position; @@ -1983,7 +1994,8 @@ class raw_hash_set { // m.emplace("abc", "xyz"); template ::value, int>::type = 0> - std::pair emplace(Args&&... args) { + std::pair emplace(Args&&... args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return PolicyTraits::apply(EmplaceDecomposable{*this}, std::forward(args)...); } @@ -1993,7 +2005,8 @@ class raw_hash_set { // destroys. template ::value, int>::type = 0> - std::pair emplace(Args&&... args) { + std::pair emplace(Args&&... args) + ABSL_ATTRIBUTE_LIFETIME_BOUND { alignas(slot_type) unsigned char raw[sizeof(slot_type)]; slot_type* slot = reinterpret_cast(&raw); @@ -2003,7 +2016,8 @@ class raw_hash_set { } template - iterator emplace_hint(const_iterator, Args&&... args) { + iterator emplace_hint(const_iterator, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(std::forward(args)...).first; } @@ -2053,7 +2067,8 @@ class raw_hash_set { }; template - iterator lazy_emplace(const key_arg& key, F&& f) { + iterator lazy_emplace(const key_arg& key, + F&& f) ABSL_ATTRIBUTE_LIFETIME_BOUND { auto res = find_or_prepare_insert(key); if (res.second) { slot_type* slot = slot_array() + res.first; @@ -2103,7 +2118,8 @@ class raw_hash_set { erase_meta_only(it); } - iterator erase(const_iterator first, const_iterator last) { + iterator erase(const_iterator first, + const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND { while (first != last) { erase(first++); } @@ -2232,7 +2248,8 @@ class raw_hash_set { // 2. The type of the key argument doesn't have to be key_type. This is so // called heterogeneous key support. template - iterator find(const key_arg& key, size_t hash) { + iterator find(const key_arg& key, + size_t hash) ABSL_ATTRIBUTE_LIFETIME_BOUND { auto seq = probe(common(), hash); slot_type* slot_ptr = slot_array(); const ctrl_t* ctrl = control(); @@ -2250,17 +2267,19 @@ class raw_hash_set { } } template - iterator find(const key_arg& key) { + iterator find(const key_arg& key) ABSL_ATTRIBUTE_LIFETIME_BOUND { prefetch_heap_block(); return find(key, hash_ref()(key)); } template - const_iterator find(const key_arg& key, size_t hash) const { + const_iterator find(const key_arg& key, + size_t hash) const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_cast(this)->find(key, hash); } template - const_iterator find(const key_arg& key) const { + const_iterator find(const key_arg& key) const + ABSL_ATTRIBUTE_LIFETIME_BOUND { prefetch_heap_block(); return find(key, hash_ref()(key)); } @@ -2271,14 +2290,15 @@ class raw_hash_set { } template - std::pair equal_range(const key_arg& key) { + std::pair equal_range(const key_arg& key) + ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = find(key); if (it != end()) return {it, std::next(it)}; return {it, it}; } template std::pair equal_range( - const key_arg& key) const { + const key_arg& key) const ABSL_ATTRIBUTE_LIFETIME_BOUND { auto it = find(key); if (it != end()) return {it, std::next(it)}; return {it, it}; @@ -2606,10 +2626,10 @@ class raw_hash_set { "constructed value does not match the lookup key"); } - iterator iterator_at(size_t i) { + iterator iterator_at(size_t i) ABSL_ATTRIBUTE_LIFETIME_BOUND { return {control() + i, slot_array() + i, common().generation_ptr()}; } - const_iterator iterator_at(size_t i) const { + const_iterator iterator_at(size_t i) const ABSL_ATTRIBUTE_LIFETIME_BOUND { return {control() + i, slot_array() + i, common().generation_ptr()}; } -- cgit v1.2.3