Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion score/containers/docs/architecture/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Static Architecture
:safety: ASIL_B
:status: valid
:version: 1
:fulfils: comp_req__containers__dynamic_array[version==1], comp_req__containers__intrusive_list[version==1], comp_req__containers__type_safety[version==1], comp_req__containers__non_relocatable_vector[version==1], comp_req__containers__deterministic_behavior[version==1]
:fulfils: comp_req__containers__dynamic_array[version==1], comp_req__containers__intrusive_list[version==1], comp_req__containers__non_relocatable_vector[version==1], comp_req__containers__deterministic_behavior[version==1]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

:belongs_to: comp__baselibs_containers[version==1]

.. needarch::
Expand Down
1 change: 0 additions & 1 deletion score/containers/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ The Containers library should provide type-safe data structures and efficient me

* :need:`comp_req__containers__dynamic_array`
* :need:`comp_req__containers__intrusive_list`
* :need:`comp_req__containers__type_safety`
* :need:`comp_req__containers__deterministic_behavior`

The component should be extensible in the future to support additional data structures and algorithms as needed.
12 changes: 0 additions & 12 deletions score/containers/docs/requirements/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,6 @@ Functional Requirements

The Containers library shall provide an intrusive doubly-linked list based on the C++ standardization proposal P0406R1.

.. comp_req:: Type Safety
:id: comp_req__containers__type_safety
:reqtype: Functional
:security: YES
:safety: ASIL_B
:derived_from: feat_req__baselibs__containers_library[version==2]
:status: valid
:version: 1
:satisfied_by: comp__baselibs_containers[version==1]

The Containers library shall enforce compile-time type safety for all container operations.

.. comp_req:: Non-Relocatable Vector
:id: comp_req__containers__non_relocatable_vector
:reqtype: Functional
Expand Down
240 changes: 240 additions & 0 deletions score/containers/dynamic_array_test.cpp

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions score/containers/intrusive_list_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ void CheckNonEmpty(ListType& list,

TEST(IntrusiveList, NotLinkedListElement)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "equivalence-classes");
RecordProperty("Description",
"Check that constructing, copying, and moving a list element that is not linked into any list "
"does not trigger any assertion.");

ListElement element;
ListElement copied_element{element};
ListElement moved_element{std::move(element)};
Expand All @@ -116,6 +123,13 @@ TEST(IntrusiveList, NotLinkedListElement)

TEST(IntrusiveList, EmptyIterator)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check that default-constructed (unlinked) iterators of all four iterator kinds compare equal "
"to themselves and to each other across const/non-const variants.");

const List::iterator iterator;
const List::const_iterator const_iterator;
EXPECT_TRUE(iterator == iterator);
Expand All @@ -137,6 +151,13 @@ TEST(IntrusiveList, EmptyIterator)

TEST(IntrusiveList, EmptyList)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check that a default-constructed intrusive_list, and a list moved-from an empty list, are "
"empty and their const view reports the same.");

List list;
const List& const_list = list;

Expand All @@ -151,6 +172,13 @@ TEST(IntrusiveList, EmptyList)

TEST(IntrusiveList, SingleElementMinimalChecks)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check that a list constructed from a single-range element is non-empty and becomes empty "
"after clear().");

std::array<ListElement, 1> elements;
List list{elements.begin(), elements.end()};
EXPECT_FALSE(list.empty());
Expand All @@ -173,6 +201,15 @@ static_assert(refers_to_const_v<decltype(std::declval<List::const_reverse_iterat

TEST(IntrusiveList, SingleElementBasedIteratorChecks)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check iterator/reverse_iterator/const_iterator/const_reverse_iterator dereference, member "
"access, comparison, and increment/decrement semantics on a single-element list, and "
"statically assert that const-correctness of dereferenced iterator types is enforced at "
"compile time.");

constexpr std::size_t kMagic = 42;
std::array<ListElement, 1> elements{kMagic};
List list{elements.begin(), elements.end()};
Expand Down Expand Up @@ -360,6 +397,14 @@ TEST(IntrusiveList, SingleElementBasedIteratorChecks)

TEST(IntrusiveList, SingleElementInsertRemoveChecks)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check that push_back/pop_back, push_front/pop_front, move construction, insert/remove, and "
"insert/remove_if on a single element correctly transition the list between empty and "
"non-empty.");

