Skip to content

Commit

Permalink
\#55 adding assign to VLA
Browse files Browse the repository at this point in the history
  • Loading branch information
thirtytwobits committed Aug 16, 2023
1 parent 64209d5 commit 5c6ccd5
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 29 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
"strstream": "cpp",
"typeindex": "cpp",
"charconv": "cpp",
"csignal": "cpp"
"csignal": "cpp",
"format": "cpp"
}
}
59 changes: 59 additions & 0 deletions cetlvast/suites/unittest/test_variable_length_array_bool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,62 @@ TYPED_TEST(VLABoolTests, TestBoolIterator)
ASSERT_EQ(true, *(foo.cend() - 1));
ASSERT_EQ(true, foo.cbegin()[2]);
}

TYPED_TEST(VLABoolTests, TestBoolPopBack)
{
auto test_subject = TypeParam::make_bool_container(
std::initializer_list<bool>{true, true, true, true, true, true, true, true, true});
std::size_t starting_size = test_subject.size();
ASSERT_EQ(9, starting_size);
while(starting_size > 0)
{
test_subject.pop_back();
--starting_size;
ASSERT_EQ(starting_size, test_subject.size());
}
}

TYPED_TEST(VLABoolTests, TestBoolResize)
{
auto array = TypeParam::make_bool_container();
for(std::size_t i = 1; i <= 64; ++i)
{
array.resize(i);
ASSERT_EQ(i, array.size());
ASSERT_EQ(false, array[i]);
}
}

TYPED_TEST(VLABoolTests, TestBoolResizeWithDefault)
{
auto array = TypeParam::make_bool_container(std::initializer_list<bool>{false});
array.resize(22, true);
ASSERT_EQ(22, array.size());
ASSERT_EQ(false, array[0]);
for(std::size_t i = 1; i < array.size(); ++i)
{
ASSERT_EQ(true, array[i]);
}
}

TYPED_TEST(VLABoolTests, TestBoolResizeOneBit)
{
auto array = TypeParam::make_bool_container(std::initializer_list<bool>{true, false, true});
ASSERT_EQ(3, array.size());
ASSERT_EQ(1, array[0]);
ASSERT_EQ(0, array[1]);
ASSERT_EQ(1, array[2]);
array.resize(4, 1);
ASSERT_EQ(4, array.size());
ASSERT_EQ(1, array[0]);
ASSERT_EQ(0, array[1]);
ASSERT_EQ(1, array[2]);
ASSERT_EQ(1, array[3]);
array.resize(5);
ASSERT_EQ(5, array.size());
ASSERT_EQ(1, array[0]);
ASSERT_EQ(0, array[1]);
ASSERT_EQ(1, array[2]);
ASSERT_EQ(1, array[3]);
ASSERT_EQ(0, array[4]);
}
142 changes: 141 additions & 1 deletion cetlvast/suites/unittest/test_variable_length_array_compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class CetlUnsynchronizedArrayMemoryResourceFactory
return delegate_.reallocate(p, old_size_bytes, new_size_bytes, alignment);
}

std::array<cetl::pf17::byte, ImplArraySizeBytes> memory_;
std::array<cetl::pf17::byte, ImplArraySizeBytes> memory_;
cetl::pmr::UnsynchronizedBufferMemoryResourceDelegate<cetl::pf17::pmr::memory_resource> delegate_;
};

Expand Down Expand Up @@ -662,6 +662,80 @@ TYPED_TEST(VLATestsGeneric, TestOverMaxSize)
#endif
}

// +-------------------------------------------------------------------------------------------------------------------+

TYPED_TEST(VLATestsGeneric, TestResize)
{
typename TestFixture::SubjectType subject{TestFixture::make_allocator()};

std::size_t clamped_max = std::min(this->get_expected_max_size(), 10UL);
ASSERT_GT(this->get_expected_max_size(), 0) << "This test is only valid if get_expected_max_size() > 0";
ASSERT_GT(clamped_max, subject.size());
subject.resize(clamped_max);
ASSERT_EQ(clamped_max, subject.size());

typename TestFixture::SubjectType::value_type default_constructed_value{};
ASSERT_EQ(subject[subject.size() - 1], default_constructed_value);
}

// +-------------------------------------------------------------------------------------------------------------------+

