diff --git a/configure.py b/configure.py index 53276b3d0..933d5ea01 100644 --- a/configure.py +++ b/configure.py @@ -804,7 +804,7 @@ config.libs = [ "JGadget", [ Object(NonMatching, "JSystem/JGadget/binary.cpp"), - Object(NonMatching, "JSystem/JGadget/linklist.cpp"), + Object(Matching, "JSystem/JGadget/linklist.cpp"), Object(NonMatching, "JSystem/JGadget/std-vector.cpp"), ], ), diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 6acec6951..60c7baf3f 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -38,6 +38,7 @@ struct TNodeLinkList { struct const_iterator { const_iterator(TLinkListNode* pNode) { node = pNode; } + const_iterator(iterator it) { node = it.node; } const_iterator& operator++() { node = node->getNext(); return *this; } const_iterator& operator--() { node = node->getPrev(); return *this; } @@ -76,6 +77,26 @@ struct TNodeLinkList { iterator Erase(JGadget::TLinkListNode*); void Remove(JGadget::TLinkListNode*); + bool Iterator_isEnd_(const_iterator it) const { return it.node == &ocObject_; } + template void Remove_if(Predicate predicate, TNodeLinkList& tList) { + iterator it = begin(); + + while (!Iterator_isEnd_(it)) { + if (predicate(*it)) { + iterator itPrev = it; + ++it; + tList.splice(tList.end(), *this, itPrev); + } else { + ++it; + } + } + } + + template void remove_if(Predicate predicate) { + TNodeLinkList list; + Remove_if(predicate, list); + } + public: /* 0x00 */ u32 count; /* 0x04 */ TLinkListNode ocObject_; diff --git a/src/JSystem/JGadget/linklist.cpp b/src/JSystem/JGadget/linklist.cpp index 302677a39..956bd4637 100644 --- a/src/JSystem/JGadget/linklist.cpp +++ b/src/JSystem/JGadget/linklist.cpp @@ -3,46 +3,101 @@ // Translation Unit: linklist.cpp // -#include "linklist.h" -#include "dolphin/types.h" +#include "JSystem/JGadget/linklist.h" + +namespace std { + +template +inline InputIterator find_if(InputIterator first, InputIterator last, Predicate pred) { + while (first != last && !pred(*first)) + ++first; + return first; +} + +} // namespace std + +template +class TPRIsEqual_pointer_ { +public: + TPRIsEqual_pointer_(const T* p) { this->p_ = p; } + + bool operator()(const T& rSrc) const { + return &rSrc == this->p_; + } + +private: + const T* p_; +}; /* 802BFC00-802BFC3C .text __dt__Q27JGadget13TNodeLinkListFv */ JGadget::TNodeLinkList::~TNodeLinkList() { - /* Nonmatching */ } /* 802BFC3C-802BFC84 .text erase__Q27JGadget13TNodeLinkListFQ37JGadget13TNodeLinkList8iterator */ -void JGadget::TNodeLinkList::erase(JGadget::TNodeLinkList::iterator) { - /* Nonmatching */ +JGadget::TNodeLinkList::iterator JGadget::TNodeLinkList::erase(iterator it) { + iterator next = it; + ++next; + return erase(it, next); } /* 802BFC84-802BFCEC .text erase__Q27JGadget13TNodeLinkListFQ37JGadget13TNodeLinkList8iteratorQ37JGadget13TNodeLinkList8iterator */ -void JGadget::TNodeLinkList::erase(JGadget::TNodeLinkList::iterator, JGadget::TNodeLinkList::iterator) { - /* Nonmatching */ +JGadget::TNodeLinkList::iterator JGadget::TNodeLinkList::erase(iterator a, iterator b) { + TLinkListNode* cur = a.node; + TLinkListNode* end = b.node; + TLinkListNode* next; + + for (; cur != end; cur = next) { + next = cur->mNext; + Erase(cur); + } + + return b; } /* 802BFCEC-802BFD8C .text splice__Q27JGadget13TNodeLinkListFQ37JGadget13TNodeLinkList8iteratorRQ27JGadget13TNodeLinkListQ37JGadget13TNodeLinkList8iterator */ -void JGadget::TNodeLinkList::splice(JGadget::TNodeLinkList::iterator, JGadget::TNodeLinkList&, JGadget::TNodeLinkList::iterator) { - /* Nonmatching */ +void JGadget::TNodeLinkList::splice(iterator it, TNodeLinkList& rSrc, iterator itSrc) { + iterator itSrcNext = itSrc; + ++itSrcNext; + + if ((it == itSrc) || (it == itSrcNext)) { + return; + } else { + TLinkListNode* const node = &(*itSrc); + rSrc.Erase(node); + Insert(it, node); + } } /* 802BFD8C-802BFDF4 .text Find__Q27JGadget13TNodeLinkListFPCQ27JGadget13TLinkListNode */ -void JGadget::TNodeLinkList::Find(const JGadget::TLinkListNode*) { - /* Nonmatching */ +JGadget::TNodeLinkList::iterator JGadget::TNodeLinkList::Find(const TLinkListNode* node) { + return std::find_if(begin(), end(), TPRIsEqual_pointer_(node)); } /* 802BFDF4-802BFE20 .text Insert__Q27JGadget13TNodeLinkListFQ37JGadget13TNodeLinkList8iteratorPQ27JGadget13TLinkListNode */ -void JGadget::TNodeLinkList::Insert(JGadget::TNodeLinkList::iterator, JGadget::TLinkListNode*) { - /* Nonmatching */ +JGadget::TNodeLinkList::iterator JGadget::TNodeLinkList::Insert(iterator it, TLinkListNode* p) { + TLinkListNode* pIt = it.node; + TLinkListNode* pItPrev = pIt->mPrev; + + p->mNext = pIt; + p->mPrev = pItPrev; + pIt->mPrev = p; + pItPrev->mNext = p; + count++; + return p; } /* 802BFE20-802BFE44 .text Erase__Q27JGadget13TNodeLinkListFPQ27JGadget13TLinkListNode */ -void JGadget::TNodeLinkList::Erase(JGadget::TLinkListNode*) { - /* Nonmatching */ +JGadget::TNodeLinkList::iterator JGadget::TNodeLinkList::Erase(TLinkListNode* p) { + TLinkListNode* pNext = p->mNext; + TLinkListNode* pPrev = p->mPrev; + pNext->mPrev = pPrev; + pPrev->mNext = pNext; + count--; + return pNext; } /* 802BFE44-802BFF14 .text Remove__Q27JGadget13TNodeLinkListFPQ27JGadget13TLinkListNode */ -void JGadget::TNodeLinkList::Remove(JGadget::TLinkListNode*) { - /* Nonmatching */ +void JGadget::TNodeLinkList::Remove(TLinkListNode* p) { + remove_if(TPRIsEqual_pointer_(p)); }