Index: libcxx/test/std/containers/sequences/vector/access.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/access.pass.cpp +++ libcxx/test/std/containers/sequences/vector/access.pass.cpp @@ -27,7 +27,17 @@ #include "min_allocator.h" #include "test_macros.h" -template +struct EqComparable { + int value; + + EqComparable(int v) : value(v) {} + + friend bool operator==(const EqComparable& lhs, const EqComparable& rhs) { + return lhs.value == rhs.value; + } +}; + +template C make(int size, int start = 0) { @@ -37,84 +47,85 @@ return c; } -int main(int, char**) -{ - { - typedef std::vector C; - C c = make(10); - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(c.front()); - LIBCPP_ASSERT_NOEXCEPT(c.back()); - // at() is NOT noexcept - ASSERT_SAME_TYPE(C::reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::reference, decltype(c.at(0))); - ASSERT_SAME_TYPE(C::reference, decltype(c.front())); - ASSERT_SAME_TYPE(C::reference, decltype(c.back())); - for (int i = 0; i < 10; ++i) - assert(c[i] == i); - for (int i = 0; i < 10; ++i) - assert(c.at(i) == i); - assert(c.front() == 0); - assert(c.back() == 9); +template +void test_get_basic(Vector& c, int N = 0) { + for (int i = 0; i < 10; ++i) + assert(c[i] == N + i); + for (int i = 0; i < 10; ++i) + assert(c.at(i) == N + i); + +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + c.at(10); + assert(false); + } catch (std::out_of_range&) {} +#endif + + assert(c.front() == N); + assert(c.back() == N + 9); +} + +template +void test_get(int N = 0) { + Vector c = make(10, N); + const Vector& cc = c; + test_get_basic(c, N); + test_get_basic(cc, N); +} + +template +void test_set(int N = 0) { + Vector c = make(10, N); + + for (int i = 0; i < 10; ++i) { + assert(c[i] == N + i); + c[i] = N + i + 1; + assert(c[i] == N + i + 1); } - { - typedef std::vector C; - const int N = 5; - const C c = make(10, N); - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(c.front()); - LIBCPP_ASSERT_NOEXCEPT(c.back()); - // at() is NOT noexcept - ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.at(0))); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.front())); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.back())); - for (int i = 0; i < 10; ++i) - assert(c[i] == N + i); - for (int i = 0; i < 10; ++i) - assert(c.at(i) == N + i); - assert(c.front() == N); - assert(c.back() == N + 9); + for (int i = 0; i < 10; ++i) { + assert(c.at(i) == N + i + 1); + c.at(i) = N + i + 2; + assert(c.at(i) == N + i + 2); } + + assert(c.front() == N + 2); + c.front() = N + 3; + assert(c.front() == N + 3); + + assert(c.back() == N + 9 + 2); + c.back() = N + 9 + 3; + assert(c.back() == N + 9 + 3); +} + +template +void test() { + test_get(); + test_set(); + + test_get(36); + test_set(36); + + Vector c; + const Vector& cc = c; + ASSERT_SAME_TYPE(typename Vector::reference, decltype(c[0])); + ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc[0])); + + ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.at(0))); + ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.at(0))); + + ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.front())); + ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.front())); + + ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.back())); + ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.back())); +} + +int main(int, char**) +{ + test>(); + test>(); #if TEST_STD_VER >= 11 - { - typedef std::vector> C; - const int N = 34; - C c = make(10, N); - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(c.front()); - LIBCPP_ASSERT_NOEXCEPT(c.back()); - // at() is NOT noexcept - ASSERT_SAME_TYPE(C::reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::reference, decltype(c.at(0))); - ASSERT_SAME_TYPE(C::reference, decltype(c.front())); - ASSERT_SAME_TYPE(C::reference, decltype(c.back())); - for (int i = 0; i < 10; ++i) - assert(c[i] == N + i); - for (int i = 0; i < 10; ++i) - assert(c.at(i) == N + i); - assert(c.front() == N); - assert(c.back() == N + 9); - } - { - typedef std::vector> C; - const int N = 23; - const C c = make(10, N); - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(c.front()); - LIBCPP_ASSERT_NOEXCEPT(c.back()); - // at() is NOT noexcept - ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.at(0))); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.front())); - ASSERT_SAME_TYPE(C::const_reference, decltype(c.back())); - for (int i = 0; i < 10; ++i) - assert(c[i] == N + i); - for (int i = 0; i < 10; ++i) - assert(c.at(i) == N + i); - assert(c.front() == N); - assert(c.back() == N + 9); - } + test>>(); #endif return 0; Index: libcxx/test/std/containers/sequences/vector/reverse_iterators.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/sequences/vector/reverse_iterators.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// reverse_iterator rbegin(); +// reverse_iterator rend(); +// const_reverse_iterator rbegin() const; +// const_reverse_iterator rend() const; +// const_reverse_iterator crbegin() const; +// const_reverse_iterator crend() const; + +#include +#include +#include + +#include "min_allocator.h" + +template +void check_vector_reverse_iterators() { + { + Vector vec; + typename Vector::reverse_iterator i = vec.rbegin(); + typename Vector::reverse_iterator j = vec.rend(); + + assert(std::distance(i, j) == 0); + assert(i == j); + + typename Vector::const_reverse_iterator ci = vec.crbegin(); + typename Vector::const_reverse_iterator cj = vec.crend(); + + assert(std::distance(ci, cj) == 0); + assert(ci == cj); + } + { + Vector vec; + const Vector& cvec = vec; + vec.reserve(10); + for (int i = 0; i < 10; ++i) + vec.push_back(i); + { + int iterations = 0; + + for (typename Vector::const_reverse_iterator it = vec.crbegin(); it != vec.crend(); ++it) { + assert(*it == (10 - iterations - 1)); + ++iterations; + } + assert(iterations == 10); + } + { + int iterations = 0; + + for (typename Vector::const_reverse_iterator it = cvec.rbegin(); it != cvec.rend(); ++it) { + assert(*it == (10 - iterations - 1)); + ++iterations; + } + assert(iterations == 10); + } + { + int iterations = 0; + + for (typename Vector::reverse_iterator it = vec.rbegin(); it != vec.rend(); ++it) { + assert(*it == (10 - iterations - 1)); + *it = 40; + assert(*it == 40); + ++iterations; + } + assert(iterations == 10); + } + + assert(std::distance(vec.rbegin(), vec.rend()) == 10); + assert(std::distance(cvec.rbegin(), cvec.rend()) == 10); + assert(std::distance(vec.crbegin(), vec.crend()) == 10); + } +} + +int main(int, char**) { + check_vector_reverse_iterators >(); + check_vector_reverse_iterators > >(); + + return 0; +} Index: libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -48,6 +48,37 @@ assert(v.capacity() == 150); assert(is_contiguous_container_asan_correct(v)); } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::vector v; + size_t sz = v.max_size() + 1; + + try { + v.reserve(sz); + assert(false); + } catch (std::length_error&) { + assert(v.size() == 0); + assert(v.capacity() == 0); + } + } + { + std::vector v(10, 0); + size_t previous_capacity = v.capacity(); + size_t sz = v.max_size() + 1; + + try { + v.reserve(sz); + assert(false); + } catch (std::length_error&) { + assert(v.size() == 10); + assert(v.capacity() == previous_capacity); + + for (int i = 0; i < 10; ++i) { + assert(v[i] == 0); + } + } + } +#endif #if TEST_STD_VER >= 11 { std::vector> v; Index: libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp @@ -32,6 +32,14 @@ assert(l2 == l); assert(l2.get_allocator() == other_allocator(5)); } + { + // Test copy assignment with equal allocator objects + std::vector> l(3, 2, other_allocator(3)); + std::vector> l2(l, other_allocator(3)); + l2 = l; + assert(l2 == l); + assert(l2.get_allocator() == other_allocator(3)); + } #if TEST_STD_VER >= 11 { std::vector > l(3, 2, min_allocator()); Index: libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp @@ -57,6 +57,19 @@ assert(v[0] == 3); assert(is_contiguous_container_asan_correct(v)); } + { + const size_t reserve = 8; + const size_t size = 4; + const int value = 160; + std::vector v; + v.reserve(reserve); + v.resize(size); + v.emplace(v.cend(), value); + + assert(v.size() == size + 1); + assert(v.capacity() == reserve); + assert(v[size] == value); + } return 0; } Index: libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -23,7 +23,8 @@ { { std::vector v(100); - std::vector::iterator i = v.insert(v.cbegin() + 10, 1); + const int value = 1; + std::vector::iterator i = v.insert(v.cbegin() + 10, value); assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); @@ -34,11 +35,29 @@ for (++j; j < 101; ++j) assert(v[j] == 0); } + { + const size_t size = 100; + std::vector v(size); + v.reserve(size + 1); + const int value = 1; + + // no reallocation expected + std::vector::iterator it = v.insert(v.cbegin() + size, value); + + assert(v.size() == size + 1); + assert(is_contiguous_container_asan_correct(v)); + assert(it == v.begin() + size); + for (size_t i = 0; i < size; ++i) { + assert(v[i] == 0); + } + assert(v[size] == value); + } { std::vector v(100); while(v.size() < v.capacity()) v.push_back(0); // force reallocation size_t sz = v.size(); - std::vector::iterator i = v.insert(v.cbegin() + 10, 1); + const int value = 1; + std::vector::iterator i = v.insert(v.cbegin() + 10, value); assert(v.size() == sz + 1); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); @@ -54,7 +73,8 @@ while(v.size() < v.capacity()) v.push_back(0); v.pop_back(); v.pop_back(); // force no reallocation size_t sz = v.size(); - std::vector::iterator i = v.insert(v.cbegin() + 10, 1); + const int value = 1; + std::vector::iterator i = v.insert(v.cbegin() + 10, value); assert(v.size() == sz + 1); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); @@ -67,7 +87,8 @@ } { std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, 1); + const int value = 1; + std::vector >::iterator i = v.insert(v.cbegin() + 10, value); assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); @@ -81,7 +102,8 @@ #if TEST_STD_VER >= 11 { std::vector> v(100); - std::vector>::iterator i = v.insert(v.cbegin() + 10, 1); + const int value = 1; + std::vector>::iterator i = v.insert(v.cbegin() + 10, value); assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10);