TYPED_TEST(VLATestsGeneric, TestResizeToZero)
{
typename TestFixture::SubjectType subject{TestFixture::make_allocator()};

std::size_t clamped_max = std::min(this->get_expected_max_size(), 10UL);
ASSERT_GT(this->get_expected_max_size(), 0) << "This test is only valid if get_expected_max_size() > 0";
ASSERT_GT(clamped_max, subject.size());
subject.resize(clamped_max);
ASSERT_EQ(clamped_max, subject.size());
std::size_t capacity_before = subject.capacity();

subject.resize(0);
ASSERT_EQ(0, subject.size());
ASSERT_EQ(capacity_before, subject.capacity());
}

// +-------------------------------------------------------------------------------------------------------------------+

TYPED_TEST(VLATestsGeneric, TestResizeWithCopy)
{
if (std::is_same<typename TypeParam::container_type, cetlvast::SkipTag>::value)
{
GTEST_SKIP() << "Skipping test that requires CETL reallocation support.";
}

typename TestFixture::SubjectType subject{TestFixture::make_allocator()};

std::size_t clamped_max = std::min(this->get_expected_max_size(), 10UL);
ASSERT_GT(this->get_expected_max_size(), 1) << "This test is only valid if get_expected_max_size() > 1";
ASSERT_GT(clamped_max, subject.size());

subject.push_back(1);

const typename TestFixture::SubjectType::value_type copy_from_value{2};
subject.resize(clamped_max, copy_from_value);
ASSERT_EQ(clamped_max, subject.size());
ASSERT_EQ(1, subject[0]);

for (std::size_t i = 1; i < subject.size(); ++i)
{
ASSERT_EQ(subject[i], copy_from_value);
}
}

// +----------------------------------------------------------------------+

#ifdef __cpp_exceptions

TYPED_TEST(VLATestsGeneric, TestResizeExceptionLengthError)
{
typename TestFixture::SubjectType subject{TestFixture::make_allocator()};
ASSERT_THROW(subject.resize(subject.max_size() + 1), std::length_error);
}

#endif // __cpp_exceptions

// +----------------------------------------------------------------------+
/**
* Test suite to ensure non-trivial objects are properly handled. This one is both for bool and non-bool spec.
Expand Down Expand Up @@ -1036,3 +1110,69 @@ TEST(VLATestsNonTrivialSpecific, TestMoveAssignment)
ASSERT_NE(lhs, rhs);
ASSERT_EQ(std::string("three"), lhs[0]);
}

struct NoDefault
{
~NoDefault() = default;
NoDefault() = delete;
NoDefault(int value)
: data_{value} {};
NoDefault(const NoDefault&) = default;
NoDefault(NoDefault&&) noexcept = default;
NoDefault& operator=(const NoDefault&) = default;
NoDefault& operator=(NoDefault&&) noexcept = default;

int data() const noexcept
{
return data_;
}

private:
int data_;
};

TEST(VLATestsNonTrivialSpecific, TestResizeWithNoDefaultCtorData)
{
std::allocator<NoDefault> allocator{};
cetl::VariableLengthArray<NoDefault, std::allocator<NoDefault>> subject{{NoDefault{1}}, allocator};
ASSERT_EQ(1, subject.size());
subject.resize(10, NoDefault{2});
ASSERT_EQ(10, subject.size());
ASSERT_EQ(1, subject[0].data());
for (std::size_t i = 1; i < subject.size(); ++i)
{
ASSERT_EQ(2, subject[i].data());
}
}

#ifdef __cpp_exceptions

struct GrenadeError : public std::runtime_error
{
GrenadeError(const char* message)
: std::runtime_error(message)
{

}
};

struct Grenade
{
Grenade(int value)
{
if (value == 2)
{
throw GrenadeError("");
}
}
};

TYPED_TEST(VLATestsGeneric, TestResizeExceptionFromCtorOnResize)
{
std::allocator<Grenade> allocator{};
cetl::VariableLengthArray<Grenade, std::allocator<Grenade>> subject{{Grenade{1}}, allocator};
ASSERT_EQ(1, subject.size());
ASSERT_THROW(subject.resize(2, Grenade{2}), GrenadeError);
}

#endif // __cpp_exceptions
Loading

0 comments on commit 5c6ccd5

Please sign in to comment.