List list;
const List& const_list = list;
ListElement front_back;
Expand Down Expand Up @@ -407,6 +452,12 @@ TEST(IntrusiveList, SingleElementInsertRemoveChecks)

TEST(IntrusiveList, TwoElementsInsertRemoveChecks)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check push/pop/insert/remove/move-construction ordering (front/back) for a two-element list.");

List list;
const List& const_list = list;
ListElement front;
Expand Down Expand Up @@ -474,6 +525,13 @@ TEST(IntrusiveList, TwoElementsInsertRemoveChecks)

TEST(IntrusiveList, SixElementsInsertRemoveChecks)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "equivalence-classes");
RecordProperty("Description",
"Check range-construct, assign, insert-range (at begin/end/middle), move-construction, remove, "
"and remove_if for a six-element list preserve order and 'no auto-unlink' semantics.");

constexpr std::size_t num_elements = 6;
std::array<ListElement, num_elements> elements;
List list{elements.begin(), elements.end()};
Expand Down Expand Up @@ -549,6 +607,13 @@ DISABLE_WARNING_SELF_MOVE // testing correctness of implementation

TEST(IntrusiveList, MoveAssignmentTest)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "error-guessing");
RecordProperty("Description",
"Check move-assignment, including self-move-assignment, correctly empties the source and "
"transfers elements for 0-, 1-, 2-, and 6-element lists.");

// NOLINTBEGIN(bugprone-use-after-move): testing correctness of implementation

List list;
Expand Down Expand Up @@ -594,6 +659,13 @@ DISABLE_WARNING_POP // "-Wself-move"

TEST(IntrusiveList, EraseTest)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "boundary-values");
RecordProperty("Description",
"Check erase() of a single iterator, a range, an empty range, and a full-range erase update "
"size, the returned iterator, and the remaining elements correctly.");

constexpr std::size_t num_elements = 6;
std::array<ListElement, num_elements> elements;
List list{elements.begin(), elements.end()};
Expand Down Expand Up @@ -622,6 +694,13 @@ TEST(IntrusiveList, EraseTest)

TEST(IntrusiveList, SwapTest)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "equivalence-classes");
RecordProperty("Description",
"Check member swap() and free-function swap(), including self-swap, correctly exchange "
"contents between empty and non-empty lists of varying sizes.");

List list1;

list1.swap(list1);
Expand Down Expand Up @@ -675,6 +754,14 @@ TEST(IntrusiveList, SwapTest)

TEST(IntrusiveList, DisposeTest)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "equivalence-classes");
RecordProperty("Description",
"Check pop_back_and_dispose/pop_front_and_dispose/erase_and_dispose/dispose_and_assign/"
"remove_and_dispose/remove_and_dispose_if/clear_and_dispose invoke the disposer exactly once "
"per removed element in the expected order.");

// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers): "Magic numbers" here are the test labels by themselves

constexpr std::size_t num_elements = 6;
Expand Down Expand Up @@ -734,6 +821,14 @@ class multi_element : public score::containers::intrusive_list_element<>,

