diff options
Diffstat (limited to 'absl/container/inlined_vector.h')
-rw-r--r-- | absl/container/inlined_vector.h | 94 |
1 files changed, 45 insertions, 49 deletions
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 642dae6cb907..5f3f0095bca8 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -66,12 +66,11 @@ namespace absl { // designed to cover the same API footprint as covered by `std::vector`. template <typename T, size_t N, typename A = std::allocator<T>> class InlinedVector { + static_assert(N > 0, "InlinedVector requires inline capacity greater than 0"); constexpr static typename A::size_type inlined_capacity() { return static_cast<typename A::size_type>(N); } - static_assert(inlined_capacity() > 0, "InlinedVector needs inlined capacity"); - template <typename Iterator> using DisableIfIntegral = absl::enable_if_t<!std::is_integral<Iterator>::value>; @@ -131,7 +130,8 @@ class InlinedVector { InlinedVector(std::initializer_list<value_type> init_list, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { - AppendRange(init_list.begin(), init_list.end()); + AppendRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); } // Creates an inlined vector with elements constructed from the provided @@ -144,7 +144,7 @@ class InlinedVector { InlinedVector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { - AppendRange(first, last); + AppendRange(first, last, IteratorCategory<InputIterator>{}); } // Creates a copy of `other` using `other`'s allocator. @@ -366,7 +366,6 @@ class InlinedVector { // Returns a copy of the allocator of the inlined vector. allocator_type get_allocator() const { return allocator(); } - // --------------------------------------------------------------------------- // InlinedVector Member Mutators // --------------------------------------------------------------------------- @@ -376,7 +375,8 @@ class InlinedVector { // Replaces the contents of the inlined vector with copies of the elements in // the provided `std::initializer_list`. InlinedVector& operator=(std::initializer_list<value_type> init_list) { - AssignRange(init_list.begin(), init_list.end()); + AssignRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); return *this; } @@ -453,14 +453,15 @@ class InlinedVector { // inlined vector with copies of the values in the provided // `std::initializer_list`. void assign(std::initializer_list<value_type> init_list) { - AssignRange(init_list.begin(), init_list.end()); + AssignRange(init_list.begin(), init_list.end(), + IteratorCategory<decltype(init_list.begin())>{}); } // Overload of `InlinedVector::assign()` to replace the contents of the // inlined vector with values constructed from the range [`first`, `last`). template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr> void assign(InputIterator first, InputIterator last) { - AssignRange(first, last); + AssignRange(first, last, IteratorCategory<InputIterator>{}); } // `InlinedVector::resize()` @@ -845,40 +846,28 @@ class InlinedVector { void Destroy(pointer from, pointer to); template <typename Iterator> - void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) { - std::copy(first, last, std::back_inserter(*this)); - } - - template <typename Iterator> void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag); template <typename Iterator> - void AppendRange(Iterator first, Iterator last) { - AppendRange(first, last, IteratorCategory<Iterator>()); - } - - template <typename Iterator> - void AssignRange(Iterator first, Iterator last, std::input_iterator_tag); + void AppendRange(Iterator first, Iterator last, std::input_iterator_tag); template <typename Iterator> void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag); template <typename Iterator> - void AssignRange(Iterator first, Iterator last) { - AssignRange(first, last, IteratorCategory<Iterator>()); - } + void AssignRange(Iterator first, Iterator last, std::input_iterator_tag); iterator InsertWithCount(const_iterator position, size_type n, const_reference v); - template <typename InputIterator> - iterator InsertWithRange(const_iterator position, InputIterator first, - InputIterator last, std::input_iterator_tag); - template <typename ForwardIterator> iterator InsertWithRange(const_iterator position, ForwardIterator first, ForwardIterator last, std::forward_iterator_tag); + template <typename InputIterator> + iterator InsertWithRange(const_iterator position, InputIterator first, + InputIterator last, std::input_iterator_tag); + // Stores either the inlined or allocated representation union Rep { using ValueTypeBuffer = @@ -889,7 +878,7 @@ class InlinedVector { // Structs wrap the buffers to perform indirection that solves a bizarre // compilation error on Visual Studio (all known versions). struct InlinedRep { - ValueTypeBuffer inlined[inlined_capacity()]; + ValueTypeBuffer inlined[N]; }; struct AllocatedRep { AllocationBuffer allocation; @@ -1364,15 +1353,8 @@ void InlinedVector<T, N, A>::AppendRange(Iterator first, Iterator last, template <typename T, size_t N, typename A> template <typename Iterator> -void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last, +void InlinedVector<T, N, A>::AppendRange(Iterator first, Iterator last, std::input_iterator_tag) { - // Optimized to avoid reallocation. - // Prefer reassignment to copy construction for elements. - iterator out = begin(); - for (; first != last && out != end(); ++first, ++out) { - *out = *first; - } - erase(out, end()); std::copy(first, last, std::back_inserter(*this)); } @@ -1399,6 +1381,20 @@ void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last, } template <typename T, size_t N, typename A> +template <typename Iterator> +void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last, + std::input_iterator_tag) { + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + iterator out = begin(); + for (; first != last && out != end(); ++first, ++out) { + *out = *first; + } + erase(out, end()); + std::copy(first, last, std::back_inserter(*this)); +} + +template <typename T, size_t N, typename A> auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position, size_type n, const_reference v) -> iterator { @@ -1414,20 +1410,6 @@ auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position, } template <typename T, size_t N, typename A> -template <typename InputIterator> -auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, - InputIterator first, - InputIterator last, - std::input_iterator_tag) - -> iterator { - assert(position >= begin() && position <= end()); - size_type index = position - cbegin(); - size_type i = index; - while (first != last) insert(begin() + i++, *first++); - return begin() + index; -} - -template <typename T, size_t N, typename A> template <typename ForwardIterator> auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, ForwardIterator first, @@ -1446,6 +1428,20 @@ auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, return it_pair.first; } +template <typename T, size_t N, typename A> +template <typename InputIterator> +auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position, + InputIterator first, + InputIterator last, + std::input_iterator_tag) + -> iterator { + assert(position >= begin() && position <= end()); + size_type index = position - cbegin(); + size_type i = index; + while (first != last) insert(begin() + i++, *first++); + return begin() + index; +} + } // namespace absl #endif // ABSL_CONTAINER_INLINED_VECTOR_H_ |