summaryrefslogtreecommitdiff
path: root/absl/container/inlined_vector.h
diff options
context:
space:
mode:
authorGravatar Aaron Jacobs <jacobsa@google.com>2023-04-11 17:54:53 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-04-11 17:55:40 -0700
commitdd89c56c2ad8fe06db8fd199c7ff77c817f0111f (patch)
tree0a26cb71ca08d2f1c36d02cb667b86c4b32c9918 /absl/container/inlined_vector.h
parent2927340217c37328319b5869285a6dcdbc13e7a7 (diff)
inlined_vector: relax the requirements on the move-construction fast path.
Don't require a trivial move constructor and trivial destructor. This excludes types that have declared themselves trivially relocatable by another means, like std::unique_ptr. Instead use "is trivially relocatable" directly, which includes all previous types as well as those that have opted in. PiperOrigin-RevId: 523557136 Change-Id: Icea2dbb8f36f99623308155f2e5b1edd8e5bd36b
Diffstat (limited to 'absl/container/inlined_vector.h')
-rw-r--r--absl/container/inlined_vector.h36
1 files changed, 10 insertions, 26 deletions
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 36327ad1..9c3289a7 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -217,20 +217,12 @@ class InlinedVector {
absl::allocator_is_nothrow<allocator_type>::value ||
std::is_nothrow_move_constructible<value_type>::value)
: storage_(other.storage_.GetAllocator()) {
- // Fast path: if the value type can be trivally move constructed and
- // destroyed, and we know the allocator doesn't do anything fancy, then it's
- // safe for us to simply adopt the contents of the storage for `other` and
- // remove its own reference to them. It's as if we had individually
+ // Fast path: if the value type can be trivially relocated (i.e. moved from
+ // and destroyed), and we know the allocator doesn't do anything fancy, then
+ // it's safe for us to simply adopt the contents of the storage for `other`
+ // and remove its own reference to them. It's as if we had individually
// move-constructed each value and then destroyed the original.
- //
- // TODO(b/274984172): a move construction followed by destroying the source
- // is a "relocation" in the language of P1144R4. So actually the minimum
- // condition we need here (in addition to the allocator) is "trivially
- // relocatable". Relaxing this would allow using memcpy with types like
- // std::unique_ptr that opt in to declaring themselves trivially relocatable
- // despite not being trivially move-constructible and/oror destructible.
- if (absl::is_trivially_move_constructible<value_type>::value &&
- absl::is_trivially_destructible<value_type>::value &&
+ if (absl::is_trivially_relocatable<value_type>::value &&
std::is_same<A, std::allocator<value_type>>::value) {
storage_.MemcpyFrom(other.storage_);
other.storage_.SetInlinedSize(0);
@@ -271,20 +263,12 @@ class InlinedVector {
const allocator_type&
allocator) noexcept(absl::allocator_is_nothrow<allocator_type>::value)
: storage_(allocator) {
- // Fast path: if the value type can be trivally move constructed and
- // destroyed and we know the allocator doesn't do anything fancy, then it's
- // safe for us to simply adopt the contents of the storage for `other` and
- // remove its own reference to them. It's as if we had individually
+ // Fast path: if the value type can be trivially relocated (i.e. moved from
+ // and destroyed), and we know the allocator doesn't do anything fancy, then
+ // it's safe for us to simply adopt the contents of the storage for `other`
+ // and remove its own reference to them. It's as if we had individually
// move-constructed each value and then destroyed the original.
- //
- // TODO(b/274984172): a move construction followed by destroying the source
- // is a "relocation" in the language of P1144R4. So actually the minimum
- // condition we need here (in addition to the allocator) is "trivially
- // relocatable". Relaxing this would allow using memcpy with types like
- // std::unique_ptr that opt in to declaring themselves trivially relocatable
- // despite not being trivially move-constructible and/oror destructible.
- if (absl::is_trivially_move_constructible<value_type>::value &&
- absl::is_trivially_destructible<value_type>::value &&
+ if (absl::is_trivially_relocatable<value_type>::value &&
std::is_same<A, std::allocator<value_type>>::value) {
storage_.MemcpyFrom(other.storage_);
other.storage_.SetInlinedSize(0);