First pass linklist

This commit is contained in:
Cuyler36
2023-11-28 11:17:10 -05:00
parent b61bf26bdb
commit fa466b571b
4 changed files with 425 additions and 0 deletions
+170
View File
@@ -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 <typename T>
class TPRIsEqual_pointer_ {
public:
TPRIsEqual_pointer_<T>(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 <typename Predicate> 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 <typename Predicate> 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
+19
View File
@@ -0,0 +1,19 @@
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include "types.h"
namespace std {
template <class InputIterator, class Predicate>
inline
InputIterator
find_if(InputIterator first, InputIterator last, Predicate pred) {
while (first != last && !pred(*first))
++first;
return first;
}
} // namespace std
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifndef ITERATOR_H
#define ITERATOR_H
#include "types.h"
namespace std {
struct input_iterator_tag {};
template<class Iterator>
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 <class InputIterator>
inline
typename iterator_traits<InputIterator>::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag) {
typename iterator_traits<InputIterator>::difference_type result = 0;
for (; first != last; ++first)
++result;
return result;
}
template <class InputIterator>
inline
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
return __distance(first, last, typename iterator_traits<InputIterator>::iterator_category());
}
} // namespace std
#endif
+198
View File
@@ -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<typename Predicate>
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(u<size()); // #line 362
const TLinkListNode* pIt = it.p_;
JUT_ASSERT(pIt!=0); // #line 364
JGADGET_EXIT(pIt->pNext_->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