Coverage Report

Created: 2026-07-25 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/abseil-cpp/absl/container/internal/inlined_vector.h
Line
Count
Source
1
// Copyright 2019 The Abseil Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_
16
#define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_
17
18
#include <algorithm>
19
#include <cstddef>
20
#include <cstring>
21
#include <iterator>
22
#include <limits>
23
#include <memory>
24
#include <new>
25
#include <type_traits>
26
#include <utility>
27
28
#include "absl/base/attributes.h"
29
#include "absl/base/config.h"
30
#include "absl/base/macros.h"
31
#include "absl/container/internal/compressed_tuple.h"
32
#include "absl/memory/memory.h"
33
#include "absl/meta/type_traits.h"
34
#include "absl/types/span.h"
35
36
namespace absl {
37
ABSL_NAMESPACE_BEGIN
38
namespace inlined_vector_internal {
39
40
// GCC does not deal very well with the below code
41
#if !defined(__clang__) && defined(__GNUC__)
42
#pragma GCC diagnostic push
43
#pragma GCC diagnostic ignored "-Warray-bounds"
44
#endif
45
46
template <typename A>
47
using AllocatorTraits = std::allocator_traits<A>;
48
template <typename A>
49
using ValueType = typename AllocatorTraits<A>::value_type;
50
template <typename A>
51
using SizeType = typename AllocatorTraits<A>::size_type;
52
template <typename A>
53
using Pointer = typename AllocatorTraits<A>::pointer;
54
template <typename A>
55
using ConstPointer = typename AllocatorTraits<A>::const_pointer;
56
template <typename A>
57
using SizeType = typename AllocatorTraits<A>::size_type;
58
template <typename A>
59
using DifferenceType = typename AllocatorTraits<A>::difference_type;
60
template <typename A>
61
using Reference = ValueType<A>&;
62
template <typename A>
63
using ConstReference = const ValueType<A>&;
64
template <typename A>
65
using Iterator = Pointer<A>;
66
template <typename A>
67
using ConstIterator = ConstPointer<A>;
68
template <typename A>
69
using ReverseIterator = typename std::reverse_iterator<Iterator<A>>;
70
template <typename A>
71
using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>;
72
template <typename A>
73
using MoveIterator = typename std::move_iterator<Iterator<A>>;
74
75
template <typename Iterator>
76
using IsAtLeastForwardIterator = std::is_convertible<
77
    typename std::iterator_traits<Iterator>::iterator_category,
78
    std::forward_iterator_tag>;
79
80
template <typename A>
81
using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>;
82
template <typename A>
83
using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;
84
85
template <typename T>
86
struct TypeIdentity {
87
  using type = T;
88
};
89
90
// Used for function arguments in template functions to prevent ADL by forcing
91
// callers to explicitly specify the template parameter.
92
template <typename T>
93
using NoTypeDeduction = typename TypeIdentity<T>::type;
94
95
template <typename A, bool IsTriviallyDestructible =
96
                          absl::is_trivially_destructible<ValueType<A>>::value>
97
struct DestroyAdapter;
98
99
template <typename A>
100
struct DestroyAdapter<A, /* IsTriviallyDestructible */ false> {
101
  static void DestroyElements(A& allocator, Pointer<A> destroy_first,
102
0
                              SizeType<A> destroy_size) {
103
0
    for (SizeType<A> i = destroy_size; i != 0;) {
104
0
      --i;
105
0
      AllocatorTraits<A>::destroy(allocator, destroy_first + i);
106
0
    }
107
0
  }
108
};
109
110
template <typename A>
111
struct DestroyAdapter<A, /* IsTriviallyDestructible */ true> {
112
  static void DestroyElements(A& allocator, Pointer<A> destroy_first,
113
0
                              SizeType<A> destroy_size) {
114
0
    static_cast<void>(allocator);
115
0
    static_cast<void>(destroy_first);
116
0
    static_cast<void>(destroy_size);
117
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::DestroyAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, true>::DestroyElements(std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>&, absl::lts_20240116::str_format_internal::FormatArgImpl*, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::DestroyAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, true>::DestroyElements(std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>&, absl::lts_20240116::cord_internal::CordRep**, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::DestroyAdapter<std::__1::allocator<int>, true>::DestroyElements(std::__1::allocator<int>&, int*, unsigned long)
118
};
119
120
template <typename A>
121
struct Allocation {
122
  Pointer<A> data = nullptr;
123
  SizeType<A> capacity = 0;
124
};
125
126
template <typename A,
127
          bool IsOverAligned =
128
              (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)>
129
struct MallocAdapter {
130
0
  static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) {
131
0
    return {AllocatorTraits<A>::allocate(allocator, requested_capacity),
132
0
            requested_capacity};
133
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, false>::Allocate(std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>&, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, false>::Allocate(std::__1::allocator<absl::lts_20240116::status_internal::Payload>&, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, false>::Allocate(std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>&, unsigned long)
134
135
  static void Deallocate(A& allocator, Pointer<A> pointer,
136
0
                         SizeType<A> capacity) {
137
0
    AllocatorTraits<A>::deallocate(allocator, pointer, capacity);
138
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, false>::Deallocate(std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>&, absl::lts_20240116::str_format_internal::FormatArgImpl*, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, false>::Deallocate(std::__1::allocator<absl::lts_20240116::status_internal::Payload>&, absl::lts_20240116::status_internal::Payload*, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, false>::Deallocate(std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>&, absl::lts_20240116::cord_internal::CordRep**, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::MallocAdapter<std::__1::allocator<int>, false>::Deallocate(std::__1::allocator<int>&, int*, unsigned long)
139
};
140
141
template <typename A, typename ValueAdapter>
142
void ConstructElements(NoTypeDeduction<A>& allocator,
143
                       Pointer<A> construct_first, ValueAdapter& values,
144
0
                       SizeType<A> construct_size) {
145
0
  for (SizeType<A> i = 0; i < construct_size; ++i) {
146
0
    ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); }
147
0
    ABSL_INTERNAL_CATCH_ANY {
148
0
      DestroyAdapter<A>::DestroyElements(allocator, construct_first, i);
149
0
      ABSL_INTERNAL_RETHROW;
150
0
    }
151
0
  }
152
0
}
Unexecuted instantiation: void absl::lts_20240116::inlined_vector_internal::ConstructElements<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, absl::lts_20240116::str_format_internal::FormatArgImpl const*> >(absl::lts_20240116::inlined_vector_internal::TypeIdentity<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::type&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::pointer, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, absl::lts_20240116::str_format_internal::FormatArgImpl const*>&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::size_type)
Unexecuted instantiation: void absl::lts_20240116::inlined_vector_internal::ConstructElements<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, std::__1::move_iterator<absl::lts_20240116::status_internal::Payload*> > >(absl::lts_20240116::inlined_vector_internal::TypeIdentity<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::type&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::pointer, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, std::__1::move_iterator<absl::lts_20240116::status_internal::Payload*> >&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::size_type)
Unexecuted instantiation: void absl::lts_20240116::inlined_vector_internal::ConstructElements<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::status_internal::Payload const*> >(absl::lts_20240116::inlined_vector_internal::TypeIdentity<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::type&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::pointer, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::status_internal::Payload const*>&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::size_type)
Unexecuted instantiation: void absl::lts_20240116::inlined_vector_internal::ConstructElements<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, std::__1::move_iterator<absl::lts_20240116::cord_internal::CordRep**> > >(absl::lts_20240116::inlined_vector_internal::TypeIdentity<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::type&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::pointer, absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, std::__1::move_iterator<absl::lts_20240116::cord_internal::CordRep**> >&, std::__1::allocator_traits<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::size_type)
153
154
template <typename A, typename ValueAdapter>
155
void AssignElements(Pointer<A> assign_first, ValueAdapter& values,
156
0
                    SizeType<A> assign_size) {
157
0
  for (SizeType<A> i = 0; i < assign_size; ++i) {
158
0
    values.AssignNext(assign_first + i);
159
0
  }
160
0
}
161
162
template <typename A>
163
struct StorageView {
164
  Pointer<A> data;
165
  SizeType<A> size;
166
  SizeType<A> capacity;
167
};
168
169
template <typename A, typename Iterator>
170
class IteratorValueAdapter {
171
 public:
172
0
  explicit IteratorValueAdapter(const Iterator& it) : it_(it) {}
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, std::__1::move_iterator<absl::lts_20240116::status_internal::Payload*> >::IteratorValueAdapter(std::__1::move_iterator<absl::lts_20240116::status_internal::Payload*> const&)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, std::__1::move_iterator<absl::lts_20240116::cord_internal::CordRep**> >::IteratorValueAdapter(std::__1::move_iterator<absl::lts_20240116::cord_internal::CordRep**> const&)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::status_internal::Payload const*>::IteratorValueAdapter(absl::lts_20240116::status_internal::Payload const* const&)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, absl::lts_20240116::str_format_internal::FormatArgImpl const*>::IteratorValueAdapter(absl::lts_20240116::str_format_internal::FormatArgImpl const* const&)
173
174
0
  void ConstructNext(A& allocator, Pointer<A> construct_at) {
175
0
    AllocatorTraits<A>::construct(allocator, construct_at, *it_);
176
0
    ++it_;
177
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>, absl::lts_20240116::str_format_internal::FormatArgImpl const*>::ConstructNext(std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl>&, absl::lts_20240116::str_format_internal::FormatArgImpl*)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, std::__1::move_iterator<absl::lts_20240116::status_internal::Payload*> >::ConstructNext(std::__1::allocator<absl::lts_20240116::status_internal::Payload>&, absl::lts_20240116::status_internal::Payload*)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::status_internal::Payload>, absl::lts_20240116::status_internal::Payload const*>::ConstructNext(std::__1::allocator<absl::lts_20240116::status_internal::Payload>&, absl::lts_20240116::status_internal::Payload*)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::IteratorValueAdapter<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>, std::__1::move_iterator<absl::lts_20240116::cord_internal::CordRep**> >::ConstructNext(std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>&, absl::lts_20240116::cord_internal::CordRep**)
178
179
0
  void AssignNext(Pointer<A> assign_at) {
180
0
    *assign_at = *it_;
181
0
    ++it_;
182
0
  }
183
184
 private:
185
  Iterator it_;
186
};
187
188
template <typename A>
189
class CopyValueAdapter {
190
 public:
191
  explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {}
192
193
  void ConstructNext(A& allocator, Pointer<A> construct_at) {
194
    AllocatorTraits<A>::construct(allocator, construct_at, *ptr_);
195
  }
196
197
  void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; }
198
199
 private:
200
  ConstPointer<A> ptr_;
201
};
202
203
template <typename A>
204
class DefaultValueAdapter {
205
 public:
206
  explicit DefaultValueAdapter() {}
207
208
  void ConstructNext(A& allocator, Pointer<A> construct_at) {
209
    AllocatorTraits<A>::construct(allocator, construct_at);
210
  }
211
212
  void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); }
213
};
214
215
template <typename A>
216
class AllocationTransaction {
217
 public:
218
  explicit AllocationTransaction(A& allocator)
219
0
      : allocator_data_(allocator, nullptr), capacity_(0) {}
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::AllocationTransaction(std::__1::allocator<absl::lts_20240116::status_internal::Payload>&)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::AllocationTransaction(std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*>&)
220
221
0
  ~AllocationTransaction() {
222
0
    if (DidAllocate()) {
223
0
      MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity());
224
0
    }
225
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::~AllocationTransaction()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::~AllocationTransaction()
226
227
  AllocationTransaction(const AllocationTransaction&) = delete;
228
  void operator=(const AllocationTransaction&) = delete;
229
230
0
  A& GetAllocator() { return allocator_data_.template get<0>(); }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetAllocator()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocator()
231
0
  Pointer<A>& GetData() { return allocator_data_.template get<1>(); }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetData()
232
0
  SizeType<A>& GetCapacity() { return capacity_; }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetCapacity()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetCapacity()
233
234
0
  bool DidAllocate() { return GetData() != nullptr; }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::DidAllocate()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::DidAllocate()
235
236
0
  Pointer<A> Allocate(SizeType<A> requested_capacity) {
237
0
    Allocation<A> result =
238
0
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
239
0
    GetData() = result.data;
240
0
    GetCapacity() = result.capacity;
241
0
    return result.data;
242
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::Allocate(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::Allocate(unsigned long)
243
244
0
  ABSL_MUST_USE_RESULT Allocation<A> Release() && {
245
0
    Allocation<A> result = {GetData(), GetCapacity()};
246
0
    Reset();
247
0
    return result;
248
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::Release() &&
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::Release() &&
249
250
 private:
251
0
  void Reset() {
252
0
    GetData() = nullptr;
253
0
    GetCapacity() = 0;
254
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::Reset()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::AllocationTransaction<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::Reset()
255
256
  container_internal::CompressedTuple<A, Pointer<A>> allocator_data_;
257
  SizeType<A> capacity_;
258
};
259
260
template <typename A>
261
class ConstructionTransaction {
262
 public:
263
  explicit ConstructionTransaction(A& allocator)
264
      : allocator_data_(allocator, nullptr), size_(0) {}
265
266
  ~ConstructionTransaction() {
267
    if (DidConstruct()) {
268
      DestroyAdapter<A>::DestroyElements(GetAllocator(), GetData(), GetSize());
269
    }
270
  }
271
272
  ConstructionTransaction(const ConstructionTransaction&) = delete;
273
  void operator=(const ConstructionTransaction&) = delete;
274
275
  A& GetAllocator() { return allocator_data_.template get<0>(); }
276
  Pointer<A>& GetData() { return allocator_data_.template get<1>(); }
277
  SizeType<A>& GetSize() { return size_; }
278
279
  bool DidConstruct() { return GetData() != nullptr; }
280
  template <typename ValueAdapter>
281
  void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) {
282
    ConstructElements<A>(GetAllocator(), data, values, size);
283
    GetData() = data;
284
    GetSize() = size;
285
  }
286
  void Commit() && {
287
    GetData() = nullptr;
288
    GetSize() = 0;
289
  }
290
291
 private:
292
  container_internal::CompressedTuple<A, Pointer<A>> allocator_data_;
293
  SizeType<A> size_;
294
};
295
296
template <typename T, size_t N, typename A>
297
class Storage {
298
 public:
299
  struct MemcpyPolicy {};
300
  struct ElementwiseAssignPolicy {};
301
  struct ElementwiseSwapPolicy {};
302
  struct ElementwiseConstructPolicy {};
303
304
  using MoveAssignmentPolicy = absl::conditional_t<
305
      // Fast path: if the value type can be trivially move assigned and
306
      // destroyed, and we know the allocator doesn't do anything fancy, then
307
      // it's safe for us to simply adopt the contents of the storage for
308
      // `other` and remove its own reference to them. It's as if we had
309
      // individually move-assigned each value and then destroyed the original.
310
      absl::conjunction<absl::is_trivially_move_assignable<ValueType<A>>,
311
                        absl::is_trivially_destructible<ValueType<A>>,
312
                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
313
      MemcpyPolicy,
314
      // Otherwise we use move assignment if possible. If not, we simulate
315
      // move assignment using move construction.
316
      //
317
      // Note that this is in contrast to e.g. std::vector and std::optional,
318
      // which are themselves not move-assignable when their contained type is
319
      // not.
320
      absl::conditional_t<IsMoveAssignOk<A>::value, ElementwiseAssignPolicy,
321
                          ElementwiseConstructPolicy>>;
322
323
  // The policy to be used specifically when swapping inlined elements.
324
  using SwapInlinedElementsPolicy = absl::conditional_t<
325
      // Fast path: if the value type can be trivially move constructed/assigned
326
      // and destroyed, and we know the allocator doesn't do anything fancy,
327
      // then it's safe for us to simply swap the bytes in the inline storage.
328
      // It's as if we had move-constructed a temporary vector, move-assigned
329
      // one to the other, then move-assigned the first from the temporary.
330
      absl::conjunction<absl::is_trivially_move_constructible<ValueType<A>>,
331
                        absl::is_trivially_move_assignable<ValueType<A>>,
332
                        absl::is_trivially_destructible<ValueType<A>>,
333
                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
334
      MemcpyPolicy,
335
      absl::conditional_t<IsSwapOk<A>::value, ElementwiseSwapPolicy,
336
                          ElementwiseConstructPolicy>>;
337
338
0
  static SizeType<A> NextCapacity(SizeType<A> current_capacity) {
339
0
    return current_capacity * 2;
340
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::NextCapacity(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::NextCapacity(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::NextCapacity(unsigned long)
341
342
  static SizeType<A> ComputeCapacity(SizeType<A> current_capacity,
343
0
                                     SizeType<A> requested_capacity) {
344
0
    return (std::max)(NextCapacity(current_capacity), requested_capacity);
345
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::ComputeCapacity(unsigned long, unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::ComputeCapacity(unsigned long, unsigned long)
346
347
  // ---------------------------------------------------------------------------
348
  // Storage Constructors and Destructor
349
  // ---------------------------------------------------------------------------
350
351
0
  Storage() : metadata_(A(), /* size and is_allocated */ 0u) {}
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::Storage()
352
353
  explicit Storage(const A& allocator)
354
0
      : metadata_(allocator, /* size and is_allocated */ 0u) {}
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::Storage(std::__1::allocator<absl::lts_20240116::status_internal::Payload> const&)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::Storage(std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> const&)
355
356
0
  ~Storage() {
357
    // Fast path: if we are empty and not allocated, there's nothing to do.
358
0
    if (GetSizeAndIsAllocated() == 0) {
359
0
      return;
360
0
    }
361
362
    // Fast path: if no destructors need to be run and we know the allocator
363
    // doesn't do anything fancy, then all we need to do is deallocate (and
364
    // maybe not even that).
365
0
    if (absl::is_trivially_destructible<ValueType<A>>::value &&
366
0
        std::is_same<A, std::allocator<ValueType<A>>>::value) {
367
0
      DeallocateIfAllocated();
368
0
      return;
369
0
    }
370
371
0
    DestroyContents();
372
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::~Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::~Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::~Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::~Storage()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::~Storage()
373
374
  // ---------------------------------------------------------------------------
375
  // Storage Member Accessors
376
  // ---------------------------------------------------------------------------
377
378
0
  SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetSizeAndIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetSizeAndIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSizeAndIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSizeAndIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetSizeAndIsAllocated()
379
380
0
  const SizeType<A>& GetSizeAndIsAllocated() const {
381
0
    return metadata_.template get<1>();
382
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetSizeAndIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetSizeAndIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSizeAndIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSizeAndIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetSizeAndIsAllocated() const
383
384
0
  SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetSize() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetSize() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSize() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetSize() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetSize() const
385
386
0
  bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetIsAllocated() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetIsAllocated() const
387
388
0
  Pointer<A> GetAllocatedData() {
389
    // GCC 12 has a false-positive -Wmaybe-uninitialized warning here.
390
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
391
#pragma GCC diagnostic push
392
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
393
#endif
394
0
    return data_.allocated.allocated_data;
395
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
396
#pragma GCC diagnostic pop
397
#endif
398
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetAllocatedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetAllocatedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocatedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocatedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetAllocatedData()
399
400
0
  ConstPointer<A> GetAllocatedData() const {
401
0
    return data_.allocated.allocated_data;
402
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetAllocatedData() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetAllocatedData() const
403
404
  // ABSL_ATTRIBUTE_NO_SANITIZE_CFI is used because the memory pointed to may be
405
  // uninitialized, a common pattern in allocate()+construct() APIs.
406
  // https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking
407
  // NOTE: When this was written, LLVM documentation did not explicitly
408
  // mention that casting `char*` and using `reinterpret_cast` qualifies
409
  // as a bad cast.
410
0
  ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer<A> GetInlinedData() {
411
0
    return reinterpret_cast<Pointer<A>>(data_.inlined.inlined_data);
412
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetInlinedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetInlinedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetInlinedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetInlinedData()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetInlinedData()
413
414
0
  ABSL_ATTRIBUTE_NO_SANITIZE_CFI ConstPointer<A> GetInlinedData() const {
415
0
    return reinterpret_cast<ConstPointer<A>>(data_.inlined.inlined_data);
416
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetInlinedData() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetInlinedData() const
417
418
0
  SizeType<A> GetAllocatedCapacity() const {
419
0
    return data_.allocated.allocated_capacity;
420
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetAllocatedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetAllocatedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocatedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetAllocatedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocatedCapacity() const
421
422
0
  SizeType<A> GetInlinedCapacity() const {
423
0
    return static_cast<SizeType<A>>(kOptimalInlinedSize);
424
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetInlinedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetInlinedCapacity() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetInlinedCapacity() const
425
426
0
  StorageView<A> MakeStorageView() {
427
0
    return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(),
428
0
                                             GetAllocatedCapacity()}
429
0
                            : StorageView<A>{GetInlinedData(), GetSize(),
430
0
                                             GetInlinedCapacity()};
431
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::MakeStorageView()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::MakeStorageView()
432
433
0
  A& GetAllocator() { return metadata_.template get<0>(); }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::GetAllocator()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::GetAllocator()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocator()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::GetAllocator()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::GetAllocator()
434
435
0
  const A& GetAllocator() const { return metadata_.template get<0>(); }
436
437
  // ---------------------------------------------------------------------------
438
  // Storage Member Mutators
439
  // ---------------------------------------------------------------------------
440
441
  ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other);
442
443
  template <typename ValueAdapter>
444
  void Initialize(ValueAdapter values, SizeType<A> new_size);
445
446
  template <typename ValueAdapter>
447
  void Assign(ValueAdapter values, SizeType<A> new_size);
448
449
  template <typename ValueAdapter>
450
  void Resize(ValueAdapter values, SizeType<A> new_size);
451
452
  template <typename ValueAdapter>
453
  Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values,
454
                     SizeType<A> insert_count);
455
456
  template <typename... Args>
457
  Reference<A> EmplaceBack(Args&&... args);
458
459
  Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to);
460
461
  void Reserve(SizeType<A> requested_capacity);
462
463
  void ShrinkToFit();
464
465
  void Swap(Storage* other_storage_ptr);
466
467
0
  void SetIsAllocated() {
468
0
    GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1);
469
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::SetIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::SetIsAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SetIsAllocated()
470
471
  void UnsetIsAllocated() {
472
    GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1);
473
  }
474
475
  void SetSize(SizeType<A> size) {
476
    GetSizeAndIsAllocated() =
477
        (size << 1) | static_cast<SizeType<A>>(GetIsAllocated());
478
  }
479
480
  void SetAllocatedSize(SizeType<A> size) {
481
    GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1);
482
  }
483
484
  void SetInlinedSize(SizeType<A> size) {
485
    GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1);
486
  }
487
488
0
  void AddSize(SizeType<A> count) {
489
0
    GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1);
490
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::AddSize(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::AddSize(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::AddSize(unsigned long)
491
492
0
  void SubtractSize(SizeType<A> count) {
493
0
    ABSL_HARDENING_ASSERT(count <= GetSize());
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::SubtractSize(unsigned long)::{lambda()#1}::operator()() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SubtractSize(unsigned long)::{lambda()#1}::operator()() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SubtractSize(unsigned long)::{lambda()#1}::operator()() const
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::SubtractSize(unsigned long)::{lambda()#1}::operator()() const
494
495
0
    GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1);
496
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::SubtractSize(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SubtractSize(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SubtractSize(unsigned long)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::SubtractSize(unsigned long)
497
498
0
  void SetAllocation(Allocation<A> allocation) {
499
0
    data_.allocated.allocated_data = allocation.data;
500
0
    data_.allocated.allocated_capacity = allocation.capacity;
501
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::SetAllocation(absl::lts_20240116::inlined_vector_internal::Allocation<std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::SetAllocation(absl::lts_20240116::inlined_vector_internal::Allocation<std::__1::allocator<absl::lts_20240116::status_internal::Payload> >)
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::SetAllocation(absl::lts_20240116::inlined_vector_internal::Allocation<std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >)
502
503
0
  void MemcpyFrom(const Storage& other_storage) {
504
0
    // Assumption check: it doesn't make sense to memcpy inlined elements unless
505
0
    // we know the allocator doesn't do anything fancy, and one of the following
506
0
    // holds:
507
0
    //
508
0
    //  *  The elements are trivially relocatable.
509
0
    //
510
0
    //  *  It's possible to trivially assign the elements and then destroy the
511
0
    //     source.
512
0
    //
513
0
    //  *  It's possible to trivially copy construct/assign the elements.
514
0
    //
515
0
    {
516
0
      using V = ValueType<A>;
517
0
      ABSL_HARDENING_ASSERT(
518
0
          other_storage.GetIsAllocated() ||
519
0
          (std::is_same<A, std::allocator<V>>::value &&
520
0
           (
521
0
               // First case above
522
0
               absl::is_trivially_relocatable<V>::value ||
523
0
               // Second case above
524
0
               (absl::is_trivially_move_assignable<V>::value &&
525
0
                absl::is_trivially_destructible<V>::value) ||
526
0
               // Third case above
527
0
               (absl::is_trivially_copy_constructible<V>::value ||
528
0
                absl::is_trivially_copy_assignable<V>::value))));
529
0
    }
530
0
531
0
    GetSizeAndIsAllocated() = other_storage.GetSizeAndIsAllocated();
532
0
    data_ = other_storage.data_;
533
0
  }
534
535
0
  void DeallocateIfAllocated() {
536
0
    if (GetIsAllocated()) {
537
0
      MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(),
538
0
                                   GetAllocatedCapacity());
539
0
    }
540
0
  }
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::str_format_internal::FormatArgImpl, 4ul, std::__1::allocator<absl::lts_20240116::str_format_internal::FormatArgImpl> >::DeallocateIfAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::DeallocateIfAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::DeallocateIfAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::DeallocateIfAllocated()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::DeallocateIfAllocated()
541
542
 private:
543
  ABSL_ATTRIBUTE_NOINLINE void DestroyContents();
544
545
  using Metadata = container_internal::CompressedTuple<A, SizeType<A>>;
546
547
  struct Allocated {
548
    Pointer<A> allocated_data;
549
    SizeType<A> allocated_capacity;
550
  };
551
552
  // `kOptimalInlinedSize` is an automatically adjusted inlined capacity of the
553
  // `InlinedVector`. Sometimes, it is possible to increase the capacity (from
554
  // the user requested `N`) without increasing the size of the `InlinedVector`.
555
  static constexpr size_t kOptimalInlinedSize =
556
      (std::max)(N, sizeof(Allocated) / sizeof(ValueType<A>));
557
558
  struct Inlined {
559
    alignas(ValueType<A>) char inlined_data[sizeof(
560
        ValueType<A>[kOptimalInlinedSize])];
561
  };
562
563
  union Data {
564
    Allocated allocated;
565
    Inlined inlined;
566
  };
567
568
  void SwapN(ElementwiseSwapPolicy, Storage* other, SizeType<A> n);
569
  void SwapN(ElementwiseConstructPolicy, Storage* other, SizeType<A> n);
570
571
  void SwapInlinedElements(MemcpyPolicy, Storage* other);
572
  template <typename NotMemcpyPolicy>
573
  void SwapInlinedElements(NotMemcpyPolicy, Storage* other);
574
575
  template <typename... Args>
576
  ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args);
577
578
  Metadata metadata_;
579
  Data data_;
580
};
581
582
template <typename T, size_t N, typename A>
583
0
void Storage<T, N, A>::DestroyContents() {
584
0
  Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData();
585
0
  DestroyAdapter<A>::DestroyElements(GetAllocator(), data, GetSize());
586
0
  DeallocateIfAllocated();
587
0
}
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::DestroyContents()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 47ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::DestroyContents()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<int, 47ul, std::__1::allocator<int> >::DestroyContents()
Unexecuted instantiation: absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::DestroyContents()
588
589
template <typename T, size_t N, typename A>
590
0
void Storage<T, N, A>::InitFrom(const Storage& other) {
591
0
  const SizeType<A> n = other.GetSize();
592
0
  ABSL_HARDENING_ASSERT(n > 0);  // Empty sources handled handled in caller.
593
0
  ConstPointer<A> src;
594
0
  Pointer<A> dst;
595
0
  if (!other.GetIsAllocated()) {
596
0
    dst = GetInlinedData();
597
0
    src = other.GetInlinedData();
598
0
  } else {
599
    // Because this is only called from the `InlinedVector` constructors, it's
600
    // safe to take on the allocation with size `0`. If `ConstructElements(...)`
601
    // throws, deallocation will be automatically handled by `~Storage()`.
602
0
    SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n);
603
0
    Allocation<A> allocation =
604
0
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
605
0
    SetAllocation(allocation);
606
0
    dst = allocation.data;
607
0
    src = other.GetAllocatedData();
608
0
  }
609
610
  // Fast path: if the value type is trivially copy constructible and we know
611
  // the allocator doesn't do anything fancy, then we know it is legal for us to
612
  // simply memcpy the other vector's elements.
613
0
  if (absl::is_trivially_copy_constructible<ValueType<A>>::value &&
614
0
      std::is_same<A, std::allocator<ValueType<A>>>::value) {
615
0
    std::memcpy(reinterpret_cast<char*>(dst),
616
0
                reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>));
617
0
  } else {
618
0
    auto values = IteratorValueAdapter<A, ConstPointer<A>>(src);
619
0
    ConstructElements<A>(GetAllocator(), dst, values, n);
620
0
  }
621
622
0
  GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated();
623
0
}
624
625
template <typename T, size_t N, typename A>
626
template <typename ValueAdapter>
627
auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size)
628
0
    -> void {
629
  // Only callable from constructors!
630
0
  ABSL_HARDENING_ASSERT(!GetIsAllocated());
631
0
  ABSL_HARDENING_ASSERT(GetSize() == 0);
632
633
0
  Pointer<A> construct_data;
634
0
  if (new_size > GetInlinedCapacity()) {
635
    // Because this is only called from the `InlinedVector` constructors, it's
636
    // safe to take on the allocation with size `0`. If `ConstructElements(...)`
637
    // throws, deallocation will be automatically handled by `~Storage()`.
638
0
    SizeType<A> requested_capacity =
639
0
        ComputeCapacity(GetInlinedCapacity(), new_size);
640
0
    Allocation<A> allocation =
641
0
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
642
0
    construct_data = allocation.data;
643
0
    SetAllocation(allocation);
644
0
    SetIsAllocated();
645
0
  } else {
646
0
    construct_data = GetInlinedData();
647
0
  }
648
649
0
  ConstructElements<A>(GetAllocator(), construct_data, values, new_size);
650
651
  // Since the initial size was guaranteed to be `0` and the allocated bit is
652
  // already correct for either case, *adding* `new_size` gives us the correct
653
  // result faster than setting it directly.
654
0
  AddSize(new_size);
655
0
}
656
657
template <typename T, size_t N, typename A>
658
template <typename ValueAdapter>
659
auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size)
660
    -> void {
661
  StorageView<A> storage_view = MakeStorageView();
662
663
  AllocationTransaction<A> allocation_tx(GetAllocator());
664
665
  absl::Span<ValueType<A>> assign_loop;
666
  absl::Span<ValueType<A>> construct_loop;
667
  absl::Span<ValueType<A>> destroy_loop;
668
669
  if (new_size > storage_view.capacity) {
670
    SizeType<A> requested_capacity =
671
        ComputeCapacity(storage_view.capacity, new_size);
672
    construct_loop = {allocation_tx.Allocate(requested_capacity), new_size};
673
    destroy_loop = {storage_view.data, storage_view.size};
674
  } else if (new_size > storage_view.size) {
675
    assign_loop = {storage_view.data, storage_view.size};
676
    construct_loop = {storage_view.data + storage_view.size,
677
                      new_size - storage_view.size};
678
  } else {
679
    assign_loop = {storage_view.data, new_size};
680
    destroy_loop = {storage_view.data + new_size, storage_view.size - new_size};
681
  }
682
683
  AssignElements<A>(assign_loop.data(), values, assign_loop.size());
684
685
  ConstructElements<A>(GetAllocator(), construct_loop.data(), values,
686
                       construct_loop.size());
687
688
  DestroyAdapter<A>::DestroyElements(GetAllocator(), destroy_loop.data(),
689
                                     destroy_loop.size());
690
691
  if (allocation_tx.DidAllocate()) {
692
    DeallocateIfAllocated();
693
    SetAllocation(std::move(allocation_tx).Release());
694
    SetIsAllocated();
695
  }
696
697
  SetSize(new_size);
698
}
699
700
template <typename T, size_t N, typename A>
701
template <typename ValueAdapter>
702
auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size)
703
    -> void {
704
  StorageView<A> storage_view = MakeStorageView();
705
  Pointer<A> const base = storage_view.data;
706
  const SizeType<A> size = storage_view.size;
707
  A& alloc = GetAllocator();
708
  if (new_size <= size) {
709
    // Destroy extra old elements.
710
    DestroyAdapter<A>::DestroyElements(alloc, base + new_size, size - new_size);
711
  } else if (new_size <= storage_view.capacity) {
712
    // Construct new elements in place.
713
    ConstructElements<A>(alloc, base + size, values, new_size - size);
714
  } else {
715
    // Steps:
716
    //  a. Allocate new backing store.
717
    //  b. Construct new elements in new backing store.
718
    //  c. Move existing elements from old backing store to new backing store.
719
    //  d. Destroy all elements in old backing store.
720
    // Use transactional wrappers for the first two steps so we can roll
721
    // back if necessary due to exceptions.
722
    AllocationTransaction<A> allocation_tx(alloc);
723
    SizeType<A> requested_capacity =
724
        ComputeCapacity(storage_view.capacity, new_size);
725
    Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);
726
727
    ConstructionTransaction<A> construction_tx(alloc);
728
    construction_tx.Construct(new_data + size, values, new_size - size);
729
730
    IteratorValueAdapter<A, MoveIterator<A>> move_values(
731
        (MoveIterator<A>(base)));
732
    ConstructElements<A>(alloc, new_data, move_values, size);
733
734
    DestroyAdapter<A>::DestroyElements(alloc, base, size);
735
    std::move(construction_tx).Commit();
736
    DeallocateIfAllocated();
737
    SetAllocation(std::move(allocation_tx).Release());
738
    SetIsAllocated();
739
  }
740
  SetSize(new_size);
741
}
742
743
template <typename T, size_t N, typename A>
744
template <typename ValueAdapter>
745
auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values,
746
                              SizeType<A> insert_count) -> Iterator<A> {
747
  StorageView<A> storage_view = MakeStorageView();
748
749
  auto insert_index = static_cast<SizeType<A>>(
750
      std::distance(ConstIterator<A>(storage_view.data), pos));
751
  SizeType<A> insert_end_index = insert_index + insert_count;
752
  SizeType<A> new_size = storage_view.size + insert_count;
753
754
  if (new_size > storage_view.capacity) {
755
    AllocationTransaction<A> allocation_tx(GetAllocator());
756
    ConstructionTransaction<A> construction_tx(GetAllocator());
757
    ConstructionTransaction<A> move_construction_tx(GetAllocator());
758
759
    IteratorValueAdapter<A, MoveIterator<A>> move_values(
760
        MoveIterator<A>(storage_view.data));
761
762
    SizeType<A> requested_capacity =
763
        ComputeCapacity(storage_view.capacity, new_size);
764
    Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);
765
766
    construction_tx.Construct(new_data + insert_index, values, insert_count);
767
768
    move_construction_tx.Construct(new_data, move_values, insert_index);
769
770
    ConstructElements<A>(GetAllocator(), new_data + insert_end_index,
771
                         move_values, storage_view.size - insert_index);
772
773
    DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
774
                                       storage_view.size);
775
776
    std::move(construction_tx).Commit();
777
    std::move(move_construction_tx).Commit();
778
    DeallocateIfAllocated();
779
    SetAllocation(std::move(allocation_tx).Release());
780
781
    SetAllocatedSize(new_size);
782
    return Iterator<A>(new_data + insert_index);
783
  } else {
784
    SizeType<A> move_construction_destination_index =
785
        (std::max)(insert_end_index, storage_view.size);
786
787
    ConstructionTransaction<A> move_construction_tx(GetAllocator());
788
789
    IteratorValueAdapter<A, MoveIterator<A>> move_construction_values(
790
        MoveIterator<A>(storage_view.data +
791
                        (move_construction_destination_index - insert_count)));
792
    absl::Span<ValueType<A>> move_construction = {
793
        storage_view.data + move_construction_destination_index,
794
        new_size - move_construction_destination_index};
795
796
    Pointer<A> move_assignment_values = storage_view.data + insert_index;
797
    absl::Span<ValueType<A>> move_assignment = {
798
        storage_view.data + insert_end_index,
799
        move_construction_destination_index - insert_end_index};
800
801
    absl::Span<ValueType<A>> insert_assignment = {move_assignment_values,
802
                                                  move_construction.size()};
803
804
    absl::Span<ValueType<A>> insert_construction = {
805
        insert_assignment.data() + insert_assignment.size(),
806
        insert_count - insert_assignment.size()};
807
808
    move_construction_tx.Construct(move_construction.data(),
809
                                   move_construction_values,
810
                                   move_construction.size());
811
812
    for (Pointer<A>
813
             destination = move_assignment.data() + move_assignment.size(),
814
             last_destination = move_assignment.data(),
815
             source = move_assignment_values + move_assignment.size();
816
         ;) {
817
      --destination;
818
      --source;
819
      if (destination < last_destination) break;
820
      *destination = std::move(*source);
821
    }
822
823
    AssignElements<A>(insert_assignment.data(), values,
824
                      insert_assignment.size());
825
826
    ConstructElements<A>(GetAllocator(), insert_construction.data(), values,
827
                         insert_construction.size());
828
829
    std::move(move_construction_tx).Commit();
830
831
    AddSize(insert_count);
832
    return Iterator<A>(storage_view.data + insert_index);
833
  }
834
}
835
836
template <typename T, size_t N, typename A>
837
template <typename... Args>
838
0
auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> {
839
0
  StorageView<A> storage_view = MakeStorageView();
840
0
  const SizeType<A> n = storage_view.size;
841
0
  if (ABSL_PREDICT_TRUE(n != storage_view.capacity)) {
842
    // Fast path; new element fits.
843
0
    Pointer<A> last_ptr = storage_view.data + n;
844
0
    AllocatorTraits<A>::construct(GetAllocator(), last_ptr,
845
0
                                  std::forward<Args>(args)...);
846
0
    AddSize(1);
847
0
    return *last_ptr;
848
0
  }
849
  // TODO(b/173712035): Annotate with musttail attribute to prevent regression.
850
0
  return EmplaceBackSlow(std::forward<Args>(args)...);
851
0
}
Unexecuted instantiation: absl::lts_20240116::status_internal::Payload& absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::EmplaceBack<absl::lts_20240116::status_internal::Payload>(absl::lts_20240116::status_internal::Payload&&)
Unexecuted instantiation: absl::lts_20240116::cord_internal::CordRep*& absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::EmplaceBack<absl::lts_20240116::cord_internal::CordRep* const&>(absl::lts_20240116::cord_internal::CordRep* const&)
852
853
template <typename T, size_t N, typename A>
854
template <typename... Args>
855
0
auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> {
856
0
  StorageView<A> storage_view = MakeStorageView();
857
0
  AllocationTransaction<A> allocation_tx(GetAllocator());
858
0
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
859
0
      MoveIterator<A>(storage_view.data));
860
0
  SizeType<A> requested_capacity = NextCapacity(storage_view.capacity);
861
0
  Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity);
862
0
  Pointer<A> last_ptr = construct_data + storage_view.size;
863
864
  // Construct new element.
865
0
  AllocatorTraits<A>::construct(GetAllocator(), last_ptr,
866
0
                                std::forward<Args>(args)...);
867
  // Move elements from old backing store to new backing store.
868
0
  ABSL_INTERNAL_TRY {
869
0
    ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values,
870
0
                         storage_view.size);
871
0
  }
872
0
  ABSL_INTERNAL_CATCH_ANY {
873
0
    AllocatorTraits<A>::destroy(GetAllocator(), last_ptr);
874
0
    ABSL_INTERNAL_RETHROW;
875
0
  }
876
  // Destroy elements in old backing store.
877
0
  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
878
0
                                     storage_view.size);
879
880
0
  DeallocateIfAllocated();
881
0
  SetAllocation(std::move(allocation_tx).Release());
882
0
  SetIsAllocated();
883
0
  AddSize(1);
884
0
  return *last_ptr;
885
0
}
Unexecuted instantiation: absl::lts_20240116::status_internal::Payload& absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::status_internal::Payload, 1ul, std::__1::allocator<absl::lts_20240116::status_internal::Payload> >::EmplaceBackSlow<absl::lts_20240116::status_internal::Payload>(absl::lts_20240116::status_internal::Payload&&)
Unexecuted instantiation: absl::lts_20240116::cord_internal::CordRep*& absl::lts_20240116::inlined_vector_internal::Storage<absl::lts_20240116::cord_internal::CordRep*, 2ul, std::__1::allocator<absl::lts_20240116::cord_internal::CordRep*> >::EmplaceBackSlow<absl::lts_20240116::cord_internal::CordRep* const&>(absl::lts_20240116::cord_internal::CordRep* const&)
886
887
template <typename T, size_t N, typename A>
888
auto Storage<T, N, A>::Erase(ConstIterator<A> from, ConstIterator<A> to)
889
0
    -> Iterator<A> {
890
0
  StorageView<A> storage_view = MakeStorageView();
891
892
0
  auto erase_size = static_cast<SizeType<A>>(std::distance(from, to));
893
0
  auto erase_index = static_cast<SizeType<A>>(
894
0
      std::distance(ConstIterator<A>(storage_view.data), from));
895
0
  SizeType<A> erase_end_index = erase_index + erase_size;
896
897
0
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
898
0
      MoveIterator<A>(storage_view.data + erase_end_index));
899
900
0
  AssignElements<A>(storage_view.data + erase_index, move_values,
901
0
                    storage_view.size - erase_end_index);
902
903
0
  DestroyAdapter<A>::DestroyElements(
904
0
      GetAllocator(), storage_view.data + (storage_view.size - erase_size),
905
0
      erase_size);
906
907
0
  SubtractSize(erase_size);
908
0
  return Iterator<A>(storage_view.data + erase_index);
909
0
}
910
911
template <typename T, size_t N, typename A>
912
auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void {
913
  StorageView<A> storage_view = MakeStorageView();
914
915
  if (ABSL_PREDICT_FALSE(requested_capacity <= storage_view.capacity)) return;
916
917
  AllocationTransaction<A> allocation_tx(GetAllocator());
918
919
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
920
      MoveIterator<A>(storage_view.data));
921
922
  SizeType<A> new_requested_capacity =
923
      ComputeCapacity(storage_view.capacity, requested_capacity);
924
  Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity);
925
926
  ConstructElements<A>(GetAllocator(), new_data, move_values,
927
                       storage_view.size);
928
929
  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
930
                                     storage_view.size);
931
932
  DeallocateIfAllocated();
933
  SetAllocation(std::move(allocation_tx).Release());
934
  SetIsAllocated();
935
}
936
937
template <typename T, size_t N, typename A>
938
auto Storage<T, N, A>::ShrinkToFit() -> void {
939
  // May only be called on allocated instances!
940
  ABSL_HARDENING_ASSERT(GetIsAllocated());
941
942
  StorageView<A> storage_view{GetAllocatedData(), GetSize(),
943
                              GetAllocatedCapacity()};
944
945
  if (ABSL_PREDICT_FALSE(storage_view.size == storage_view.capacity)) return;
946
947
  AllocationTransaction<A> allocation_tx(GetAllocator());
948
949
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
950
      MoveIterator<A>(storage_view.data));
951
952
  Pointer<A> construct_data;
953
  if (storage_view.size > GetInlinedCapacity()) {
954
    SizeType<A> requested_capacity = storage_view.size;
955
    construct_data = allocation_tx.Allocate(requested_capacity);
956
    if (allocation_tx.GetCapacity() >= storage_view.capacity) {
957
      // Already using the smallest available heap allocation.
958
      return;
959
    }
960
  } else {
961
    construct_data = GetInlinedData();
962
  }
963
964
  ABSL_INTERNAL_TRY {
965
    ConstructElements<A>(GetAllocator(), construct_data, move_values,
966
                         storage_view.size);
967
  }
968
  ABSL_INTERNAL_CATCH_ANY {
969
    SetAllocation({storage_view.data, storage_view.capacity});
970
    ABSL_INTERNAL_RETHROW;
971
  }
972
973
  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
974
                                     storage_view.size);
975
976
  MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data,
977
                               storage_view.capacity);
978
979
  if (allocation_tx.DidAllocate()) {
980
    SetAllocation(std::move(allocation_tx).Release());
981
  } else {
982
    UnsetIsAllocated();
983
  }
984
}
985
986
template <typename T, size_t N, typename A>
987
auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void {
988
  using std::swap;
989
  ABSL_HARDENING_ASSERT(this != other_storage_ptr);
990
991
  if (GetIsAllocated() && other_storage_ptr->GetIsAllocated()) {
992
    swap(data_.allocated, other_storage_ptr->data_.allocated);
993
  } else if (!GetIsAllocated() && !other_storage_ptr->GetIsAllocated()) {
994
    SwapInlinedElements(SwapInlinedElementsPolicy{}, other_storage_ptr);
995
  } else {
996
    Storage* allocated_ptr = this;
997
    Storage* inlined_ptr = other_storage_ptr;
998
    if (!allocated_ptr->GetIsAllocated()) swap(allocated_ptr, inlined_ptr);
999
1000
    StorageView<A> allocated_storage_view{
1001
        allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(),
1002
        allocated_ptr->GetAllocatedCapacity()};
1003
1004
    IteratorValueAdapter<A, MoveIterator<A>> move_values(
1005
        MoveIterator<A>(inlined_ptr->GetInlinedData()));
1006
1007
    ABSL_INTERNAL_TRY {
1008
      ConstructElements<A>(inlined_ptr->GetAllocator(),
1009
                           allocated_ptr->GetInlinedData(), move_values,
1010
                           inlined_ptr->GetSize());
1011
    }
1012
    ABSL_INTERNAL_CATCH_ANY {
1013
      allocated_ptr->SetAllocation(Allocation<A>{
1014
          allocated_storage_view.data, allocated_storage_view.capacity});
1015
      ABSL_INTERNAL_RETHROW;
1016
    }
1017
1018
    DestroyAdapter<A>::DestroyElements(inlined_ptr->GetAllocator(),
1019
                                       inlined_ptr->GetInlinedData(),
1020
                                       inlined_ptr->GetSize());
1021
1022
    inlined_ptr->SetAllocation(Allocation<A>{allocated_storage_view.data,
1023
                                             allocated_storage_view.capacity});
1024
  }
1025
1026
  swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated());
1027
  swap(GetAllocator(), other_storage_ptr->GetAllocator());
1028
}
1029
1030
template <typename T, size_t N, typename A>
1031
void Storage<T, N, A>::SwapN(ElementwiseSwapPolicy, Storage* other,
1032
                             SizeType<A> n) {
1033
  std::swap_ranges(GetInlinedData(), GetInlinedData() + n,
1034
                   other->GetInlinedData());
1035
}
1036
1037
template <typename T, size_t N, typename A>
1038
void Storage<T, N, A>::SwapN(ElementwiseConstructPolicy, Storage* other,
1039
                             SizeType<A> n) {
1040
  Pointer<A> a = GetInlinedData();
1041
  Pointer<A> b = other->GetInlinedData();
1042
  // see note on allocators in `SwapInlinedElements`.
1043
  A& allocator_a = GetAllocator();
1044
  A& allocator_b = other->GetAllocator();
1045
  for (SizeType<A> i = 0; i < n; ++i, ++a, ++b) {
1046
    ValueType<A> tmp(std::move(*a));
1047
1048
    AllocatorTraits<A>::destroy(allocator_a, a);
1049
    AllocatorTraits<A>::construct(allocator_b, a, std::move(*b));
1050
1051
    AllocatorTraits<A>::destroy(allocator_b, b);
1052
    AllocatorTraits<A>::construct(allocator_a, b, std::move(tmp));
1053
  }
1054
}
1055
1056
template <typename T, size_t N, typename A>
1057
void Storage<T, N, A>::SwapInlinedElements(MemcpyPolicy, Storage* other) {
1058
  Data tmp = data_;
1059
  data_ = other->data_;
1060
  other->data_ = tmp;
1061
}
1062
1063
template <typename T, size_t N, typename A>
1064
template <typename NotMemcpyPolicy>
1065
void Storage<T, N, A>::SwapInlinedElements(NotMemcpyPolicy policy,
1066
                                           Storage* other) {
1067
  // Note: `destroy` needs to use pre-swap allocator while `construct` -
1068
  // post-swap allocator. Allocators will be swapped later on outside of
1069
  // `SwapInlinedElements`.
1070
  Storage* small_ptr = this;
1071
  Storage* large_ptr = other;
1072
  if (small_ptr->GetSize() > large_ptr->GetSize()) {
1073
    std::swap(small_ptr, large_ptr);
1074
  }
1075
1076
  auto small_size = small_ptr->GetSize();
1077
  auto diff = large_ptr->GetSize() - small_size;
1078
  SwapN(policy, other, small_size);
1079
1080
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
1081
      MoveIterator<A>(large_ptr->GetInlinedData() + small_size));
1082
1083
  ConstructElements<A>(large_ptr->GetAllocator(),
1084
                       small_ptr->GetInlinedData() + small_size, move_values,
1085
                       diff);
1086
1087
  DestroyAdapter<A>::DestroyElements(large_ptr->GetAllocator(),
1088
                                     large_ptr->GetInlinedData() + small_size,
1089
                                     diff);
1090
}
1091
1092
// End ignore "array-bounds"
1093
#if !defined(__clang__) && defined(__GNUC__)
1094
#pragma GCC diagnostic pop
1095
#endif
1096
1097
}  // namespace inlined_vector_internal
1098
ABSL_NAMESPACE_END
1099
}  // namespace absl
1100
1101
#endif  // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_