From fa466b571b5473104d005c7633dec916bb8bedd1 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 28 Nov 2023 11:17:10 -0500 Subject: [PATCH] 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 +