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:
Abseil Team 2019-01-25 13:54:06 -08:00 committed by Xiaoyi Zhang
parent 0dffca4e36
commit 5e0dcf72c6

View file

@ -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++);