From 308ce31528a7edfa39f5f6d36142278a0ae1bf45 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 25 Feb 2019 11:52:11 -0800 Subject: Export of internal Abseil changes. -- e4e4a3460b64ba0571be217b04ec286bfac6b6bf by Tom Manshreck : Internal change PiperOrigin-RevId: 235573160 -- 200323f1243e20c201d20bdab4c15a20346a27e5 by CJ Johnson : Removed unneded template parameter from InlinedVector internal functions PiperOrigin-RevId: 234910222 -- 2f1bba53c9ca40d0718c4c1edfcfea40edd5049e by CJ Johnson : Add comment highlighting the fact that the InlinedVector(&&, alloc) move constructor overload will still commit pointer theft in one case PiperOrigin-RevId: 234899890 GitOrigin-RevId: e4e4a3460b64ba0571be217b04ec286bfac6b6bf Change-Id: I0aabbabb96e9a057a55ed6b42591ea43b4609efe --- absl/container/inlined_vector.h | 62 ++++++++++++++++------------ absl/container/internal/hashtablez_sampler.h | 18 +++++++- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 5c9e6d97..e8daf6af 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -156,11 +156,11 @@ class InlinedVector { std::copy(first, last, std::back_inserter(*this)); } - // Creates a copy of `other` using `other`'s allocator. + // Creates a copy of an `other` inlined vector using `other`'s allocator. InlinedVector(const InlinedVector& other) : InlinedVector(other, other.allocator()) {} - // Creates a copy of `other` but with a specified allocator. + // Creates a copy of an `other` inlined vector using a specified allocator. InlinedVector(const InlinedVector& other, const allocator_type& alloc) : allocator_and_tag_(alloc) { reserve(other.size()); @@ -173,14 +173,19 @@ class InlinedVector { } } - // Creates an inlined vector by moving in the contents of `other`. + // Creates an inlined vector by moving in the contents of an `other` inlined + // vector without performing any allocations. If `other` contains allocated + // memory, the newly-created instance will take ownership of that memory + // (leaving `other` itself empty). However, if `other` does not contain any + // allocated memory, the new inlined vector will will perform element-wise + // move construction of `other`s elements. // - // NOTE: This move constructor does not allocate and only moves the underlying - // objects, so its `noexcept` specification depends on whether moving the - // underlying objects can throw or not. We assume: - // a) move constructors should only throw due to allocation failure and - // b) if `value_type`'s move constructor allocates, it uses the same - // allocation function as the `InlinedVector`'s allocator, so the move + // NOTE: since no allocation is performed for the inlined vector in either + // case, the `noexcept(...)` specification depends on whether moving the + // underlying objects can throw. We assume: + // a) Move constructors should only throw due to allocation failure. + // b) If `value_type`'s move constructor allocates, it uses the same + // allocation function as the `InlinedVector`'s allocator. Thus, the move // constructor is non-throwing if the allocator is non-throwing or // `value_type`'s move constructor is specified as `noexcept`. InlinedVector(InlinedVector&& other) noexcept( @@ -202,14 +207,19 @@ class InlinedVector { } } - // Creates an inlined vector by moving in the contents of `other`. + // Creates an inlined vector by moving in the contents of an `other` inlined + // vector, performing allocations with the specified `alloc` allocator. If + // `other`'s allocator is not equal to `alloc` and `other` contains allocated + // memory, this move constructor will create a new allocation. // - // NOTE: This move constructor allocates and subsequently moves the underlying - // objects, so its `noexcept` specification depends on whether the allocation - // can throw and whether moving the underlying objects can throw. Based on the - // same assumptions as above, the `noexcept` specification is dominated by - // whether the allocation can throw regardless of whether `value_type`'s move - // constructor is specified as `noexcept`. + // NOTE: since allocation is performed in this case, this constructor can + // only be `noexcept` if the specified allocator is also `noexcept`. If this + // is the case, or if `other` contains allocated memory, this constructor + // performs element-wise move construction of its contents. + // + // Only in the case where `other`'s allocator is equal to `alloc` and `other` + // contains allocated memory will the newly created inlined vector take + // ownership of `other`'s allocated memory. InlinedVector(InlinedVector&& other, const allocator_type& alloc) noexcept( absl::allocator_is_nothrow::value) : allocator_and_tag_(alloc) { @@ -1110,9 +1120,9 @@ class InlinedVector { } } - template - void AssignForwardRange(ForwardIterator first, ForwardIterator last) { - static_assert(IsAtLeastForwardIterator::value, ""); + template + void AssignForwardRange(ForwardIt first, ForwardIt last) { + static_assert(IsAtLeastForwardIterator::value, ""); auto length = std::distance(first, last); @@ -1134,9 +1144,9 @@ class InlinedVector { } } - template - void AppendForwardRange(ForwardIterator first, ForwardIterator last) { - static_assert(IsAtLeastForwardIterator::value, ""); + template + void AppendForwardRange(ForwardIt first, ForwardIt last) { + static_assert(IsAtLeastForwardIterator::value, ""); auto length = std::distance(first, last); reserve(size() + length); @@ -1162,10 +1172,10 @@ class InlinedVector { return it_pair.first; } - template - iterator InsertWithForwardRange(const_iterator position, - ForwardIterator first, ForwardIterator last) { - static_assert(IsAtLeastForwardIterator::value, ""); + template + iterator InsertWithForwardRange(const_iterator position, ForwardIt first, + ForwardIt last) { + static_assert(IsAtLeastForwardIterator::value, ""); assert(position >= begin() && position <= end()); if (ABSL_PREDICT_FALSE(first == last)) diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index e2d8f364..547954f7 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -12,8 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// This is a low level library to sample hashtables and collect runtime -// statistics about them. +// ----------------------------------------------------------------------------- +// File: hashtablez_sampler.h +// ----------------------------------------------------------------------------- +// +// This header file defines the API for a low level library to sample hashtables +// and collect runtime statistics about them. // // `HashtablezSampler` controls the lifecycle of `HashtablezInfo` objects which // store information about a single sample. @@ -22,6 +26,16 @@ // `Sample()` and `Unsample()` make use of a single global sampler with // properties controlled by the flags hashtablez_enabled, // hashtablez_sample_rate, and hashtablez_max_samples. +// +// WARNING +// +// Using this sampling API may cause sampled Swiss tables to use the global +// allocator (operator `new`) in addition to any custom allocator. If you +// are using a table in an unusual circumstance where allocation or calling a +// linux syscall is unacceptable, this could interfere. +// +// +// This utility is internal-only. Use at your own risk. #ifndef ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_ #define ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_ -- cgit v1.2.3