Syntax
class LinkedList
{
class Iterator;
class ConstIterator;
public:
LinkedList(void)
: mHead(nullptr)
{
}
Type *GetHead(void) { return mHead; }
const Type *GetHead(void) const { return mHead; }
void SetHead(Type *aHead) { mHead = aHead; }
void Clear(void) { mHead = nullptr; }
bool IsEmpty(void) const { return (mHead == nullptr); }
void Push(Type &aEntry)
{
aEntry.SetNext(mHead);
mHead = &aEntry;
}
void PushAfter(Type &aEntry, Type &aPrevEntry)
{
aEntry.SetNext(aPrevEntry.GetNext());
aPrevEntry.SetNext(&aEntry);
}
void PushAfterTail(Type &aEntry)
{
Type *tail = GetTail();
if (tail == nullptr)
{
Push(aEntry);
}
else
{
PushAfter(aEntry, *tail);
}
}
Type *Pop(void)
{
Type *entry = mHead;
if (mHead != nullptr)
{
mHead = mHead->GetNext();
}
return entry;
}
Type *PopAfter(Type *aPrevEntry)
{
Type *entry;
if (aPrevEntry == nullptr)
{
entry = Pop();
}
else
{
entry = aPrevEntry->GetNext();
if (entry != nullptr)
{
aPrevEntry->SetNext(entry->GetNext());
}
}
return entry;
}
bool Contains(const Type &aEntry) const
{
const Type *prev;
return Find(aEntry, prev) == kErrorNone;
}
template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const
{
return FindMatching(aIndicator) != nullptr;
}
Error Add(Type &aEntry)
{
Error error = kErrorNone;
if (Contains(aEntry))
{
error = kErrorAlready;
}
else
{
Push(aEntry);
}
return error;
}
Error Remove(const Type &aEntry)
{
Type *prev;
Error error = Find(aEntry, prev);
if (error == kErrorNone)
{
PopAfter(prev);
}
return error;
}
template <typename Indicator> Type *RemoveMatching(const Indicator &aIndicator)
{
Type *prev;
Type *entry = FindMatching(aIndicator, prev);
if (entry != nullptr)
{
PopAfter(prev);
}
return entry;
}
template <typename Indicator> void RemoveAllMatching(const Indicator &aIndicator, LinkedList &aRemovedList)
{
Type *entry;
Type *prev;
Type *next;
for (prev = nullptr, entry = GetHead(); entry != nullptr; entry = next)
{
next = entry->GetNext();
if (entry->Matches(aIndicator))
{
PopAfter(prev);
aRemovedList.Push(*entry);
}
else
{
prev = entry;
}
}
}
Error Find(const Type &aEntry, const Type *&aPrevEntry) const
{
Error error = kErrorNotFound;
aPrevEntry = nullptr;
for (const Type *entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext())
{
if (entry == &aEntry)
{
error = kErrorNone;
break;
}
}
return error;
}
Error Find(const Type &aEntry, Type *&aPrevEntry)
{
return AsConst(this)->Find(aEntry, const_cast<const Type *&>(aPrevEntry));
}
template <typename Indicator>
const Type *FindMatching(const Type *aBegin,
const Type *aEnd,
const Indicator &aIndicator,
const Type *&aPrevEntry) const
{
const Type *entry;
aPrevEntry = nullptr;
for (entry = aBegin; entry != aEnd; aPrevEntry = entry, entry = entry->GetNext())
{
if (entry->Matches(aIndicator))
{
break;
}
}
return entry;
}
template <typename Indicator>
Type *FindMatching(const Type *aBegin, const Type *aEnd, const Indicator &aIndicator, Type *&aPrevEntry)
{
return AsNonConst(FindMatching(aBegin, aEnd, aIndicator, const_cast<const Type *&>(aPrevEntry)));
}
template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator, const Type *&aPrevEntry) const
{
return FindMatching(mHead, nullptr, aIndicator, aPrevEntry);
}
template <typename Indicator> Type *FindMatching(const Indicator &aIndicator, Type *&aPrevEntry)
{
return AsNonConst(AsConst(this)->FindMatching(aIndicator, const_cast<const Type *&>(aPrevEntry)));
}
template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator) const
{
const Type *prev;
return FindMatching(aIndicator, prev);
}
template <typename Indicator> Type *FindMatching(const Indicator &aIndicator)
{
return AsNonConst(AsConst(this)->FindMatching(aIndicator));
}
const Type *GetTail(void) const
{
const Type *tail = mHead;
if (tail != nullptr)
{
while (tail->GetNext() != nullptr)
{
tail = tail->GetNext();
}
}
return tail;
}
Type *GetTail(void) { return AsNonConst(AsConst(this)->GetTail()); }
Iterator begin(void) { return Iterator(GetHead()); }
Iterator end(void) { return Iterator(nullptr); }
ConstIterator begin(void) const { return ConstIterator(GetHead()); }
ConstIterator end(void) const { return ConstIterator(nullptr); }
private:
class Iterator : public ItemPtrIterator<Type, Iterator>
{
friend class LinkedList;
friend class ItemPtrIterator<Type, Iterator>;
using ItemPtrIterator<Type, Iterator>::mItem;
explicit Iterator(Type *aItem)
: ItemPtrIterator<Type, Iterator>(aItem)
{
}
void Advance(void) { mItem = mItem->GetNext(); }
};
class ConstIterator : public ItemPtrIterator<const Type, ConstIterator>
{
friend class LinkedList;
friend class ItemPtrIterator<const Type, ConstIterator>;
using ItemPtrIterator<const Type, ConstIterator>::mItem;
explicit ConstIterator(const Type *aItem)
: ItemPtrIterator<const Type, ConstIterator>(aItem)
{
}
void Advance(void) { mItem = mItem->GetNext(); }
};
Type *mHead;
};