Syntax
class Array
{
static_assert(kMaxSize != 0, "Array `kMaxSize` cannot be zero");
public:
typedef SizeType IndexType;
Array(void)
: mLength(0)
{
}
Array(const Array &aOtherArray) { *this = aOtherArray; }
explicit Array(Instance &aInstance)
: mLength(0)
{
for (Type &element : mElements)
{
element.Init(aInstance);
}
}
void Clear(void) { mLength = 0; }
bool IsEmpty(void) const { return (mLength == 0); }
bool IsFull(void) const { return (mLength == GetMaxSize()); }
IndexType GetMaxSize(void) const { return static_cast<IndexType>(kMaxSize); }
IndexType GetLength(void) const { return mLength; }
void SetLength(IndexType aLength) { mLength = aLength; }
Type *GetArrayBuffer(void) { return mElements; }
const Type *GetArrayBuffer(void) const { return mElements; }
Type &operator[](IndexType aIndex) { return mElements[aIndex]; }
const Type &operator[](IndexType aIndex) const { return mElements[aIndex]; }
Type *At(IndexType aIndex) { return (aIndex < mLength) ? &mElements[aIndex] : nullptr; }
const Type *At(IndexType aIndex) const { return (aIndex < mLength) ? &mElements[aIndex] : nullptr; }
Type *Front(void) { return At(0); }
const Type *Front(void) const { return At(0); }
Type *Back(void) { return At(mLength - 1); }
const Type *Back(void) const { return At(mLength - 1); }
Error PushBack(const Type &aEntry) { return IsFull() ? kErrorNoBufs : (mElements[mLength++] = aEntry, kErrorNone); }
Type *PushBack(void) { return IsFull() ? nullptr : &mElements[mLength++]; }
Type *PopBack(void) { return IsEmpty() ? nullptr : &mElements[--mLength]; }
IndexType IndexOf(const Type &aElement) const { return static_cast<IndexType>(&aElement - &mElements[0]); }
void Remove(Type &aElement)
{
Type *lastElement = PopBack();
if (lastElement != &aElement)
{
aElement = *lastElement;
}
}
Type *Find(const Type &aEntry) { return AsNonConst(AsConst(this)->Find(aEntry)); }
const Type *Find(const Type &aEntry) const
{
const Type *matched = nullptr;
for (const Type &element : *this)
{
if (element == aEntry)
{
matched = &element;
break;
}
}
return matched;
}
bool Contains(const Type &aEntry) const { return Find(aEntry) != nullptr; }
template <typename Indicator> Type *FindMatching(const Indicator &aIndicator)
{
return AsNonConst(AsConst(this)->FindMatching(aIndicator));
}
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;
}
template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const
{
return FindMatching(aIndicator) != nullptr;
}
template <typename Indicator> void RemoveMatching(const Indicator &aIndicator)
{
Type *entry = FindMatching(aIndicator);
if (entry != nullptr)
{
Remove(*entry);
}
}
template <typename Indicator> void RemoveAllMatching(const Indicator &aIndicator)
{
for (IndexType index = 0; index < GetLength();)
{
Type &entry = mElements[index];
if (entry.Matches(aIndicator))
{
Remove(entry);
}
else
{
index++;
}
}
}
Array &operator=(const Array &aOtherArray)
{
Clear();
for (const Type &otherElement : aOtherArray)
{
IgnoreError(PushBack(otherElement));
}
return *this;
}
bool IsInArrayBuffer(const Type *aEntry) const
{
return (&mElements[0] <= aEntry) && (aEntry < GetArrayEnd(mElements));
}
Type *begin(void) { return &mElements[0]; }
Type *end(void) { return &mElements[mLength]; }
const Type *begin(void) const { return &mElements[0]; }
const Type *end(void) const { return &mElements[mLength]; }
private:
Type mElements[kMaxSize];
IndexType mLength;
};