diff --git a/test/boost/chunked_vector_test.cc b/test/boost/chunked_vector_test.cc index 262e3e2a32..2fcb33cc8d 100644 --- a/test/boost/chunked_vector_test.cc +++ b/test/boost/chunked_vector_test.cc @@ -32,7 +32,7 @@ using deque = std::deque; BOOST_AUTO_TEST_CASE(test_random_walk) { auto rand = std::default_random_engine(); - auto op_gen = std::uniform_int_distribution(0, 9); + auto op_gen = std::uniform_int_distribution(0, 10); auto nr_dist = std::geometric_distribution(0.7); deque d; disk_array c; @@ -105,6 +105,13 @@ BOOST_AUTO_TEST_CASE(test_random_walk) { d.resize(nr); break; } + case 10: { + auto pos = std::uniform_int_distribution(0, d.size())(rand); + auto n = rand(); + c.insert(c.begin() + pos, n); + d.insert(d.begin() + pos, n); + break; + } default: abort(); } @@ -467,3 +474,37 @@ BOOST_AUTO_TEST_CASE(test_value_init_ctor) { BOOST_REQUIRE_EQUAL(*it, v); } } + +BOOST_AUTO_TEST_CASE(test_insert_single) { + auto vec = utils::chunked_vector(); + auto r1 = vec.insert(vec.begin(), 1); + BOOST_REQUIRE_EQUAL(vec.size(), 1); + BOOST_REQUIRE_EQUAL(r1 - std::begin(vec), 0); + BOOST_REQUIRE_EQUAL(vec[0], 1); + auto r2 = vec.insert(vec.begin(), 2); + BOOST_REQUIRE_EQUAL(vec.size(), 2); + BOOST_REQUIRE_EQUAL(r2 - std::begin(vec), 0); + BOOST_REQUIRE_EQUAL(vec[0], 2); + BOOST_REQUIRE_EQUAL(vec[1], 1); + auto r3 = vec.insert(vec.end(), 3); + BOOST_REQUIRE_EQUAL(vec.size(), 3); + BOOST_REQUIRE_EQUAL(r3 - std::begin(vec), 2); + BOOST_REQUIRE_EQUAL(vec[0], 2); + BOOST_REQUIRE_EQUAL(vec[1], 1); + BOOST_REQUIRE_EQUAL(vec[2], 3); + auto r4 = vec.insert(vec.end() - 2, 4); + BOOST_REQUIRE_EQUAL(vec.size(), 4); + BOOST_REQUIRE_EQUAL(r4 - std::begin(vec), 1); + BOOST_REQUIRE_EQUAL(vec[0], 2); + BOOST_REQUIRE_EQUAL(vec[1], 4); + BOOST_REQUIRE_EQUAL(vec[2], 1); + BOOST_REQUIRE_EQUAL(vec[3], 3); + auto r5 = vec.emplace(vec.end() - 2, 6); + BOOST_REQUIRE_EQUAL(vec.size(), 5); + BOOST_REQUIRE_EQUAL(r5 - std::begin(vec), 2); + BOOST_REQUIRE_EQUAL(vec[0], 2); + BOOST_REQUIRE_EQUAL(vec[1], 4); + BOOST_REQUIRE_EQUAL(vec[2], 6); + BOOST_REQUIRE_EQUAL(vec[3], 1); + BOOST_REQUIRE_EQUAL(vec[4], 3); +} \ No newline at end of file diff --git a/utils/chunked_vector.hh b/utils/chunked_vector.hh index b13cc45eb7..9caca674c5 100644 --- a/utils/chunked_vector.hh +++ b/utils/chunked_vector.hh @@ -321,6 +321,11 @@ public: bool operator==(const chunked_vector& x) const { return std::ranges::equal(*this, x); } +public: + iterator insert(const_iterator pos, const T& x); + iterator insert(const_iterator pos, T&& x); + template + iterator emplace(const_iterator pos, Args&&... args); }; template @@ -595,6 +600,34 @@ chunked_vector::clear() { shrink_to_fit(); } +template +typename chunked_vector::iterator +chunked_vector::insert(const_iterator pos, const T& x) { + auto insert_idx = pos - begin(); + push_back(x); + std::rotate(begin() + insert_idx, end() - 1, end()); + return begin() + insert_idx; +} + +template +typename chunked_vector::iterator +chunked_vector::insert(const_iterator pos, T&& x) { + auto insert_idx = pos - begin(); + push_back(std::move(x)); + std::rotate(begin() + insert_idx, end() - 1, end()); + return begin() + insert_idx; +} + +template +template +typename chunked_vector::iterator +chunked_vector::emplace(const_iterator pos, Args&&... args) { + auto insert_idx = pos - begin(); + emplace_back(std::forward(args)...); + std::rotate(begin() + insert_idx, end() - 1, end()); + return begin() + insert_idx; +} + template std::ostream& operator<<(std::ostream& os, const chunked_vector& v) { fmt::print(os, "{}", v);