diff --git a/include/beman/inplace_vector/inplace_vector.hpp b/include/beman/inplace_vector/inplace_vector.hpp index 413a27b..f2c7b0d 100644 --- a/include/beman/inplace_vector/inplace_vector.hpp +++ b/include/beman/inplace_vector/inplace_vector.hpp @@ -475,6 +475,18 @@ struct inplace_vector } } + template R> + constexpr std::ranges::borrowed_iterator_t try_append_range(R &&rg) + requires(std::constructible_from>) + { + auto it = std::ranges::begin(rg); + const auto end = std::ranges::end(rg); + for (; size() != capacity() && it != end; ++it) { + unchecked_emplace_back(*it); + } + return it; + } + template constexpr iterator emplace(const_iterator position, Args &&...args) requires(std::constructible_from && std::movable) @@ -717,6 +729,15 @@ struct inplace_vector return *this; } + constexpr inplace_vector &operator=(std::initializer_list il) + requires(std::constructible_from< + T, std::ranges::range_reference_t>> && + std::movable) + { + assign_range(il); + return *this; + } + constexpr void swap(inplace_vector &x) noexcept(N == 0 || (std::is_nothrow_swappable_v && diff --git a/tests/beman/inplace_vector/CMakeLists.txt b/tests/beman/inplace_vector/CMakeLists.txt index a746209..1d80ab2 100644 --- a/tests/beman/inplace_vector/CMakeLists.txt +++ b/tests/beman/inplace_vector/CMakeLists.txt @@ -41,6 +41,7 @@ add_gtest(compare) add_gtest(constructors) add_gtest(size_n_data) add_gtest(erasure) +add_gtest(modifiers) # constexpr test add_executable(beman.inplace_vector.tests.constexpr constexpr.test.cpp) diff --git a/tests/beman/inplace_vector/modifiers.test.cpp b/tests/beman/inplace_vector/modifiers.test.cpp index f29658f..bee74d1 100644 --- a/tests/beman/inplace_vector/modifiers.test.cpp +++ b/tests/beman/inplace_vector/modifiers.test.cpp @@ -1,6 +1,7 @@ -#include +#include #include "gtest_setup.hpp" +#include namespace { // 23.3.14.5 Modifiers [inplace.vector.modifiers] @@ -581,8 +582,41 @@ TYPED_TEST(Modifiers, TryAppendRanges) { // elements in the range begin() + [0, n) are not modified, and elements in // the range begin() + [n, n + k) correspond to the inserted elements. - // TODO - GTEST_SKIP(); + using IV = TestFixture::IV; + using T = TestFixture::T; + using size_type = IV::size_type; + + IV device; + auto reference = this->unique(); + + device.try_append_range(reference | std::views::take(0)); + EXPECT_EQ(device, IV()); + device.clear(); + + EXPECT_EQ(device.try_append_range(reference), reference.end()); + EXPECT_EQ(device, reference); + EXPECT_EQ(device.try_append_range(reference), reference.begin()); + device.clear(); + + auto range = std::array{}; + std::copy_n(reference.begin(), IV::capacity(), range.begin()); + EXPECT_EQ(device.try_append_range(range), range.end() - 1); + EXPECT_EQ(device, reference); + device.clear(); + + auto half_size = std::midpoint(size_type(0), reference.size()); + EXPECT_EQ(device.try_append_range(reference | std::views::take(half_size)), + reference.begin() + half_size); + EXPECT_EQ(device.try_append_range(reference | std::views::drop(half_size)), + reference.end()); + EXPECT_EQ(device, reference); + + device.clear(); + + EXPECT_EQ(device.try_append_range(reference | std::views::drop(half_size)), + reference.end()); + EXPECT_EQ(device.try_append_range(reference), reference.begin() + half_size); + device.clear(); } TYPED_TEST(Modifiers, UncheckedEmplacedBack) {