Syntax
class Array
{
public:
using IndexType = uint16_t;
Array(void)
: mArray(nullptr)
, mLength(0)
, mCapacity(0)
{
}
~Array(void) { Free(); }
void Free(void)
{
Clear();
Heap::Free(mArray);
mArray = nullptr;
mCapacity = 0;
}
void Clear(void)
{
for (Type &entry : *this)
{
entry.~Type();
}
mLength = 0;
}
IndexType GetLength(void) const { return mLength; }
const Type *AsCArray(void) const { return (mLength != 0) ? mArray : nullptr; }
IndexType GetCapacity(void) const { return mCapacity; }
Error ReserveCapacity(IndexType aCapacity) { return Allocate(aCapacity); }
void TakeFrom(Array &&aOther)
{
Free();
mArray = aOther.mArray;
mLength = aOther.mLength;
mCapacity = aOther.mCapacity;
aOther.mArray = nullptr;
aOther.mLength = 0;
aOther.mCapacity = 0;
}
Type &operator[](IndexType aIndex) { return mArray[aIndex]; }
const Type &operator[](IndexType aIndex) const { return mArray[aIndex]; }
Type *At(IndexType aIndex) { return (aIndex < mLength) ? &mArray[aIndex] : nullptr; }
const Type *At(IndexType aIndex) const { return (aIndex < mLength) ? &mArray[aIndex] : nullptr; }
Type *Front(void) { return At(0); }
const Type *Front(void) const { return At(0); }
Type *Back(void) { return (mLength > 0) ? &mArray[mLength - 1] : nullptr; }
const Type *Back(void) const { return (mLength > 0) ? &mArray[mLength - 1] : nullptr; }
Error PushBack(const Type &aEntry)
{
Error error = kErrorNone;
if (mLength == mCapacity)
{
SuccessOrExit(error = Allocate(mCapacity + kCapacityIncrements));
}
new (&mArray[mLength++]) Type(aEntry);
exit:
return error;
}
Error PushBack(Type &&aEntry)
{
Error error = kErrorNone;
if (mLength == mCapacity)
{
SuccessOrExit(error = Allocate(mCapacity + kCapacityIncrements));
}
new (&mArray[mLength++]) Type(static_cast<Type &&>(aEntry));
exit:
return error;
}
Type *PushBack(void)
{
Type *newEntry = nullptr;
if (mLength == mCapacity)
{
SuccessOrExit(Allocate(mCapacity + kCapacityIncrements));
}
newEntry = new (&mArray[mLength++]) Type();
exit:
return newEntry;
}
void PopBack(void)
{
if (mLength > 0)
{
mArray[mLength - 1].~Type();
mLength--;
}
}
IndexType IndexOf(const Type &aElement) const { return static_cast<IndexType>(&aElement - mArray); }
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;
}
Type *begin(void) { return (mLength > 0) ? mArray : nullptr; }
Type *end(void) { return (mLength > 0) ? &mArray[mLength] : nullptr; }
const Type *begin(void) const { return (mLength > 0) ? mArray : nullptr; }
const Type *end(void) const { return (mLength > 0) ? &mArray[mLength] : nullptr; }
Array(const Array &) = delete;
Array &operator=(const Array &) = delete;
private:
Error Allocate(IndexType aCapacity)
{
Error error = kErrorNone;
Type *newArray;
VerifyOrExit((aCapacity != mCapacity) && (aCapacity >= mLength));
newArray = static_cast<Type *>(Heap::CAlloc(aCapacity, sizeof(Type)));
VerifyOrExit(newArray != nullptr, error = kErrorNoBufs);
for (IndexType index = 0; index < mLength; index++)
{
new (&newArray[index]) Type(static_cast<Type &&>(mArray[index]));
mArray[index].~Type();
}
Heap::Free(mArray);
mArray = newArray;
mCapacity = aCapacity;
exit:
return error;
}
Type *mArray;
IndexType mLength;
IndexType mCapacity;
};
![]()
template <typename Type, uint16_t kCapacityIncrements = 2> class Array![]()
Array(const Array &) = delete;
![]()
return