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