TEST(IntrusiveList, MultiTagTest)
{
RecordProperty("PartiallyVerifies", "comp_req__containers__intrusive_list");
RecordProperty("TestType", "requirements-based");
RecordProperty("DerivationTechnique", "equivalence-classes");
RecordProperty("Description",
"Check that the same element type can simultaneously belong to independent intrusive_list "
"instances distinguished by tag, and that operations on one tagged list do not affect "
"membership in another.");

constexpr std::size_t num_elements = 6;
std::array<multi_element, num_elements> elements;
score::containers::intrusive_list<multi_element> no_tag_list{elements.begin(), elements.end()};
Expand Down
47 changes: 47 additions & 0 deletions score/containers/non_relocatable_vector_emplace_back_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ TYPED_TEST_SUITE(NonRelocatableVectorPolymorphicAllocatorFixture, PolymorphicAll

TYPED_TEST(NonRelocatableVectorFixture, EmplaceBackUpdatesSize)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
this->RecordProperty("TestType", "requirements-based");
this->RecordProperty("DerivationTechnique", "equivalence-classes");
this->RecordProperty("Description", "Check that each call to emplace_back() increments size() by one.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

for (std::size_t i = 0; i < kNonZeroNumberElements; ++i)
Expand All @@ -100,6 +105,13 @@ TYPED_TEST(NonRelocatableVectorFixture, EmplaceBackUpdatesSize)

TYPED_TEST(NonRelocatableVectorTrivialFixture, EmplaceBackAllocatesAndReturnsElement)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
Comment thread
Nikhil2206 marked this conversation as resolved.
this->RecordProperty("TestType", "requirements-based");
this->RecordProperty("DerivationTechnique", "equivalence-classes");
this->RecordProperty("Description",
"Check that emplace_back() on trivial elements constructs the element in place at the "
"correct index and returns a reference to it.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

for (std::size_t i = 0; i < kNonZeroNumberElements; ++i)
Expand All @@ -118,6 +130,13 @@ TYPED_TEST(NonRelocatableVectorTrivialFixture, EmplaceBackAllocatesAndReturnsEle

TYPED_TEST(NonRelocatableVectorNonTrivialFixture, EmplaceBackAllocatesAndReturnsElement)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
this->RecordProperty("TestType", "requirements-based");
this->RecordProperty("DerivationTechnique", "equivalence-classes");
this->RecordProperty("Description",
"Check that emplace_back() on non-trivial elements constructs the element in place at "
"the correct index and returns a reference to it.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

for (std::size_t i = 0; i < kNonZeroNumberElements; ++i)
Expand All @@ -137,6 +156,13 @@ TYPED_TEST(NonRelocatableVectorNonTrivialFixture, EmplaceBackAllocatesAndReturns

TYPED_TEST(NonRelocatableVectorTriviallyConstructibleDestructibleTypeFixture, EmplaceBackAllocatesAndReturnsElement)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
this->RecordProperty("TestType", "requirements-based");
this->RecordProperty("DerivationTechnique", "equivalence-classes");
this->RecordProperty("Description",
"Check that emplace_back() on trivially-constructible/destructible elements constructs "
"the element in place at the correct index and returns a reference to it.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

for (std::size_t i = 0; i < kNonZeroNumberElements; ++i)
Expand All @@ -156,6 +182,13 @@ TYPED_TEST(NonRelocatableVectorTriviallyConstructibleDestructibleTypeFixture, Em

TYPED_TEST(NonRelocatableVectorNonMoveableAndCopyableElementTypeFixture, EmplaceBackAllocatesAndReturnsElement)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
this->RecordProperty("TestType", "requirements-based");
this->RecordProperty("DerivationTechnique", "equivalence-classes");
this->RecordProperty("Description",
"Check that emplace_back() on non-moveable, non-copyable elements constructs the "
"element in place at the correct index and returns a reference to it.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

for (std::size_t i = 0; i < kNonZeroNumberElements; ++i)
Expand All @@ -174,6 +207,13 @@ TYPED_TEST(NonRelocatableVectorNonMoveableAndCopyableElementTypeFixture, Emplace

TYPED_TEST(NonRelocatableVectorFixture, CallingEmplaceBackMoreTimesThanWereReservedTerminates)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__non_relocatable_vector");
this->RecordProperty("TestType", "fault-injection");
this->RecordProperty("DerivationTechnique", "boundary-values");
this->RecordProperty("Description",
"Check that calling emplace_back() more times than the vector's reserved capacity "
"terminates via contract violation instead of silently overflowing.");

this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);

// and given that emplace_back was called size() - 1 times
Expand All @@ -189,6 +229,13 @@ TYPED_TEST(NonRelocatableVectorFixture, CallingEmplaceBackMoreTimesThanWereReser

TYPED_TEST(NonRelocatableVectorPolymorphicAllocatorFixture, EmplaceBackDoesNotAllocate)
{
this->RecordProperty("PartiallyVerifies", "comp_req__containers__deterministic_behavior");
this->RecordProperty("TestType", "resource-usage");
this->RecordProperty("DerivationTechnique", "requirements-analysis");
this->RecordProperty("Description",
"Check that repeated emplace_back() calls up to the reserved capacity do not trigger "
"any additional memory allocation beyond what was allocated at construction.");

// Given a NonRelocatableVector which has allocated n bytes on construction
this->GivenANonRelocatableVectorConstructedWithNumberOfElements(kNonZeroNumberElements);
const auto allocated_bytes_after_construction = this->memory_resource_.GetUserAllocatedBytes();
Expand Down
Loading
Loading