1 /* 2 Copyright (c) 2000-2003 Lee Thomason (www.grinninglizard.com) 3 4 Grinning Lizard Utilities. Note that software that uses the 5 utility package (including Lilith3D and Kyra) have more restrictive 6 licences which applies to code outside of the utility package. 7 8 9 This software is provided 'as-is', without any express or implied 10 warranty. In no event will the authors be held liable for any 11 damages arising from the use of this software. 12 13 Permission is granted to anyone to use this software for any 14 purpose, including commercial applications, and to alter it and 15 redistribute it freely, subject to the following restrictions: 16 17 1. The origin of this software must not be misrepresented; you must 18 not claim that you wrote the original software. If you use this 19 software in a product, an acknowledgment in the product documentation 20 would be appreciated but is not required. 21 22 2. Altered source versions must be plainly marked as such, and 23 must not be misrepresented as being the original software. 24 25 3. This notice may not be removed or altered from any source 26 distribution. 27 */ 28 29 #ifndef INPLACE_IMAGENODE_INCLUDED 30 #define INPLACE_IMAGENODE_INCLUDED 31 32 #ifdef _MSC_VER 33 #pragma warning( disable : 4530 ) 34 #pragma warning( disable : 4786 ) 35 #endif 36 37 #include "../../grinliz/gldebug.h" 38 39 // The type of this must be a pointer. 40 template <class T> 41 class GlInsideNode 42 { 43 public: 44 /// Constructs a sentinel node. GlInsideNode()45 GlInsideNode() { next = this; prev = this; data = 0; } 46 47 /// If image is null, this will be a sentinel node. GlInsideNode(T _data)48 GlInsideNode( T _data ) { next = this; prev = this; data = _data; } 49 ~GlInsideNode()50 virtual ~GlInsideNode() {} 51 IsSentinel()52 bool IsSentinel() const { return !data; } InList()53 bool InList() const { return !(( next == this ) && ( prev == this )); } 54 55 /// Insert addMe before this. InsertBefore(GlInsideNode<T> * addMe)56 void InsertBefore( GlInsideNode<T>* addMe ) 57 { 58 GLASSERT( !addMe->IsSentinel() ); 59 addMe->prev = prev; 60 prev->next = addMe; 61 prev = addMe; 62 addMe->next = this; 63 } 64 65 /// Insert addMe after this. InsertAfter(GlInsideNode<T> * addMe)66 void InsertAfter( GlInsideNode<T>* addMe ) 67 { 68 GLASSERT( !addMe->IsSentinel() ); 69 addMe->prev = this; 70 addMe->next = next; 71 next->prev = addMe; 72 next = addMe; 73 } 74 75 /// Take this node out of the list Remove()76 void Remove() 77 { 78 prev->next = next; 79 next->prev = prev; 80 prev = next = this; // assume sentinel, again. 81 } 82 83 // Should be private, but I don't feel like fighting with 84 // making templates friends. 85 86 GlInsideNode<T>* next; 87 GlInsideNode<T>* prev; 88 T data; 89 }; 90 91 92 template <class T> 93 class GlInsideNodeIt 94 { 95 public: GlInsideNodeIt(GlInsideNode<T> & _sentinel)96 GlInsideNodeIt( GlInsideNode<T>& _sentinel ) 97 : sentinel( &_sentinel ), current( 0 ) 98 { 99 GLASSERT( sentinel->IsSentinel() ); 100 } 101 CurrentNode()102 GlInsideNode<T>* CurrentNode() { return current; } CurrentData()103 T CurrentData() { return current->data; } SetCurrent(GlInsideNode<T> * c)104 void SetCurrent( GlInsideNode<T>* c ) { current = c; } 105 Begin()106 void Begin() { current = sentinel->next; } Last()107 void Last() { current = sentinel->prev; } Next()108 void Next() { current = current->next; } Prev()109 void Prev() { current = current->prev; } Done()110 bool Done() { return current->IsSentinel(); } 111 InsertBefore(GlInsideNode<T> & addMe)112 void InsertBefore( GlInsideNode<T>& addMe ) { current->InsertBefore( &addMe ); } InsertAfter(GlInsideNode<T> & addMe)113 void InsertAfter( GlInsideNode<T>& addMe ) { current->InsertAfter( &addMe ); } 114 115 private: 116 GlInsideNode<T>* sentinel; 117 GlInsideNode<T>* current; 118 }; 119 120 121 #endif 122