From fa466b571b5473104d005c7633dec916bb8bedd1 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 28 Nov 2023 11:17:10 -0500 Subject: [PATCH 1/4] First pass linklist --- include/JSystem/JGadget/linklist.h | 170 +++++++++++++++++++++++++ include/MSL_CPP/algorithm.h | 19 +++ include/MSL_CPP/iterator.h | 38 ++++++ src/JSystem/JGadget/linklist.cpp | 198 +++++++++++++++++++++++++++++ 4 files changed, 425 insertions(+) create mode 100644 include/JSystem/JGadget/linklist.h create mode 100644 include/MSL_CPP/algorithm.h create mode 100644 include/MSL_CPP/iterator.h create mode 100644 src/JSystem/JGadget/linklist.cpp diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h new file mode 100644 index 00000000..300aed73 --- /dev/null +++ b/include/JSystem/JGadget/linklist.h @@ -0,0 +1,170 @@ +#ifndef JGADGET_LINK_H +#define JGADGET_LINK_H + +#include "types.h" + +#include "JSystem/JUtility/JUTAssertion.h" + +namespace JGadget { + +#define JGADGET_ASSERTWARN(cond) \ + if ((cond) == false) \ + { \ + /*JGadget_outMessage msg(&warning);*/ \ + /*msg << (#cond);*/ \ + } + +#define JGADGET_EXIT(cond) \ + if ((cond) == false) \ + { \ + /*JGadget_outMessage msg(&warning);*/ \ + /*msg << (#cond);*/ \ + return false; \ + } + +/* TODO: this definitely has a better place to live */ +template +class TPRIsEqual_pointer_ { +public: + TPRIsEqual_pointer_(const T* p) { this->p_ = p; } + + bool operator()(const T& rSrc) const { + return this->p_ == &rSrc; + } + +private: + const T* p_; +}; + +class TLinkListNode { +public: + TLinkListNode() { + this->pNext_ = nullptr; + this->pPrev_ = nullptr; + } + + ~TLinkListNode() { + JGADGET_ASSERTWARN(pNext_==NULL); + JGADGET_ASSERTWARN(pPrev_==NULL); + } + + TLinkListNode* getNext() const { + return this->pNext_; + } + + TLinkListNode* getPrev() const { + return this->pPrev_; + } + + void clear_() { + this->pNext_ = nullptr; + this->pPrev_ = nullptr; + } + + TLinkListNode* pNext_; + TLinkListNode* pPrev_; +}; + +class TNodeLinkList { +public: + TNodeLinkList() { Initialize_(); } + ~TNodeLinkList(); + + class iterator { + public: + iterator() { this->p_ = nullptr; } + iterator(TLinkListNode* node) { this->p_ = node; } + iterator(const iterator& it) { this->p_ = it.p_; } + + iterator& operator++() { + this->p_ = this->p_->getNext(); + return *this; + } + + iterator& operator--() { + this->p_ = this->p_->getPrev(); + return *this; + } + + TLinkListNode& operator*() const { + JUT_ASSERT(p_!=0); + return *this->p_; + } + + TLinkListNode* operator->() const { return this->p_; } + + TLinkListNode* p_; + }; + + class const_iterator { + public: + const_iterator(const TLinkListNode* node) { this->p_ = node; } + const_iterator(iterator it) { this->p_ = it.p_; } + const_iterator(const const_iterator& it) { this->p_ = it.p_; } + + const const_iterator& operator++() { + this->p_ = this->p_->getNext(); + return *this; + } + + const const_iterator& operator--() { + this->p_ = this->p_->getPrev(); + return *this; + } + + const TLinkListNode* operator->() const { return this->p_; } + + const TLinkListNode* p_; + }; + + bool Confirm() const; + bool Confirm_iterator(const_iterator it) const; + iterator Erase(TLinkListNode* node); + iterator Find(const TLinkListNode* node); + iterator Insert(iterator it, TLinkListNode* node); + void Remove(TLinkListNode* node); + template void Remove_if(Predicate predicate, TNodeLinkList& tList); + + s32 size() const { return this->size_; } + bool empty() const { return this->size() == 0; } + void clear() { this->erase(this->begin(), this->end()); } + iterator erase(iterator itStart, iterator itEnd); + iterator erase(iterator it); + template void remove_if(Predicate predicate) { + TNodeLinkList list; + + this->Remove_if(predicate, list); + } + void splice(iterator it, TNodeLinkList& rSrc, iterator itBegin, iterator itEnd); + void splice(iterator it, TNodeLinkList& rSrc); + void splice(iterator it, TNodeLinkList& rSrc, iterator otherIt); + iterator pop_back() { return this->erase(--this->end()); } + iterator pop_font() { return this->erase(++this->begin()); } + + iterator begin() { return this->oNode_.getNext(); } + const_iterator begin() const { return this->oNode_.getNext(); } + + iterator end() { return &this->oNode_; } + const_iterator end() const { return &this->oNode_; } + +private: + void Initialize_() { + this->size_ = 0; + this->oNode_.pNext_ = &this->oNode_; + this->oNode_.pPrev_ = &this->oNode_; + } + bool Iterator_isEnd_(const_iterator it) const { return &this->oNode_ == it.p_; } + + s32 size_; + TLinkListNode oNode_; +}; + +bool operator==(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return lhs.p_ == rhs.p_; } +bool operator!=(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return !(lhs == rhs); } + +bool operator==(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return lhs.p_ == rhs.p_; } +bool operator!=(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return !(lhs == rhs); } + +} + +#endif diff --git a/include/MSL_CPP/algorithm.h b/include/MSL_CPP/algorithm.h new file mode 100644 index 00000000..2856cb97 --- /dev/null +++ b/include/MSL_CPP/algorithm.h @@ -0,0 +1,19 @@ +#ifndef ALGORITHM_H +#define ALGORITHM_H + +#include "types.h" + +namespace std { + +template +inline +InputIterator +find_if(InputIterator first, InputIterator last, Predicate pred) { + while (first != last && !pred(*first)) + ++first; + return first; +} + +} // namespace std + +#endif diff --git a/include/MSL_CPP/iterator.h b/include/MSL_CPP/iterator.h new file mode 100644 index 00000000..be5d7378 --- /dev/null +++ b/include/MSL_CPP/iterator.h @@ -0,0 +1,38 @@ +#ifndef ITERATOR_H +#define ITERATOR_H + +#include "types.h" + +namespace std { + +struct input_iterator_tag {}; + +template +struct iterator_traits { + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +inline +typename iterator_traits::difference_type +__distance(InputIterator first, InputIterator last, input_iterator_tag) { + typename iterator_traits::difference_type result = 0; + for (; first != last; ++first) + ++result; + return result; +} + +template +inline +typename iterator_traits::difference_type +distance(InputIterator first, InputIterator last) { + return __distance(first, last, typename iterator_traits::iterator_category()); +} + +} // namespace std + +#endif diff --git a/src/JSystem/JGadget/linklist.cpp b/src/JSystem/JGadget/linklist.cpp new file mode 100644 index 00000000..05fc1094 --- /dev/null +++ b/src/JSystem/JGadget/linklist.cpp @@ -0,0 +1,198 @@ +#include "JSystem/JGadget/linklist.h" + +#include "MSL_CPP/algorithm.h" +#include "MSL_CPP/iterator.h" + +namespace JGadget { + +TNodeLinkList::~TNodeLinkList() { + Confirm(); + clear(); + JGADGET_ASSERTWARN(empty()); + this->oNode_.clear_(); +} + +void TNodeLinkList::Initialize_() { + this->size_ = 0; + this->oNode_.pNext_ = &this->oNode_; + this->oNode_.pPrev_ = &this->oNode_; +} + +TNodeLinkList::iterator TNodeLinkList::erase(iterator it, iterator itEnd) { + for (it; it != itEnd; ++it) { + this->Erase(it.p_); + } + + return itEnd; +} + +TNodeLinkList::iterator TNodeLinkList::erase(TNodeLinkList::iterator it) { + #line 102 + JUT_ASSERT(it.p_!=&oNode_); + + iterator itNext = it; + ++itNext; + + return this->erase(it, itNext); +} + +void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNodeLinkList::iterator itBegin, TNodeLinkList::iterator itEnd) { + s32 dist = 0; + + if (this == &rSrc) { + if (itBegin == itEnd) { + return; + } + } + else { + dist = std::distance(itBegin, itEnd); + + if (dist == 0) { + return; + } + } + + TLinkListNode* node_it = it.p_; + TLinkListNode* node_beg = itBegin.p_; + TLinkListNode* node_end = itEnd.p_; + + TLinkListNode* end_prev = node_end->pPrev_; + TLinkListNode* beg_prev = node_beg->pPrev_; + + beg_prev->pNext_ = node_end; + node_end->pPrev_ = beg_prev; + rSrc.size_ -= dist; + + TLinkListNode* it_prev = node_it->pPrev_; + + it_prev->pNext_ = node_beg; + node_beg->pPrev_ = it_prev; + end_prev->pNext_ = node_it; + node_it->pPrev_ = end_prev; + + this->size_ += dist; +} + +void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNodeLinkList::iterator itSrc) { + iterator itSrcNext = itSrc; + ++itSrcNext; + bool invalid = true; + + if (!(it == itSrc) && !(it == itSrcNext)) { + invalid = false; + } + + if (!invalid) { + TLinkListNode& node = *itSrc; + + rSrc.Erase(&node); + this->Insert(it, &node); + } +} + +void TNodeLinkList::splice(iterator it, TNodeLinkList& rSrc) { + #line 146 + JUT_ASSERT(this!=&rSrc); + this->splice(it, rSrc, rSrc.begin(), rSrc.end()); + JUT_ASSERT(rSrc.empty()); +} + +void TNodeLinkList::Remove(TLinkListNode* node) { + this->remove_if(TPRIsEqual_pointer_(node)); +} + +template +void TNodeLinkList::Remove_if(Predicate predicate, TNodeLinkList& tList) { + iterator itBeg = this->begin(); + iterator it = itBeg; + + while(!Iterator_isEnd_(it)) { + if (predicate(*it) == true) { + iterator itPrev = it; + ++it; + tList.splice(tList.end(), *this, itPrev); + } + else { + ++it; + } + } +} + +TNodeLinkList::iterator TNodeLinkList::Find(const TLinkListNode* node) { + return std::find_if(this->begin(), this->end(), TPRIsEqual_pointer_(node)); +} + +TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) { + #line 300 + JUT_ASSERT(p!=0); + TLinkListNode* pIt = it.p_; + JUT_ASSERT(pIt!=0); + + TLinkListNode* pItPrev = pIt->pPrev_; + JUT_ASSERT(pItPrev!=0); + + JUT_ASSERT(p->pNext_==NULL); + JUT_ASSERT(p->pPrev_==NULL); + + p->pNext_ = pIt; + p->pPrev_ = pItPrev; + pIt->pPrev_ = p; + pItPrev->pNext_ = p; + this->size_++; + + return p; +} + +TNodeLinkList::iterator TNodeLinkList::Erase(TLinkListNode* p) { + #line 325 + JUT_ASSERT(!empty()); + JUT_ASSERT(p!=0); + JUT_ASSERT(p!=&oNode_); + TLinkListNode* pNext = p->pNext_; + TLinkListNode* pPrev = p->pPrev_; + JUT_ASSERT(pNext!=0); + pNext->pPrev_ = pPrev; + JUT_ASSERT(pPrev!=0); + pPrev->pNext_ = pNext; + this->size_--; + p->clear_(); + return pNext; +} + +bool TNodeLinkList::Confirm() const { + u32 u = 0; + const_iterator itEnd(this->end()); + + #line 357 + JGADGET_EXIT(itEnd.p_==&oNode_) + const_iterator it(this->begin()); + JGADGET_EXIT(it.p_==oNode_.pNext_); // #line 359 + + for (it; it != itEnd; ++it, ++u) { + JGADGET_EXIT(upNext_->pPrev_==pIt); // #line 365 + JGADGET_EXIT(pIt->pPrev_->pNext_==pIt); // #line 366 + } + if (it.p_ == &this->oNode_) { + JGADGET_EXIT(u==size()); // #line 369 + return true; + } +} + +bool TNodeLinkList::Confirm_iterator(const_iterator it) const { + const_iterator itCur(this->begin()); + const_iterator itEnd(this->end()); + for (itCur; itCur != itEnd; ++itCur) { + if (itCur==it) { + return true; + } + } + + JGADGET_EXIT(it==itEnd); // #line 383 + return true; +} + +} // namespace JGadget + From 1e3b101bbe3317dd9cda9359bfc071a1a3e7f42a Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 2 Dec 2023 12:24:24 -0500 Subject: [PATCH 2/4] Match TP debug TNodeLinkList, first pass TLinkList --- include/JSystem/JGadget/define.h | 51 ++++++++ include/JSystem/JGadget/linklist.h | 149 +++++++++++++++++++----- include/JSystem/JUtility/JUTAssertion.h | 6 +- src/JSystem/JGadget/linklist.cpp | 128 +++++++++++--------- 4 files changed, 239 insertions(+), 95 deletions(-) create mode 100644 include/JSystem/JGadget/define.h diff --git a/include/JSystem/JGadget/define.h b/include/JSystem/JGadget/define.h new file mode 100644 index 00000000..883ed4e7 --- /dev/null +++ b/include/JSystem/JGadget/define.h @@ -0,0 +1,51 @@ +#ifndef DEFINE_H +#define DEFINE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +class JGadget_outMessage { +public: + typedef void (*MessageFunc)(const char*, int, const char*); + + static void warning(const char*, int, const char*); + + JGadget_outMessage(MessageFunc fn, const char* file, int line); + ~JGadget_outMessage(); + + JGadget_outMessage& operator<<(const char* str); + +private: + MessageFunc mMsgFunc; + char mBuffer[256]; + char* mWrite_p; + char* mFile; + int mLine; +}; + +#ifdef DEBUG + +#define JGADGET_ASSERTWARN(cond) \ + ((cond) || ((JGadget_outMessage(JGadget_outMessage::warning, __FILE__, __LINE__) << (#cond)), false)) + +#define JGADGET_EXITWARN(cond) \ + if (!(cond)) { JGadget_outMessage(JGadget_outMessage::warning, __FILE__, __LINE__) << (#cond), false; return false; } + +#else + +#define JGADGET_ASSERTWARN(cond) \ + ((cond) || (false)) + +#define JGADGET_EXITWARN(cond) \ + if (!(cond)) { false; return false; } + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 300aed73..756f53ca 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -4,25 +4,12 @@ #include "types.h" #include "JSystem/JUtility/JUTAssertion.h" +#include "JSystem/JGadget/define.h" namespace JGadget { -#define JGADGET_ASSERTWARN(cond) \ - if ((cond) == false) \ - { \ - /*JGadget_outMessage msg(&warning);*/ \ - /*msg << (#cond);*/ \ - } +namespace { -#define JGADGET_EXIT(cond) \ - if ((cond) == false) \ - { \ - /*JGadget_outMessage msg(&warning);*/ \ - /*msg << (#cond);*/ \ - return false; \ - } - -/* TODO: this definitely has a better place to live */ template class TPRIsEqual_pointer_ { public: @@ -36,6 +23,8 @@ private: const T* p_; }; +} + class TLinkListNode { public: TLinkListNode() { @@ -43,10 +32,7 @@ public: this->pPrev_ = nullptr; } - ~TLinkListNode() { - JGADGET_ASSERTWARN(pNext_==NULL); - JGADGET_ASSERTWARN(pPrev_==NULL); - } + ~TLinkListNode(); TLinkListNode* getNext() const { return this->pNext_; @@ -56,10 +42,7 @@ public: return this->pPrev_; } - void clear_() { - this->pNext_ = nullptr; - this->pPrev_ = nullptr; - } + void clear_(); TLinkListNode* pNext_; TLinkListNode* pPrev_; @@ -67,14 +50,13 @@ public: class TNodeLinkList { public: - TNodeLinkList() { Initialize_(); } + TNodeLinkList(); ~TNodeLinkList(); class iterator { public: iterator() { this->p_ = nullptr; } iterator(TLinkListNode* node) { this->p_ = node; } - iterator(const iterator& it) { this->p_ = it.p_; } iterator& operator++() { this->p_ = this->p_->getNext(); @@ -100,7 +82,6 @@ public: public: const_iterator(const TLinkListNode* node) { this->p_ = node; } const_iterator(iterator it) { this->p_ = it.p_; } - const_iterator(const const_iterator& it) { this->p_ = it.p_; } const const_iterator& operator++() { this->p_ = this->p_->getNext(); @@ -123,7 +104,7 @@ public: iterator Find(const TLinkListNode* node); iterator Insert(iterator it, TLinkListNode* node); void Remove(TLinkListNode* node); - template void Remove_if(Predicate predicate, TNodeLinkList& tList); + template void Remove_if(Predicate predicate, TNodeLinkList& other); s32 size() const { return this->size_; } bool empty() const { return this->size() == 0; } @@ -148,11 +129,7 @@ public: const_iterator end() const { return &this->oNode_; } private: - void Initialize_() { - this->size_ = 0; - this->oNode_.pNext_ = &this->oNode_; - this->oNode_.pPrev_ = &this->oNode_; - } + void Initialize_(); bool Iterator_isEnd_(const_iterator it) const { return &this->oNode_ == it.p_; } s32 size_; @@ -165,6 +142,114 @@ bool operator!=(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { retu bool operator==(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return lhs.p_ == rhs.p_; } bool operator!=(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return !(lhs == rhs); } +template +class TLinkList : public TNodeLinkList { + class iterator { + public: + iterator iterator(TNodeLinkList::iterator it) : mIt(it) { } + + bool operator==(iterator other) { return (mIt == other.mIt); } + bool operator!=(iterator other) { return !(*this == other); } + iterator& operator++() { + ++mIt; + return *this; + } + iterator& operator--() { + --mIt; + return *this; + } + + T* operator->() const { return TLinkList::Element_toValue(TNodeLinkList::iterator::operator->(mIt)); } + T& operator*() const { + T* p = TLinkList::iterator::operator->(); + #line 541 + JUT_ASSERT(p!=0); + return *p; + } + + private: + TNodeLinkList::iterator mIt; + }; + + class const_iterator { + public: + const_iterator iterator(TNodeLinkList::const_iterator it) : mIt(it) { } + + bool operator==(const_iterator other) { return (mIt == other.mIt); } + bool operator!=(const_iterator other) { return !(*this == other); } + const_iterator& operator++() { + ++mIt; + return *this; + } + const_iterator& operator--() { + --mIt; + return *this; + } + + const T* operator->() const { return TLinkList::Element_toValue(TNodeLinkList::const_iterator::operator->(mIt)); } + const T& operator*() const { + T* p = TLinkList::const_iterator::operator->(); + #line 586 + JUT_ASSERT(p!=0); + return *p; + } + + private: + TNodeLinkList::const_iterator mIt; + }; + + iterator Find(const T* p) { return TNodeLinkList::Find(TLinkList::Element_toNode(p)); } + iterator Erase( T* p) { return TNodeLinkList::Erase(Element_toNode(p)); } + iterator Insert(iterator it, T* p) { return TNodeLinkList::Insert(it, Element_toNode(p)); } + void Remove(T* p) { TNodeLinkList::Remove(TLinkList::Element_toNode(p)); } + void Push_front(T* p) { Insert(begin(), p); } + void Push_back(T* p) { Insert(end(), p); } + + T& front() { + #line 642 + JUT_ASSERT(!empty()); + return *begin(); + } + + T& back() { + #line 652 + JUT_ASSERT(!empty()); + iterator itEnd = end(); + --itEnd; + return *itEnd; + } + + iterator begin() { return TNodeLinkList::begin(); } + const_iterator begin() const { return TNodeLinkList::begin(); } + + iterator end() { return TNodeLinkList::end(); } + const_iterator end() const { return TNodeLinkList::end(); } + + static TLinkListNode* Element_toNode(T* p) { + #line 753 + JUT_ASSERT(p!=0); + return (TLinkListNode*)((char*)p + O); + } + + static const TLinkListNode* Element_toNode(const T* p) { + #line 758 + JUT_ASSERT(p!=0); + return (const TLinkListNode*)((const char*)p + O); + } + + static T* Element_toValue(TLinkListNode* p) { + #line 763 + JUT_ASSERT(p!=0); + return (T*)((char*)p - O); + } + + static const T* Element_toValue(const TLinkListNode* p) { + #line 763 + JUT_ASSERT(p!=0); + return (const T*)((const char*)p - O); + } +}; + } #endif diff --git a/include/JSystem/JUtility/JUTAssertion.h b/include/JSystem/JUtility/JUTAssertion.h index b273397f..a96af3f3 100644 --- a/include/JSystem/JUtility/JUTAssertion.h +++ b/include/JSystem/JUtility/JUTAssertion.h @@ -52,11 +52,7 @@ namespace JUTAssertion #else #define JUT_ASSERT(COND) \ - if ((COND) == false) \ - { \ - JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, #COND); \ - OSHalt("Halt"); \ - } + ((COND)) ? (void)0 : (JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, #COND), OSHalt("Halt")); #define JUT_ASSERT_F(COND, ...) \ if ((COND) == false) \ diff --git a/src/JSystem/JGadget/linklist.cpp b/src/JSystem/JGadget/linklist.cpp index 05fc1094..127eb3fc 100644 --- a/src/JSystem/JGadget/linklist.cpp +++ b/src/JSystem/JGadget/linklist.cpp @@ -19,8 +19,13 @@ void TNodeLinkList::Initialize_() { } TNodeLinkList::iterator TNodeLinkList::erase(iterator it, iterator itEnd) { - for (it; it != itEnd; ++it) { - this->Erase(it.p_); + TLinkListNode* cur = it.p_; + TLinkListNode* end = itEnd.p_; + TLinkListNode* next; + + for (; cur != end; cur = next) { + next = cur->pNext_; + this->Erase(cur); } return itEnd; @@ -76,13 +81,8 @@ void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNod void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNodeLinkList::iterator itSrc) { iterator itSrcNext = itSrc; ++itSrcNext; - bool invalid = true; - if (!(it == itSrc) && !(it == itSrcNext)) { - invalid = false; - } - - if (!invalid) { + if (((it == itSrc) || (it == itSrcNext)) == false) { TLinkListNode& node = *itSrc; rSrc.Erase(&node); @@ -97,31 +97,13 @@ void TNodeLinkList::splice(iterator it, TNodeLinkList& rSrc) { JUT_ASSERT(rSrc.empty()); } -void TNodeLinkList::Remove(TLinkListNode* node) { - this->remove_if(TPRIsEqual_pointer_(node)); -} - -template -void TNodeLinkList::Remove_if(Predicate predicate, TNodeLinkList& tList) { - iterator itBeg = this->begin(); - iterator it = itBeg; - - while(!Iterator_isEnd_(it)) { - if (predicate(*it) == true) { - iterator itPrev = it; - ++it; - tList.splice(tList.end(), *this, itPrev); - } - else { - ++it; - } - } -} - TNodeLinkList::iterator TNodeLinkList::Find(const TLinkListNode* node) { - return std::find_if(this->begin(), this->end(), TPRIsEqual_pointer_(node)); + return std::find_if(this->begin(), this->end(), TPRIsEqual_pointer_(node)); } +#undef NULL +#define NULL 0 + TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) { #line 300 JUT_ASSERT(p!=0); @@ -131,8 +113,8 @@ TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) { TLinkListNode* pItPrev = pIt->pPrev_; JUT_ASSERT(pItPrev!=0); - JUT_ASSERT(p->pNext_==NULL); - JUT_ASSERT(p->pPrev_==NULL); + JGADGET_ASSERTWARN(p->pNext_==NULL); + JGADGET_ASSERTWARN(p->pPrev_==NULL); p->pNext_ = pIt; p->pPrev_ = pItPrev; @@ -143,6 +125,9 @@ TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) { return p; } +#undef NULL +#define NULL (void*)0; + TNodeLinkList::iterator TNodeLinkList::Erase(TLinkListNode* p) { #line 325 JUT_ASSERT(!empty()); @@ -159,38 +144,65 @@ TNodeLinkList::iterator TNodeLinkList::Erase(TLinkListNode* p) { return pNext; } -bool TNodeLinkList::Confirm() const { - u32 u = 0; - const_iterator itEnd(this->end()); - - #line 357 - JGADGET_EXIT(itEnd.p_==&oNode_) - const_iterator it(this->begin()); - JGADGET_EXIT(it.p_==oNode_.pNext_); // #line 359 +void TNodeLinkList::Remove(TLinkListNode* node) { + this->remove_if(TPRIsEqual_pointer_(node)); +} - for (it; it != itEnd; ++it, ++u) { - JGADGET_EXIT(upNext_->pPrev_==pIt); // #line 365 - JGADGET_EXIT(pIt->pPrev_->pNext_==pIt); // #line 366 - } - if (it.p_ == &this->oNode_) { - JGADGET_EXIT(u==size()); // #line 369 - return true; +template +void TNodeLinkList::Remove_if(Predicate predicate, TNodeLinkList& tList) { + iterator it = this->begin(); + + while(!Iterator_isEnd_(it)) { + if (predicate(*it)) { + iterator itPrev = it; + ++it; + tList.splice(tList.end(), *this, itPrev); + } + else { + ++it; + } } } -bool TNodeLinkList::Confirm_iterator(const_iterator it) const { - const_iterator itCur(this->begin()); - const_iterator itEnd(this->end()); - for (itCur; itCur != itEnd; ++itCur) { - if (itCur==it) { - return true; - } +bool TNodeLinkList::Confirm() const { + u32 u = 0; + const_iterator itEnd = this->end(); + + #line 357 + JGADGET_EXITWARN(itEnd.p_==&oNode_); + const_iterator it = this->begin(); + JGADGET_EXITWARN(it.p_==oNode_.pNext_); // #line 359 + + for (; it != itEnd; ++it, ++u) { + JGADGET_EXITWARN(upNext_->pPrev_==pIt); + JGADGET_EXITWARN(pIt->pPrev_->pNext_==pIt); // #line 366 } - JGADGET_EXIT(it==itEnd); // #line 383 + #line 368 + JGADGET_EXITWARN(it.p_==&oNode_); + JGADGET_EXITWARN(u==size()); + return true; +} + +bool TNodeLinkList::Confirm_iterator(const_iterator it) const { + const_iterator itBegin = begin(); + const_iterator itEnd = end(); + + while (itBegin != itEnd) { + if (itBegin == it) { + return true; + } + + ++itBegin; + } + + #line 383 + JGADGET_EXITWARN(it==itEnd); + return true; } From c815fef8cb70506da81efc46ddd77e3a3c9ee919 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 2 Dec 2023 12:30:50 -0500 Subject: [PATCH 3/4] Fix operator accessing --- include/JSystem/JGadget/linklist.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 756f53ca..9f704f2b 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -159,9 +159,9 @@ class TLinkList : public TNodeLinkList { return *this; } - T* operator->() const { return TLinkList::Element_toValue(TNodeLinkList::iterator::operator->(mIt)); } + T* operator->() const { return TLinkList::Element_toValue(mIt.operator->()); } T& operator*() const { - T* p = TLinkList::iterator::operator->(); + T* p = this->operator->(); #line 541 JUT_ASSERT(p!=0); return *p; @@ -186,9 +186,9 @@ class TLinkList : public TNodeLinkList { return *this; } - const T* operator->() const { return TLinkList::Element_toValue(TNodeLinkList::const_iterator::operator->(mIt)); } + const T* operator->() const { return TLinkList::Element_toValue(mIt.operator->()); } const T& operator*() const { - T* p = TLinkList::const_iterator::operator->(); + T* p = this->operator->(); #line 586 JUT_ASSERT(p!=0); return *p; @@ -244,7 +244,7 @@ class TLinkList : public TNodeLinkList { } static const T* Element_toValue(const TLinkListNode* p) { - #line 763 + #line 768 JUT_ASSERT(p!=0); return (const T*)((const char*)p - O); } From e01a9b4f74269cd96a9847b8411eede27851fb44 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 2 Dec 2023 14:35:29 -0500 Subject: [PATCH 4/4] Link linklist.cpp --- common.py | 14 ++++++++ config/dol_slices.yml | 2 ++ configure.py | 3 ++ include/JSystem/JGadget/linklist.h | 56 +++++++++++++++++++++++------- include/MSL_CPP/iterator.h | 20 ++++------- src/JSystem/JGadget/linklist.cpp | 39 ++++++--------------- 6 files changed, 80 insertions(+), 54 deletions(-) diff --git a/common.py b/common.py index a0942ee0..7702845f 100644 --- a/common.py +++ b/common.py @@ -409,8 +409,22 @@ JSYSTEM_BASE = [ "-sym on", # might also be on for base flags? "-O4,s" # in mkdd some libraries use O4,p, might be the case here too ] +JSYSTEM_JGADGET_BASE = [ + "-lang=c++", + "-inline on", + "-fp fmadd", + #"-fp_contract on", + #"-pool off", # this is wrong + "-Cpp_exceptions off", + "-RTTI on", + "-char signed", + "-enum int", + # "-sym on", # might also be on for base flags? + "-O4,s" # in mkdd some libraries use O4,p, might be the case here too +] JSYSTEM_CFLAGS = ' '.join(JSYSTEM_BASE + LOCAL_CFLAGS) +JSYSTEM_JGADGET_CFLAGS = ' '.join(JSYSTEM_JGADGET_BASE + LOCAL_CFLAGS) DOL_CFLAGS = ' '.join(BASE_DOL_CFLAGS + LOCAL_CFLAGS) DOL_BOOT_CFLAGS = ' '.join(BOOT_CFLAGS + LOCAL_CFLAGS) DOL_DVDERR_CFLAGS = ' '.join(DVDERR_CFLAGS + LOCAL_CFLAGS) diff --git a/config/dol_slices.yml b/config/dol_slices.yml index c36022c8..119c166f 100644 --- a/config/dol_slices.yml +++ b/config/dol_slices.yml @@ -230,6 +230,8 @@ JSystem/JSupport/JSUInputStream.cpp: # .text: [0x8006e3e4, 0x8006e604] # .data: [0x800dedb8, 0x800dee60] # .sdata: [0x80218068, 0x80218088] +JSystem/JGadget/linklist.cpp: + .text: [0x8006e604, 0x8006e800] JSystem/JUtility/JUTGamePad.cpp: .text: [0x80070274, 0x800713b0] .ctors: [0x800a97ac, 0x800a97b0] diff --git a/configure.py b/configure.py index 94f2df41..4b4830fb 100644 --- a/configure.py +++ b/configure.py @@ -618,6 +618,9 @@ class CSource(Source): if path.startswith("src/dolphin/"): self.cflags = c.SDK_FLAGS self.cc = c.OCC + elif path.startswith("src/JSystem/JGadget/"): + self.cflags = c.JSYSTEM_JGADGET_CFLAGS + self.cc = c.CC elif path.startswith("src/JSystem/"): self.cflags = c.JSYSTEM_CFLAGS self.cc = c.CC diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 9f704f2b..aed8e8a3 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -16,7 +16,7 @@ public: TPRIsEqual_pointer_(const T* p) { this->p_ = p; } bool operator()(const T& rSrc) const { - return this->p_ == &rSrc; + return &rSrc == this->p_; } private: @@ -32,7 +32,14 @@ public: this->pPrev_ = nullptr; } - ~TLinkListNode(); + ~TLinkListNode() { + // Seemingly not present in earlier versions of JSystem + /* + #line 77 + JUT_ASSERT(pNext_==NULL); + JUT_ASSERT(pPrev_==NULL); + */ + } TLinkListNode* getNext() const { return this->pNext_; @@ -42,7 +49,10 @@ public: return this->pPrev_; } - void clear_(); + void clear_() { + this->pNext_ = nullptr; + this->pPrev_ = nullptr; + } TLinkListNode* pNext_; TLinkListNode* pPrev_; @@ -50,7 +60,7 @@ public: class TNodeLinkList { public: - TNodeLinkList(); + TNodeLinkList() : oNode_() { Initialize_(); } ~TNodeLinkList(); class iterator { @@ -104,7 +114,20 @@ public: iterator Find(const TLinkListNode* node); iterator Insert(iterator it, TLinkListNode* node); void Remove(TLinkListNode* node); - template void Remove_if(Predicate predicate, TNodeLinkList& other); + template void Remove_if(Predicate predicate, TNodeLinkList& tList) { + iterator it = this->begin(); + + while(!Iterator_isEnd_(it)) { + if (predicate(*it)) { + iterator itPrev = it; + ++it; + tList.splice(tList.end(), *this, itPrev); + } + else { + ++it; + } + } + } s32 size() const { return this->size_; } bool empty() const { return this->size() == 0; } @@ -129,24 +152,31 @@ public: const_iterator end() const { return &this->oNode_; } private: - void Initialize_(); - bool Iterator_isEnd_(const_iterator it) const { return &this->oNode_ == it.p_; } + void Initialize_() { + this->size_ = 0; + this->oNode_.pNext_ = &this->oNode_; + this->oNode_.pPrev_ = &this->oNode_; + } + + bool Iterator_isEnd_(const_iterator it) const { return it.p_ == &this->oNode_; } s32 size_; TLinkListNode oNode_; }; -bool operator==(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return lhs.p_ == rhs.p_; } -bool operator!=(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return !(lhs == rhs); } +inline bool operator==(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return lhs.p_ == rhs.p_; } +inline bool operator!=(TNodeLinkList::iterator lhs, TNodeLinkList::iterator rhs) { return !(lhs == rhs); } -bool operator==(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return lhs.p_ == rhs.p_; } -bool operator!=(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return !(lhs == rhs); } +inline bool operator==(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return lhs.p_ == rhs.p_; } +inline bool operator!=(TNodeLinkList::const_iterator lhs, TNodeLinkList::const_iterator rhs) { return !(lhs == rhs); } + +/* TODO: TLinkList has not been matched and should be verified */ template class TLinkList : public TNodeLinkList { class iterator { public: - iterator iterator(TNodeLinkList::iterator it) : mIt(it) { } + iterator(TNodeLinkList::iterator it) : mIt(it) { } bool operator==(iterator other) { return (mIt == other.mIt); } bool operator!=(iterator other) { return !(*this == other); } @@ -173,7 +203,7 @@ class TLinkList : public TNodeLinkList { class const_iterator { public: - const_iterator iterator(TNodeLinkList::const_iterator it) : mIt(it) { } + const_iterator(TNodeLinkList::const_iterator it) : mIt(it) { } bool operator==(const_iterator other) { return (mIt == other.mIt); } bool operator!=(const_iterator other) { return !(*this == other); } diff --git a/include/MSL_CPP/iterator.h b/include/MSL_CPP/iterator.h index be5d7378..88998d2d 100644 --- a/include/MSL_CPP/iterator.h +++ b/include/MSL_CPP/iterator.h @@ -5,22 +5,15 @@ namespace std { -struct input_iterator_tag {}; +/* TODO: these should be properly implemented */ -template -struct iterator_traits { - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; - typedef typename Iterator::iterator_category iterator_category; -}; +struct input_iterator_tag {}; template inline -typename iterator_traits::difference_type +s32 __distance(InputIterator first, InputIterator last, input_iterator_tag) { - typename iterator_traits::difference_type result = 0; + s32 result = 0; for (; first != last; ++first) ++result; return result; @@ -28,9 +21,10 @@ __distance(InputIterator first, InputIterator last, input_iterator_tag) { template inline -typename iterator_traits::difference_type +s32 distance(InputIterator first, InputIterator last) { - return __distance(first, last, typename iterator_traits::iterator_category()); + input_iterator_tag tag; + return __distance(first, last, tag); } } // namespace std diff --git a/src/JSystem/JGadget/linklist.cpp b/src/JSystem/JGadget/linklist.cpp index 127eb3fc..9232b684 100644 --- a/src/JSystem/JGadget/linklist.cpp +++ b/src/JSystem/JGadget/linklist.cpp @@ -6,16 +6,12 @@ namespace JGadget { TNodeLinkList::~TNodeLinkList() { + #ifdef DEBUG Confirm(); clear(); + #endif JGADGET_ASSERTWARN(empty()); - this->oNode_.clear_(); -} - -void TNodeLinkList::Initialize_() { - this->size_ = 0; - this->oNode_.pNext_ = &this->oNode_; - this->oNode_.pPrev_ = &this->oNode_; + //this->oNode_.clear_(); } TNodeLinkList::iterator TNodeLinkList::erase(iterator it, iterator itEnd) { @@ -82,11 +78,14 @@ void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNod iterator itSrcNext = itSrc; ++itSrcNext; - if (((it == itSrc) || (it == itSrcNext)) == false) { - TLinkListNode& node = *itSrc; + if ((it == itSrc) || (it == itSrcNext)) { + return; + } + else { + TLinkListNode* const node = &*itSrc; - rSrc.Erase(&node); - this->Insert(it, &node); + rSrc.Erase(node); + this->Insert(it, node); } } @@ -140,7 +139,7 @@ TNodeLinkList::iterator TNodeLinkList::Erase(TLinkListNode* p) { JUT_ASSERT(pPrev!=0); pPrev->pNext_ = pNext; this->size_--; - p->clear_(); + //p->clear_(); return pNext; } @@ -148,22 +147,6 @@ void TNodeLinkList::Remove(TLinkListNode* node) { this->remove_if(TPRIsEqual_pointer_(node)); } -template -void TNodeLinkList::Remove_if(Predicate predicate, TNodeLinkList& tList) { - iterator it = this->begin(); - - while(!Iterator_isEnd_(it)) { - if (predicate(*it)) { - iterator itPrev = it; - ++it; - tList.splice(tList.end(), *this, itPrev); - } - else { - ++it; - } - } -} - bool TNodeLinkList::Confirm() const { u32 u = 0; const_iterator itEnd = this->end();