From b4406e4f41eb08e76c42953a2aa27ad48acf800f Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 6 Jan 2022 14:52:10 -0500 Subject: [PATCH] Make "contains" take a const argument in intrusive list --- src/lib/support/IntrusiveList.h | 8 +++-- src/lib/support/tests/TestIntrusiveList.cpp | 40 ++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/lib/support/IntrusiveList.h b/src/lib/support/IntrusiveList.h index 4d9bc3e3b6ceae..7555b1659aa873 100644 --- a/src/lib/support/IntrusiveList.h +++ b/src/lib/support/IntrusiveList.h @@ -202,7 +202,7 @@ class IntrusiveListBase void InsertAfter(IteratorBase pos, IntrusiveListNodeBase * node) { pos.mCurrent->Append(node); } void Remove(IntrusiveListNodeBase * node) { node->Remove(); } - bool Contains(IntrusiveListNodeBase * node) const + bool Contains(const IntrusiveListNodeBase * node) const { for (auto & iter : *this) { @@ -225,8 +225,12 @@ class IntrusiveListBaseHook { public: static_assert(std::is_base_of::value, "T must be derived from IntrusiveListNodeBase"); + static T * ToObject(IntrusiveListNodeBase * node) { return static_cast(node); } + static const T * ToObject(const IntrusiveListNodeBase * node) { return static_cast(node); } + static IntrusiveListNodeBase * ToNode(T * object) { return static_cast(object); } + static const IntrusiveListNodeBase * ToNode(const T * object) { return static_cast(object); } }; /// A double-linked list where the data is stored together with the previous/next pointers for cache efficiency / and compactness. @@ -289,7 +293,7 @@ class IntrusiveList : public IntrusiveListBase void InsertBefore(Iterator pos, T * value) { IntrusiveListBase::InsertBefore(pos, Hook::ToNode(value)); } void InsertAfter(Iterator pos, T * value) { IntrusiveListBase::InsertAfter(pos, Hook::ToNode(value)); } void Remove(T * value) { IntrusiveListBase::Remove(Hook::ToNode(value)); } - bool Contains(T * value) const { return IntrusiveListBase::Contains(Hook::ToNode(value)); } + bool Contains(const T * value) const { return IntrusiveListBase::Contains(Hook::ToNode(value)); } }; } // namespace chip diff --git a/src/lib/support/tests/TestIntrusiveList.cpp b/src/lib/support/tests/TestIntrusiveList.cpp index 7e9bbb73051903..f65eb8557ba94a 100644 --- a/src/lib/support/tests/TestIntrusiveList.cpp +++ b/src/lib/support/tests/TestIntrusiveList.cpp @@ -97,6 +97,40 @@ void TestIntrusiveListRandom(nlTestSuite * inSuite, void * inContext) } } +void TestContains(nlTestSuite * inSuite, void * inContext) +{ + ListNode a, b, c; + IntrusiveList list; + + NL_TEST_ASSERT(inSuite, !list.Contains(&a)); + NL_TEST_ASSERT(inSuite, !list.Contains(&b)); + NL_TEST_ASSERT(inSuite, !list.Contains(&c)); + + list.PushBack(&a); + list.PushFront(&c); + + NL_TEST_ASSERT(inSuite, list.Contains(&a)); + NL_TEST_ASSERT(inSuite, !list.Contains(&b)); + NL_TEST_ASSERT(inSuite, list.Contains(&c)); + + list.PushBack(&b); + + NL_TEST_ASSERT(inSuite, list.Contains(&a)); + NL_TEST_ASSERT(inSuite, list.Contains(&b)); + NL_TEST_ASSERT(inSuite, list.Contains(&c)); + + list.Remove(&a); + list.Remove(&c); + + NL_TEST_ASSERT(inSuite, !list.Contains(&a)); + NL_TEST_ASSERT(inSuite, list.Contains(&b)); + NL_TEST_ASSERT(inSuite, !list.Contains(&c)); + + // all nodes have to be removed from the list on destruction. Lists do NOT do + // this automatically + list.Remove(&b); +} + int Setup(void * inContext) { return SUCCESS; @@ -113,7 +147,11 @@ int Teardown(void * inContext) /** * Test Suite. It lists all the test functions. */ -static const nlTest sTests[] = { NL_TEST_DEF_FN(TestIntrusiveListRandom), NL_TEST_SENTINEL() }; +static const nlTest sTests[] = { + NL_TEST_DEF_FN(TestIntrusiveListRandom), // + NL_TEST_DEF_FN(TestContains), // + NL_TEST_SENTINEL(), // +}; int TestIntrusiveList() {