Export of internal Abseil changes.
-- a9115ecdf91183528f677fbbd9294652ab68c35f by CJ Johnson <johnsoncj@google.com>: Shorten the names of the args of the public InlinedVector member functions PiperOrigin-RevId: 230963027 -- 93eaa2e3826901bafd16b088c8b5b272a2650fbb by CJ Johnson <johnsoncj@google.com>: Elevates input/forward iterator type checking to the top level of the InlinedVector API PiperOrigin-RevId: 230771558 GitOrigin-RevId: a9115ecdf91183528f677fbbd9294652ab68c35f Change-Id: I30524e1a2a6260c6947a7ad756caade9b0b2c82f
This commit is contained in:
parent
0dffca4e36
commit
5e0dcf72c6
1 changed files with 103 additions and 69 deletions
|
@ -135,25 +135,35 @@ class InlinedVector {
|
||||||
InitAssign(n, v);
|
InitAssign(n, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an inlined vector of copies of the values in `init_list`.
|
// Creates an inlined vector of copies of the values in `list`.
|
||||||
InlinedVector(std::initializer_list<value_type> init_list,
|
InlinedVector(std::initializer_list<value_type> list,
|
||||||
const allocator_type& alloc = allocator_type())
|
const allocator_type& alloc = allocator_type())
|
||||||
: allocator_and_tag_(alloc) {
|
: allocator_and_tag_(alloc) {
|
||||||
AppendRange(init_list.begin(), init_list.end());
|
AppendForwardRange(list.begin(), list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an inlined vector with elements constructed from the provided
|
// Creates an inlined vector with elements constructed from the provided
|
||||||
// Iterator range [`first`, `last`).
|
// forward iterator range [`first`, `last`).
|
||||||
//
|
//
|
||||||
// NOTE: The `enable_if` prevents ambiguous interpretation between a call to
|
// NOTE: The `enable_if` prevents ambiguous interpretation between a call to
|
||||||
// this constructor with two integral arguments and a call to the above
|
// this constructor with two integral arguments and a call to the above
|
||||||
// `InlinedVector(size_type, const_reference)` constructor.
|
// `InlinedVector(size_type, const_reference)` constructor.
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
||||||
|
InlinedVector(ForwardIterator first, ForwardIterator last,
|
||||||
|
const allocator_type& alloc = allocator_type())
|
||||||
|
: allocator_and_tag_(alloc) {
|
||||||
|
AppendForwardRange(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an inlined vector with elements constructed from the provided input
|
||||||
|
// iterator range [`first`, `last`).
|
||||||
template <typename InputIterator,
|
template <typename InputIterator,
|
||||||
EnableIfAtLeastInputIterator<InputIterator>* = nullptr>
|
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
||||||
InlinedVector(InputIterator first, InputIterator last,
|
InlinedVector(InputIterator first, InputIterator last,
|
||||||
const allocator_type& alloc = allocator_type())
|
const allocator_type& alloc = allocator_type())
|
||||||
: allocator_and_tag_(alloc) {
|
: allocator_and_tag_(alloc) {
|
||||||
AppendRange(first, last);
|
AppendInputRange(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a copy of `other` using `other`'s allocator.
|
// Creates a copy of `other` using `other`'s allocator.
|
||||||
|
@ -430,8 +440,8 @@ class InlinedVector {
|
||||||
//
|
//
|
||||||
// Replaces the contents of the inlined vector with copies of the elements in
|
// Replaces the contents of the inlined vector with copies of the elements in
|
||||||
// the provided `std::initializer_list`.
|
// the provided `std::initializer_list`.
|
||||||
InlinedVector& operator=(std::initializer_list<value_type> init_list) {
|
InlinedVector& operator=(std::initializer_list<value_type> list) {
|
||||||
AssignRange(init_list.begin(), init_list.end());
|
AssignForwardRange(list.begin(), list.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,16 +517,24 @@ class InlinedVector {
|
||||||
// Overload of `InlinedVector::assign()` to replace the contents of the
|
// Overload of `InlinedVector::assign()` to replace the contents of the
|
||||||
// inlined vector with copies of the values in the provided
|
// inlined vector with copies of the values in the provided
|
||||||
// `std::initializer_list`.
|
// `std::initializer_list`.
|
||||||
void assign(std::initializer_list<value_type> init_list) {
|
void assign(std::initializer_list<value_type> list) {
|
||||||
AssignRange(init_list.begin(), init_list.end());
|
AssignForwardRange(list.begin(), list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::assign()` to replace the contents of the
|
// Overload of `InlinedVector::assign()` to replace the contents of the
|
||||||
// inlined vector with values constructed from the range [`first`, `last`).
|
// inlined vector with the forward iterator range [`first`, `last`).
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
||||||
|
void assign(ForwardIterator first, ForwardIterator last) {
|
||||||
|
AssignForwardRange(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload of `InlinedVector::assign()` to replace the contents of the
|
||||||
|
// inlined vector with the input iterator range [`first`, `last`).
|
||||||
template <typename InputIterator,
|
template <typename InputIterator,
|
||||||
EnableIfAtLeastInputIterator<InputIterator>* = nullptr>
|
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
||||||
void assign(InputIterator first, InputIterator last) {
|
void assign(InputIterator first, InputIterator last) {
|
||||||
AssignRange(first, last);
|
AssignInputRange(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `InlinedVector::resize()`
|
// `InlinedVector::resize()`
|
||||||
|
@ -567,62 +585,70 @@ class InlinedVector {
|
||||||
|
|
||||||
// `InlinedVector::insert()`
|
// `InlinedVector::insert()`
|
||||||
//
|
//
|
||||||
// Copies `v` into `position`, returning an `iterator` pointing to the newly
|
// Copies `v` into `pos`, returning an `iterator` pointing to the newly
|
||||||
// inserted element.
|
// inserted element.
|
||||||
iterator insert(const_iterator position, const_reference v) {
|
iterator insert(const_iterator pos, const_reference v) {
|
||||||
return emplace(position, v);
|
return emplace(pos, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::insert()` for moving `v` into `position`,
|
// Overload of `InlinedVector::insert()` for moving `v` into `pos`, returning
|
||||||
// returning an iterator pointing to the newly inserted element.
|
// an iterator pointing to the newly inserted element.
|
||||||
iterator insert(const_iterator position, rvalue_reference v) {
|
iterator insert(const_iterator pos, rvalue_reference v) {
|
||||||
return emplace(position, std::move(v));
|
return emplace(pos, std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::insert()` for inserting `n` contiguous copies
|
// Overload of `InlinedVector::insert()` for inserting `n` contiguous copies
|
||||||
// of `v` starting at `position`. Returns an `iterator` pointing to the first
|
// of `v` starting at `pos`. Returns an `iterator` pointing to the first of
|
||||||
// of the newly inserted elements.
|
// the newly inserted elements.
|
||||||
iterator insert(const_iterator position, size_type n, const_reference v) {
|
iterator insert(const_iterator pos, size_type n, const_reference v) {
|
||||||
return InsertWithCount(position, n, v);
|
return InsertWithCount(pos, n, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::insert()` for copying the contents of the
|
// Overload of `InlinedVector::insert()` for copying the contents of the
|
||||||
// `std::initializer_list` into the vector starting at `position`. Returns an
|
// `std::initializer_list` into the vector starting at `pos`. Returns an
|
||||||
// `iterator` pointing to the first of the newly inserted elements.
|
// `iterator` pointing to the first of the newly inserted elements.
|
||||||
iterator insert(const_iterator position,
|
iterator insert(const_iterator pos, std::initializer_list<value_type> list) {
|
||||||
std::initializer_list<value_type> init_list) {
|
return insert(pos, list.begin(), list.end());
|
||||||
return insert(position, init_list.begin(), init_list.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::insert()` for inserting elements constructed
|
// Overload of `InlinedVector::insert()` for inserting elements constructed
|
||||||
// from the range [`first`, `last`). Returns an `iterator` pointing to the
|
// from the forward iterator range [`first`, `last`). Returns an `iterator`
|
||||||
// first of the newly inserted elements.
|
// pointing to the first of the newly inserted elements.
|
||||||
//
|
//
|
||||||
// NOTE: The `enable_if` is intended to disambiguate the two three-argument
|
// NOTE: The `enable_if` is intended to disambiguate the two three-argument
|
||||||
// overloads of `insert()`.
|
// overloads of `insert()`.
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
||||||
|
iterator insert(const_iterator pos, ForwardIterator first,
|
||||||
|
ForwardIterator last) {
|
||||||
|
return InsertWithForwardRange(pos, first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload of `InlinedVector::insert()` for inserting elements constructed
|
||||||
|
// from the input iterator range [`first`, `last`). Returns an `iterator`
|
||||||
|
// pointing to the first of the newly inserted elements.
|
||||||
template <typename InputIterator,
|
template <typename InputIterator,
|
||||||
EnableIfAtLeastInputIterator<InputIterator>* = nullptr>
|
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
||||||
iterator insert(const_iterator position, InputIterator first,
|
iterator insert(const_iterator pos, InputIterator first, InputIterator last) {
|
||||||
InputIterator last) {
|
return InsertWithInputRange(pos, first, last);
|
||||||
return InsertWithRange(position, first, last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `InlinedVector::emplace()`
|
// `InlinedVector::emplace()`
|
||||||
//
|
//
|
||||||
// Constructs and inserts an object in the inlined vector at the given
|
// Constructs and inserts an object in the inlined vector at the given `pos`,
|
||||||
// `position`, returning an `iterator` pointing to the newly emplaced element.
|
// returning an `iterator` pointing to the newly emplaced element.
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
iterator emplace(const_iterator position, Args&&... args) {
|
iterator emplace(const_iterator pos, Args&&... args) {
|
||||||
assert(position >= begin());
|
assert(pos >= begin());
|
||||||
assert(position <= end());
|
assert(pos <= end());
|
||||||
if (ABSL_PREDICT_FALSE(position == end())) {
|
if (ABSL_PREDICT_FALSE(pos == end())) {
|
||||||
emplace_back(std::forward<Args>(args)...);
|
emplace_back(std::forward<Args>(args)...);
|
||||||
return end() - 1;
|
return end() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
T new_t = T(std::forward<Args>(args)...);
|
T new_t = T(std::forward<Args>(args)...);
|
||||||
|
|
||||||
auto range = ShiftRight(position, 1);
|
auto range = ShiftRight(pos, 1);
|
||||||
if (range.first == range.second) {
|
if (range.first == range.second) {
|
||||||
// constructing into uninitialized memory
|
// constructing into uninitialized memory
|
||||||
Construct(range.first, std::move(new_t));
|
Construct(range.first, std::move(new_t));
|
||||||
|
@ -687,18 +713,18 @@ class InlinedVector {
|
||||||
|
|
||||||
// `InlinedVector::erase()`
|
// `InlinedVector::erase()`
|
||||||
//
|
//
|
||||||
// Erases the element at `position` of the inlined vector, returning an
|
// Erases the element at `pos` of the inlined vector, returning an `iterator`
|
||||||
// `iterator` pointing to the first element following the erased element.
|
// pointing to the first element following the erased element.
|
||||||
//
|
//
|
||||||
// NOTE: May return the end iterator, which is not dereferencable.
|
// NOTE: May return the end iterator, which is not dereferencable.
|
||||||
iterator erase(const_iterator position) {
|
iterator erase(const_iterator pos) {
|
||||||
assert(position >= begin());
|
assert(pos >= begin());
|
||||||
assert(position < end());
|
assert(pos < end());
|
||||||
|
|
||||||
iterator pos = const_cast<iterator>(position);
|
iterator position = const_cast<iterator>(pos);
|
||||||
std::move(pos + 1, end(), pos);
|
std::move(position + 1, end(), position);
|
||||||
pop_back();
|
pop_back();
|
||||||
return pos;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload of `InlinedVector::erase()` for erasing all elements in the
|
// Overload of `InlinedVector::erase()` for erasing all elements in the
|
||||||
|
@ -1084,15 +1110,18 @@ class InlinedVector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
template <typename ForwardIterator>
|
||||||
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
void AssignForwardRange(ForwardIterator first, ForwardIterator last) {
|
||||||
void AssignRange(ForwardIterator first, ForwardIterator last) {
|
static_assert(IsAtLeastForwardIterator<ForwardIterator>::value, "");
|
||||||
|
|
||||||
auto length = std::distance(first, last);
|
auto length = std::distance(first, last);
|
||||||
|
|
||||||
// Prefer reassignment to copy construction for elements.
|
// Prefer reassignment to copy construction for elements.
|
||||||
if (static_cast<size_type>(length) <= size()) {
|
if (static_cast<size_type>(length) <= size()) {
|
||||||
erase(std::copy(first, last, begin()), end());
|
erase(std::copy(first, last, begin()), end());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve(length);
|
reserve(length);
|
||||||
iterator out = begin();
|
iterator out = begin();
|
||||||
for (; out != end(); ++first, ++out) *out = *first;
|
for (; out != end(); ++first, ++out) *out = *first;
|
||||||
|
@ -1105,9 +1134,10 @@ class InlinedVector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIterator,
|
template <typename InputIterator>
|
||||||
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
void AssignInputRange(InputIterator first, InputIterator last) {
|
||||||
void AssignRange(InputIterator first, InputIterator last) {
|
static_assert(IsAtLeastInputIterator<InputIterator>::value, "");
|
||||||
|
|
||||||
// Optimized to avoid reallocation.
|
// Optimized to avoid reallocation.
|
||||||
// Prefer reassignment to copy construction for elements.
|
// Prefer reassignment to copy construction for elements.
|
||||||
iterator out = begin();
|
iterator out = begin();
|
||||||
|
@ -1118,9 +1148,10 @@ class InlinedVector {
|
||||||
std::copy(first, last, std::back_inserter(*this));
|
std::copy(first, last, std::back_inserter(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
template <typename ForwardIterator>
|
||||||
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
void AppendForwardRange(ForwardIterator first, ForwardIterator last) {
|
||||||
void AppendRange(ForwardIterator first, ForwardIterator last) {
|
static_assert(IsAtLeastForwardIterator<ForwardIterator>::value, "");
|
||||||
|
|
||||||
auto length = std::distance(first, last);
|
auto length = std::distance(first, last);
|
||||||
reserve(size() + length);
|
reserve(size() + length);
|
||||||
if (allocated()) {
|
if (allocated()) {
|
||||||
|
@ -1132,9 +1163,10 @@ class InlinedVector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIterator,
|
template <typename InputIterator>
|
||||||
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
void AppendInputRange(InputIterator first, InputIterator last) {
|
||||||
void AppendRange(InputIterator first, InputIterator last) {
|
static_assert(IsAtLeastInputIterator<InputIterator>::value, "");
|
||||||
|
|
||||||
std::copy(first, last, std::back_inserter(*this));
|
std::copy(first, last, std::back_inserter(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,11 +1183,12 @@ class InlinedVector {
|
||||||
return it_pair.first;
|
return it_pair.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
template <typename ForwardIterator>
|
||||||
EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
|
iterator InsertWithForwardRange(const_iterator position,
|
||||||
iterator InsertWithRange(const_iterator position, ForwardIterator first,
|
ForwardIterator first, ForwardIterator last) {
|
||||||
ForwardIterator last) {
|
static_assert(IsAtLeastForwardIterator<ForwardIterator>::value, "");
|
||||||
assert(position >= begin() && position <= end());
|
assert(position >= begin() && position <= end());
|
||||||
|
|
||||||
if (ABSL_PREDICT_FALSE(first == last))
|
if (ABSL_PREDICT_FALSE(first == last))
|
||||||
return const_cast<iterator>(position);
|
return const_cast<iterator>(position);
|
||||||
|
|
||||||
|
@ -1168,11 +1201,12 @@ class InlinedVector {
|
||||||
return it_pair.first;
|
return it_pair.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIterator,
|
template <typename InputIterator>
|
||||||
DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
|
iterator InsertWithInputRange(const_iterator position, InputIterator first,
|
||||||
iterator InsertWithRange(const_iterator position, InputIterator first,
|
|
||||||
InputIterator last) {
|
InputIterator last) {
|
||||||
|
static_assert(IsAtLeastInputIterator<InputIterator>::value, "");
|
||||||
assert(position >= begin() && position <= end());
|
assert(position >= begin() && position <= end());
|
||||||
|
|
||||||
size_type index = position - cbegin();
|
size_type index = position - cbegin();
|
||||||
size_type i = index;
|
size_type i = index;
|
||||||
while (first != last) insert(begin() + i++, *first++);
|
while (first != last) insert(begin() + i++, *first++);
|
||||||
|
|
Loading…
Reference in a new issue