[array] add FindMatching() and ContainsMatching() (#6872)

This commit adds template `Find/ContainsMatching<Indicator>()` methods
which search in the array to find the first element matching a given
indicator. Unit test `test_array` is also updated to check the
behavior of newly added methods.
This commit is contained in:
Abtin Keshavarzian
2021-07-31 09:35:14 -07:00
committed by Jonathan Hui
parent 75c525bac8
commit ba4a44713f
2 changed files with 100 additions and 2 deletions
+69
View File
@@ -305,6 +305,75 @@ public:
*/
bool Contains(const Type &aEntry) const { return Find(aEntry) != nullptr; }
/**
* This template method finds the first element in the array matching a given indicator.
*
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against elements
* in the array. To check that an element matches the given indicator, the `Matches()` method is invoked on each
* `Type` element in the array. The `Matches()` method should be provided by `Type` class accordingly:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aIndicator An indicator to match with elements in the array.
*
* @returns A pointer to the matched array element, or nullptr if a match could not be found.
*
*/
template <typename Indicator> Type *FindMatching(const Indicator &aIndicator)
{
return const_cast<Type *>(const_cast<const Array *>(this)->FindMatching(aIndicator));
}
/**
* This template method finds the first element in the array matching a given indicator.
*
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against elements
* in the array. To check that an element matches the given indicator, the `Matches()` method is invoked on each
* `Type` element in the array. The `Matches()` method should be provided by `Type` class accordingly:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aIndicator An indicator to match with elements in the array.
*
* @returns A pointer to the matched array element, or nullptr if a match could not be found.
*
*/
template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator) const
{
const Type *matched = nullptr;
for (const Type &element : *this)
{
if (element.Matches(aIndicator))
{
matched = &element;
break;
}
}
return matched;
}
/**
* This template method indicates whether or not the array contains an element matching a given indicator.
*
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against elements
* in the array. To check that an element matches the given indicator, the `Matches()` method is invoked on each
* `Type` element in the array. The `Matches()` method should be provided by `Type` class accordingly:
*
* bool Type::Matches(const Indicator &aIndicator) const
*
* @param[in] aIndicator An indicator to match with elements in the array.
*
* @retval TRUE The array contains a matching element with @p aIndicator.
* @retval FALSE The array does not contain a matching element with @p aIndicator.
*
*/
template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const
{
return FindMatching(aIndicator) != nullptr;
}
/**
* This method overloads assignment `=` operator to copy elements from another array into the array.
*
+31 -2
View File
@@ -171,7 +171,7 @@ void TestArray(void)
VerifyOrQuit(array.IsEmpty());
}
void TestArrayCopy(void)
void TestArrayCopyAndFindMatching(void)
{
constexpr uint16_t kMaxSize = 10;
@@ -186,6 +186,8 @@ void TestArrayCopy(void)
}
bool operator==(const Entry &aOther) { return (mName == aOther.mName) && (mYear == aOther.mYear); }
bool Matches(const char *aName) const { return strcmp(aName, mName) == 0; }
bool Matches(uint16_t aYear) const { return aYear == mYear; }
const char *mName;
uint16_t mYear;
@@ -243,6 +245,33 @@ void TestArrayCopy(void)
VerifyOrQuit(array2[index] == array4[index]);
}
}
SuccessOrQuit(array2.PushBack(ps5));
VerifyOrQuit(array2.GetLength() == 5);
for (const Entry &entry : array2)
{
Entry *match;
printf("- Name:%-3s Year:%d\n", entry.mName, entry.mYear);
match = array2.FindMatching(entry.mName);
VerifyOrQuit(match != nullptr);
VerifyOrQuit(match == &entry);
VerifyOrQuit(array2.ContainsMatching(entry.mName));
match = array2.FindMatching(entry.mYear);
VerifyOrQuit(match != nullptr);
VerifyOrQuit(match == &entry);
VerifyOrQuit(array2.ContainsMatching(entry.mYear));
}
VerifyOrQuit(array2.FindMatching("PS6") == nullptr);
VerifyOrQuit(!array2.ContainsMatching("PS6"));
VerifyOrQuit(array2.FindMatching(static_cast<uint16_t>(2001)) == nullptr);
VerifyOrQuit(!array2.ContainsMatching(static_cast<uint16_t>(2001)));
printf("\n");
}
void TestArrayIndexType(void)
@@ -261,7 +290,7 @@ void TestArrayIndexType(void)
int main(void)
{
ot::TestArray();
ot::TestArrayCopy();
ot::TestArrayCopyAndFindMatching();
ot::TestArrayIndexType();
printf("All tests passed\n");