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/fixed_array.h | 60 +++++++++++++-------- absl/container/inlined_vector.h | 90 ++++++++++++++++++++----------- 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 +++++++++++++++---------- absl/types/any.h | 6 ++- absl/types/optional.h | 26 ++++----- 8 files changed, 282 insertions(+), 164 deletions(-) diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index efc40a5f..e99137a4 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -200,18 +200,22 @@ class FixedArray { // // Returns a const T* pointer to elements of the `FixedArray`. This pointer // can be used to access (but not modify) the contained elements. - const_pointer data() const { return AsValueType(storage_.begin()); } + const_pointer data() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return AsValueType(storage_.begin()); + } // Overload of FixedArray::data() to return a T* pointer to elements of the // fixed array. This pointer can be used to access and modify the contained // elements. - pointer data() { return AsValueType(storage_.begin()); } + pointer data() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return AsValueType(storage_.begin()); + } // FixedArray::operator[] // // Returns a reference the ith element of the fixed array. // REQUIRES: 0 <= i < size() - reference operator[](size_type i) { + reference operator[](size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -219,7 +223,7 @@ class FixedArray { // Overload of FixedArray::operator()[] to return a const reference to the // ith element of the fixed array. // REQUIRES: 0 <= i < size() - const_reference operator[](size_type i) const { + const_reference operator[](size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -228,7 +232,7 @@ class FixedArray { // // Bounds-checked access. Returns a reference to the ith element of the fixed // array, or throws std::out_of_range - reference at(size_type i) { + reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND { if (ABSL_PREDICT_FALSE(i >= size())) { base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); } @@ -237,7 +241,7 @@ class FixedArray { // Overload of FixedArray::at() to return a const reference to the ith element // of the fixed array. - const_reference at(size_type i) const { + const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND { if (ABSL_PREDICT_FALSE(i >= size())) { base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); } @@ -247,14 +251,14 @@ class FixedArray { // FixedArray::front() // // Returns a reference to the first element of the fixed array. - reference front() { + reference front() ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[0]; } // Overload of FixedArray::front() to return a reference to the first element // of a fixed array of const values. - const_reference front() const { + const_reference front() const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[0]; } @@ -262,14 +266,14 @@ class FixedArray { // FixedArray::back() // // Returns a reference to the last element of the fixed array. - reference back() { + reference back() ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[size() - 1]; } // Overload of FixedArray::back() to return a reference to the last element // of a fixed array of const values. - const_reference back() const { + const_reference back() const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[size() - 1]; } @@ -277,62 +281,74 @@ class FixedArray { // FixedArray::begin() // // Returns an iterator to the beginning of the fixed array. - iterator begin() { return data(); } + iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); } // Overload of FixedArray::begin() to return a const iterator to the // beginning of the fixed array. - const_iterator begin() const { return data(); } + const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); } // FixedArray::cbegin() // // Returns a const iterator to the beginning of the fixed array. - const_iterator cbegin() const { return begin(); } + const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return begin(); + } // FixedArray::end() // // Returns an iterator to the end of the fixed array. - iterator end() { return data() + size(); } + iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { return data() + size(); } // Overload of FixedArray::end() to return a const iterator to the end of the // fixed array. - const_iterator end() const { return data() + size(); } + const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return data() + size(); + } // FixedArray::cend() // // Returns a const iterator to the end of the fixed array. - const_iterator cend() const { return end(); } + const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); } // FixedArray::rbegin() // // Returns a reverse iterator from the end of the fixed array. - reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(end()); + } // Overload of FixedArray::rbegin() to return a const reverse iterator from // the end of the fixed array. - const_reverse_iterator rbegin() const { + const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(end()); } // FixedArray::crbegin() // // Returns a const reverse iterator from the end of the fixed array. - const_reverse_iterator crbegin() const { return rbegin(); } + const_reverse_iterator crbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return rbegin(); + } // FixedArray::rend() // // Returns a reverse iterator from the beginning of the fixed array. - reverse_iterator rend() { return reverse_iterator(begin()); } + reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(begin()); + } // Overload of FixedArray::rend() for returning a const reverse iterator // from the beginning of the fixed array. - const_reverse_iterator rend() const { + const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(begin()); } // FixedArray::crend() // // Returns a reverse iterator from the beginning of the fixed array. - const_reverse_iterator crend() const { return rend(); } + const_reverse_iterator crend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { + return rend(); + } // FixedArray::fill() // diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 245e1c57..04e2c385 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -341,7 +341,7 @@ class InlinedVector { // can be used to access and modify the contained elements. // // NOTE: only elements within [`data()`, `data() + size()`) are valid. - pointer data() noexcept { + pointer data() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return storage_.GetIsAllocated() ? storage_.GetAllocatedData() : storage_.GetInlinedData(); } @@ -351,7 +351,7 @@ class InlinedVector { // modify the contained elements. // // NOTE: only elements within [`data()`, `data() + size()`) are valid. - const_pointer data() const noexcept { + const_pointer data() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return storage_.GetIsAllocated() ? storage_.GetAllocatedData() : storage_.GetInlinedData(); } @@ -359,14 +359,14 @@ class InlinedVector { // `InlinedVector::operator[](...)` // // Returns a `reference` to the `i`th element of the inlined vector. - reference operator[](size_type i) { + reference operator[](size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } // Overload of `InlinedVector::operator[](...)` that returns a // `const_reference` to the `i`th element of the inlined vector. - const_reference operator[](size_type i) const { + const_reference operator[](size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -377,7 +377,7 @@ class InlinedVector { // // NOTE: if `i` is not within the required range of `InlinedVector::at(...)`, // in both debug and non-debug builds, `std::out_of_range` will be thrown. - reference at(size_type i) { + reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND { if (ABSL_PREDICT_FALSE(i >= size())) { base_internal::ThrowStdOutOfRange( "`InlinedVector::at(size_type)` failed bounds check"); @@ -390,7 +390,7 @@ class InlinedVector { // // NOTE: if `i` is not within the required range of `InlinedVector::at(...)`, // in both debug and non-debug builds, `std::out_of_range` will be thrown. - const_reference at(size_type i) const { + const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND { if (ABSL_PREDICT_FALSE(i >= size())) { base_internal::ThrowStdOutOfRange( "`InlinedVector::at(size_type) const` failed bounds check"); @@ -401,14 +401,14 @@ class InlinedVector { // `InlinedVector::front()` // // Returns a `reference` to the first element of the inlined vector. - reference front() { + reference front() ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[0]; } // Overload of `InlinedVector::front()` that returns a `const_reference` to // the first element of the inlined vector. - const_reference front() const { + const_reference front() const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[0]; } @@ -416,14 +416,14 @@ class InlinedVector { // `InlinedVector::back()` // // Returns a `reference` to the last element of the inlined vector. - reference back() { + reference back() ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[size() - 1]; } // Overload of `InlinedVector::back()` that returns a `const_reference` to the // last element of the inlined vector. - const_reference back() const { + const_reference back() const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(!empty()); return data()[size() - 1]; } @@ -431,63 +431,82 @@ class InlinedVector { // `InlinedVector::begin()` // // Returns an `iterator` to the beginning of the inlined vector. - iterator begin() noexcept { return data(); } + iterator begin() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); } // Overload of `InlinedVector::begin()` that returns a `const_iterator` to // the beginning of the inlined vector. - const_iterator begin() const noexcept { return data(); } + const_iterator begin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return data(); + } // `InlinedVector::end()` // // Returns an `iterator` to the end of the inlined vector. - iterator end() noexcept { return data() + size(); } + iterator end() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return data() + size(); + } // Overload of `InlinedVector::end()` that returns a `const_iterator` to the // end of the inlined vector. - const_iterator end() const noexcept { return data() + size(); } + const_iterator end() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return data() + size(); + } // `InlinedVector::cbegin()` // // Returns a `const_iterator` to the beginning of the inlined vector. - const_iterator cbegin() const noexcept { return begin(); } + const_iterator cbegin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return begin(); + } // `InlinedVector::cend()` // // Returns a `const_iterator` to the end of the inlined vector. - const_iterator cend() const noexcept { return end(); } + const_iterator cend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return end(); + } // `InlinedVector::rbegin()` // // Returns a `reverse_iterator` from the end of the inlined vector. - reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + reverse_iterator rbegin() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(end()); + } // Overload of `InlinedVector::rbegin()` that returns a // `const_reverse_iterator` from the end of the inlined vector. - const_reverse_iterator rbegin() const noexcept { + const_reverse_iterator rbegin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(end()); } // `InlinedVector::rend()` // // Returns a `reverse_iterator` from the beginning of the inlined vector. - reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + reverse_iterator rend() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return reverse_iterator(begin()); + } // Overload of `InlinedVector::rend()` that returns a `const_reverse_iterator` // from the beginning of the inlined vector. - const_reverse_iterator rend() const noexcept { + const_reverse_iterator rend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return const_reverse_iterator(begin()); } // `InlinedVector::crbegin()` // // Returns a `const_reverse_iterator` from the end of the inlined vector. - const_reverse_iterator crbegin() const noexcept { return rbegin(); } + const_reverse_iterator crbegin() const noexcept + ABSL_ATTRIBUTE_LIFETIME_BOUND { + return rbegin(); + } // `InlinedVector::crend()` // // Returns a `const_reverse_iterator` from the beginning of the inlined // vector. - const_reverse_iterator crend() const noexcept { return rend(); } + const_reverse_iterator crend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { + return rend(); + } // `InlinedVector::get_allocator()` // @@ -597,20 +616,23 @@ class InlinedVector { // // Inserts a copy of `v` at `pos`, returning an `iterator` to the newly // inserted element. - iterator insert(const_iterator pos, const_reference v) { + iterator insert(const_iterator pos, + const_reference v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(pos, v); } // Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using // move semantics, returning an `iterator` to the newly inserted element. - iterator insert(const_iterator pos, value_type&& v) { + iterator insert(const_iterator pos, + value_type&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND { return emplace(pos, std::move(v)); } // Overload of `InlinedVector::insert(...)` that inserts `n` contiguous copies // of `v` starting at `pos`, returning an `iterator` pointing to the first of // the newly inserted elements. - iterator insert(const_iterator pos, size_type n, const_reference v) { + iterator insert(const_iterator pos, size_type n, + const_reference v) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -638,7 +660,8 @@ class InlinedVector { // Overload of `InlinedVector::insert(...)` that inserts copies of the // elements of `list` starting at `pos`, returning an `iterator` pointing to // the first of the newly inserted elements. - iterator insert(const_iterator pos, std::initializer_list list) { + iterator insert(const_iterator pos, std::initializer_list list) + ABSL_ATTRIBUTE_LIFETIME_BOUND { return insert(pos, list.begin(), list.end()); } @@ -650,7 +673,7 @@ class InlinedVector { template = 0> iterator insert(const_iterator pos, ForwardIterator first, - ForwardIterator last) { + ForwardIterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -670,7 +693,8 @@ class InlinedVector { // NOTE: this overload is for iterators that are "input" category. template = 0> - iterator insert(const_iterator pos, InputIterator first, InputIterator last) { + iterator insert(const_iterator pos, InputIterator first, + InputIterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -687,7 +711,8 @@ class InlinedVector { // Constructs and inserts an element using `args...` in the inlined vector at // `pos`, returning an `iterator` pointing to the newly emplaced element. template - iterator emplace(const_iterator pos, Args&&... args) { + iterator emplace(const_iterator pos, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -715,7 +740,7 @@ class InlinedVector { // Constructs and inserts an element using `args...` in the inlined vector at // `end()`, returning a `reference` to the newly emplaced element. template - reference emplace_back(Args&&... args) { + reference emplace_back(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { return storage_.EmplaceBack(std::forward(args)...); } @@ -746,7 +771,7 @@ class InlinedVector { // erased element was located. // // NOTE: may return `end()`, which is not dereferenceable. - iterator erase(const_iterator pos) { + iterator erase(const_iterator pos) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos < end()); @@ -758,7 +783,8 @@ class InlinedVector { // erased element was located. // // NOTE: may return `end()`, which is not dereferenceable. - iterator erase(const_iterator from, const_iterator to) { + iterator erase(const_iterator from, + const_iterator to) ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(from >= begin()); ABSL_HARDENING_ASSERT(from <= to); ABSL_HARDENING_ASSERT(to <= end()); 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()}; } diff --git a/absl/types/any.h b/absl/types/any.h index 204da26d..61f071f1 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -53,6 +53,7 @@ #ifndef ABSL_TYPES_ANY_H_ #define ABSL_TYPES_ANY_H_ +#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/utility/utility.h" @@ -288,7 +289,7 @@ class any { typename T, typename... Args, typename VT = absl::decay_t, absl::enable_if_t::value && std::is_constructible::value>* = nullptr> - VT& emplace(Args&&... args) { + VT& emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { reset(); // NOTE: reset() is required here even in the world of exceptions. Obj* const object_ptr = new Obj(in_place, std::forward(args)...); @@ -312,7 +313,8 @@ class any { absl::enable_if_t::value && std::is_constructible&, Args...>::value>* = nullptr> - VT& emplace(std::initializer_list ilist, Args&&... args) { + VT& emplace(std::initializer_list ilist, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { reset(); // NOTE: reset() is required here even in the world of exceptions. Obj* const object_ptr = new Obj(in_place, ilist, std::forward(args)...); diff --git a/absl/types/optional.h b/absl/types/optional.h index e42ab4d0..0a8080dc 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -357,7 +357,7 @@ class optional : private optional_internal::optional_data, template ::value>::type> - T& emplace(Args&&... args) { + T& emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { this->destruct(); this->construct(std::forward(args)...); return reference(); @@ -377,7 +377,8 @@ class optional : private optional_internal::optional_data, template &, Args&&...>::value>::type> - T& emplace(std::initializer_list il, Args&&... args) { + T& emplace(std::initializer_list il, + Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { this->destruct(); this->construct(il, std::forward(args)...); return reference(); @@ -414,11 +415,11 @@ class optional : private optional_internal::optional_data, // `optional` is empty, behavior is undefined. // // If you need myOpt->foo in constexpr, use (*myOpt).foo instead. - const T* operator->() const { + const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(this->engaged_); return std::addressof(this->data_); } - T* operator->() { + T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(this->engaged_); return std::addressof(this->data_); } @@ -427,17 +428,17 @@ class optional : private optional_internal::optional_data, // // Accesses the underlying `T` value of an `optional`. If the `optional` is // empty, behavior is undefined. - constexpr const T& operator*() const& { + constexpr const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND { return ABSL_HARDENING_ASSERT(this->engaged_), reference(); } - T& operator*() & { + T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(this->engaged_); return reference(); } - constexpr const T&& operator*() const && { + constexpr const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND { return ABSL_HARDENING_ASSERT(this->engaged_), absl::move(reference()); } - T&& operator*() && { + T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND { ABSL_HARDENING_ASSERT(this->engaged_); return std::move(reference()); } @@ -472,23 +473,24 @@ class optional : private optional_internal::optional_data, // and lvalue/rvalue-ness of the `optional` is preserved to the view of // the `T` sub-object. Throws `absl::bad_optional_access` when the `optional` // is empty. - constexpr const T& value() const & { + constexpr const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND { return static_cast(*this) ? reference() : (optional_internal::throw_bad_optional_access(), reference()); } - T& value() & { + T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND { return static_cast(*this) ? reference() : (optional_internal::throw_bad_optional_access(), reference()); } - T&& value() && { // NOLINT(build/c++11) + T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND { // NOLINT(build/c++11) return std::move( static_cast(*this) ? reference() : (optional_internal::throw_bad_optional_access(), reference())); } - constexpr const T&& value() const && { // NOLINT(build/c++11) + constexpr const T&& value() + const&& ABSL_ATTRIBUTE_LIFETIME_BOUND { // NOLINT(build/c++11) return absl::move( static_cast(*this) ? reference() -- cgit v1.2.3