#ifndef JSULIST_H #define JSULIST_H #include "dolphin/types.h" template class JSUList; // // Link // class JSUPtrList; class JSUPtrLink { public: JSUPtrLink(void* object); ~JSUPtrLink(); void* getObjectPtr() const { return mObject; } JSUPtrList* getList() const { return mList; } JSUPtrLink* getNext() const { return mNext; } JSUPtrLink* getPrev() const { return mPrev; } public: void* mObject; JSUPtrList* mList; JSUPtrLink* mPrev; JSUPtrLink* mNext; }; template class JSULink : public JSUPtrLink { public: JSULink(T* object) : JSUPtrLink((void*)object) {} T* getObject() const { return (T*)getObjectPtr(); } JSUList* getSupervisor() const { return (JSUList*)this->getList(); } JSULink* getNext() const { return (JSULink*)this->JSUPtrLink::getNext(); } JSULink* getPrev() const { return (JSULink*)this->JSUPtrLink::getPrev(); } }; // // List // class JSUPtrList { public: JSUPtrList() { this->initiate(); } JSUPtrList(bool init); ~JSUPtrList(); void initiate(); void setFirst(JSUPtrLink* first); bool append(JSUPtrLink* ptr); bool prepend(JSUPtrLink* ptr); bool insert(JSUPtrLink* before, JSUPtrLink* ptr); bool remove(JSUPtrLink* ptr); JSUPtrLink* getNthLink(u32 i) const; JSUPtrLink* getFirstLink() const { return mHead; } JSUPtrLink* getLastLink() const { return mTail; } u32 getNumLinks() const { return mLength; } private: JSUPtrLink* mHead; JSUPtrLink* mTail; u32 mLength; }; template class JSUList : public JSUPtrList { public: JSUList() : JSUPtrList() {} JSUList(bool init) : JSUPtrList(init) {} ~JSUList() {} bool append(JSULink* link) { return this->JSUPtrList::append((JSUPtrLink*)link); } bool prepend(JSULink* link) { return this->JSUPtrList::prepend((JSUPtrLink*)link); } bool insert(JSULink* before, JSULink* link) { return this->JSUPtrList::insert((JSUPtrLink*)before, (JSUPtrLink*)link); } bool remove(JSULink* link) { return this->JSUPtrList::remove((JSUPtrLink*)link); } JSULink* getFirst() const { return (JSULink*)getFirstLink(); } JSULink* getLast() const { return (JSULink*)getLastLink(); } JSULink* getEnd() const { return NULL; } u32 getNumLinks() const { return this->JSUPtrList::getNumLinks(); } }; template class JSUListIterator { public: JSUListIterator() : mLink(NULL) {} JSUListIterator(JSULink* link) : mLink(link) {} JSUListIterator(JSUList* list) : mLink(list->getFirst()) {} JSUListIterator& operator=(JSULink* link) { this->mLink = link; return *this; } T* getObject() { return this->mLink->getObject(); } bool operator==(JSULink const* other) const { return this->mLink == other; } bool operator!=(JSULink const* other) const { return this->mLink != other; } bool operator==(JSUListIterator const& other) const { return this->mLink == other.mLink; } bool operator!=(JSUListIterator const& other) const { return this->mLink != other.other; } JSUListIterator operator++(int) { JSUListIterator prev = *this; this->mLink = this->mLink->getNext(); return prev; } JSUListIterator& operator++() { this->mLink = this->mLink->getNext(); return *this; } JSUListIterator operator--(int) { JSUListIterator prev = *this; this->mLink = this->mLink->getPrev(); return prev; } JSUListIterator& operator--() { this->mLink = this->mLink->getPrev(); return *this; } T& operator*() { return *this->getObject(); } T* operator->() { return this->getObject(); } private: JSULink* mLink; }; // // Tree // #define JSU_TREE_FROM_LINK(T, LINK) (JSUTree*)(((u8*)(LINK)) - 12) #define JSU_TREE_LINK_IF_NOT_NULL(TREE) \ if (TREE) { \ TREE = (JSUTree*)(&(TREE)->mLink); \ } #define _JSU_TREE_AS_LINK(TREE) ((JSULink*)(TREE)) template class JSUTree { public: JSUTree(T* owner) : mList(), mLink(owner) {} ~JSUTree() {} bool appendChild(JSUTree* child) { JSU_TREE_LINK_IF_NOT_NULL(child); return this->mList.append(_JSU_TREE_AS_LINK(child)); } bool removeChild(JSUTree* child) { JSU_TREE_LINK_IF_NOT_NULL(child); return this->mList.remove(_JSU_TREE_AS_LINK(child)); } bool insertChild(JSUTree* before, JSUTree* child) { JSU_TREE_LINK_IF_NOT_NULL(before); JSU_TREE_LINK_IF_NOT_NULL(child); return this->mList.insert(_JSU_TREE_AS_LINK(before), _JSU_TREE_AS_LINK(child)); } JSUTree* getEndChild() const { return NULL; } JSUTree* getFirstChild() const { JSULink* link = this->mList.getFirst(); return link ? JSU_TREE_FROM_LINK(T, link) : (JSUTree*)link; } JSUTree* getLastChild() const { JSULink* link = this->mList.getLast(); return link ? JSU_TREE_FROM_LINK(T, link) : (JSUTree*)link; } JSUTree* getNextChild() const { JSULink* link = this->mLink.getNext(); return link ? JSU_TREE_FROM_LINK(T, link) : (JSUTree*)link; } JSUTree* getPrevChild() const { JSULink* link = this->mLink.getPrev(); return link ? JSU_TREE_FROM_LINK(T, link) : (JSUTree*)link; } u32 getNumChildren() const { return this->mList.getNumLinks(); } T* getObject() const { return this->mLink.getObject(); } JSUTree* getParent() const { return (JSUTree*)this->mLink.getList(); } private: JSUList mList; JSULink mLink; }; template class JSUTreeIterator { public: JSUTreeIterator() : mTree(NULL) {} JSUTreeIterator(JSUTree* tree) : mTree(tree) {} JSUTreeIterator& operator=(JSUTree* tree) { this->mTree = tree; return *this; } T* getObject() { return this->mTree->getObject(); } bool operator==(JSUTree* other) { return this->mTree == other; } bool operator!=(JSUTree* other) { return this->mTree != other; } JSUTreeIterator operator++(int) { JSUTreeIterator prev = *this; this->mTree = this->mTree->getNextChild(); return prev; } JSUTreeIterator& operator++() { this->mTree = this->mTree->getNextChild(); return *this; } T& operator*() { return *this->getObject(); } T* operator->() { return this->getObject(); } private: JSUTree* mTree; }; #endif /* JSULIST_H */