1 /* -*- mode: c++; c-file-style: raknet; tab-always-indent: nil; -*- */
2 /**
3  * @file
4  *
5  * @brief LinkedList and Circular Linked List
6  *
7  * Copyright (c) 2003, Rakkarsoft LLC and Kevin Jenkins
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in the
16  *       documentation and/or other materials provided with the distribution.
17  *     * Neither the name of the <organization> nor the
18  *       names of its contributors may be used to endorse or promote products
19  *       derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * 9/04 Giblet - updated code to work with new compilers adhering more
33  *   closely to ISO standard
34  *
35  */
36 
37 #ifndef __LINKED_LIST_H
38 #define __LINKED_LIST_H
39 /**
40 * @brief Basic Data Structures (containers)
41 *
42 * This namespace contains containers used in RakNet.
43 */
44 
45 namespace BasicDataStructures
46 {
47 
48 	// Prototype to prevent error in CircularLinkedList class when a reference is made to a LinkedList class
49 
50 	template <class LinkedListType>
51 
52 	class LinkedList;
53 
54 	/**
55 	* (Circular) Linked List ADT (Doubly Linked Pointer to Node Style) -
56 	* By Kevin Jenkins (http://www.rakkar.org)
57 	* Initilize with the following command
58 	* LinkedList<TYPE>
59 	* OR
60 	* CircularLinkedList<Type>
61 	*
62 	* Has the following member functions
63 	* - size: returns number of elements in the linked list
64 	* - insert(item):  inserts @em item at the current position in
65 	*   the LinkedList.
66 	* - add(item): inserts @em item after the current position in
67 	*   the LinkedList.  Does not increment the position
68 	* - replace(item): replaces the element at the current position @em item.
69 	* - peek:  returns the element at the current position
70 	* - pop:  returns the element at the current position and deletes it
71 	* - del: deletes the current element. Does nothing for an empty list.
72 	* - clear:  empties the LinkedList and returns storage
73 	* - bool is_in(item): Does a linear search for @em item.  Does not set
74 	*   the position to it, only returns true on item found, false otherwise
75 	* - bool find(item): Does a linear search for @em item and sets the current
76 	*   position to point to it if and only if the item is found. Returns true
77 	*   on item found, false otherwise
78 	* - sort: Sorts the elements of the list with a mergesort and sets the
79 	*   current pointer to the first element
80 	* - concatenate(list L): This appends L to the current list
81 	* - ++(prefix): moves the pointer one element up in the list and returns the
82 	*   appropriate copy of the element in the list
83 	* - --(prefix): moves the pointer one element back in the list and returns
84 	*   the appropriate copy of the element in the list
85 	* - beginning - moves the pointer to the start of the list.  For circular
86 	*   linked lists this is first 'position' created.  You should call this
87 	*   after the sort function to read the first value.
88 	* - end - moves the pointer to the end of the list.  For circular linked
89 	*   lists this is one less than the first 'position' created
90 	* The assignment and copy constructor operators are defined
91 	*
92 	* @note
93 	* 1. LinkedList and CircularLinkedList are exactly the same except LinkedList
94 	*    won't let you wrap around the root and lets you jump to two positions
95 	*    relative to the root/
96 	* 2. Postfix ++ and -- can be used but simply call the prefix versions.
97 	*
98 	*
99 	* EXAMPLE:
100 	* @code
101 	* LinkedList<int> A;  // Creates a Linked List of integers called A
102 	* CircularLinkedList<int> B;  // Creates a Circular Linked List of
103 	*          // integers called B
104 	*
105 	* A.insert(20);  // Adds 20 to A.  A: 20 - current is 20
106 	* A.insert(5);  // Adds 5 to A.  A: 5 20 - current is 5
107 	* A.insert(1);  // Adds 1 to A.  A: 1 5 20 - current is 1
108 	*
109 	* A.is_in(1); // returns true
110 	* A.is_in(200); // returns false
111 	* A.find(5);  // returns true and sets current to 5
112 	* A.peek();  // returns 5
113 	* A.find(1);  // returns true and sets current to 1
114 	*
115 	* (++A).peek();  // Returns 5
116 	* A.peek(); // Returns 5
117 	*
118 	* A.replace(10);  // Replaces 5 with 10.
119 	* A.peek();  // Returns 10
120 	*
121 	* A.beginning();  // Current points to the beginning of the list at 1
122 	*
123 	* (++A).peek();  // Returns 5
124 	* A.peek();  // Returns 10
125 	*
126 	* A.del();  // Deletes 10.  Current points to the next element, which is 20
127 	* A.peek();  // Returns 20
128 	*
129 	* A.beginning();  // Current points to the beginning of the list at 1
130 	*
131 	* (++A).peek();  // Returns 5
132 	* A.peek();  // Returns 20
133 	*
134 	* A.clear();  // Deletes all nodes in A
135 	*
136 	* A.insert(5);  // A: 5 - current is 5
137 	* A.insert(6); // A: 6 5 - current is 6
138 	* A.insert(7); // A: 7 6 5 - current is 7
139 	*
140 	* A.clear();
141 	* B.clear();
142 	*
143 	* B.add(10);
144 	* B.add(20);
145 	* B.add(30);
146 	* B.add(5);
147 	* B.add(2);
148 	* B.add(25);
149 	* // Sorts the numbers in the list and sets the current pointer to the
150 	* // first element
151 	* B.sort();
152 	*
153 	* // Postfix ++ just calls the prefix version and has no functional
154 	* // difference.
155 	* B.peek();  // Returns 2
156 	* B++;
157 	* B.peek();  // Returns 5
158 	* B++;
159 	* B.peek();  // Returns 10
160 	* B++;
161 	* B.peek();  // Returns 20
162 	* B++;
163 	* B.peek();  // Returns 25
164 	* B++;
165 	* B.peek();  // Returns 30
166 	* @endcode
167 	*/
168 	template <class CircularLinkedListType>
169 
170 	class CircularLinkedList
171 	{
172 
173 	public:
174 
175 		struct node
176 		{
177 			CircularLinkedListType item;
178 
179 			node* previous;
180 			node* next;
181 		};
182 
183 		CircularLinkedList();
184 		~CircularLinkedList();
185 		CircularLinkedList( const CircularLinkedList& original_copy );
186 		// CircularLinkedList(LinkedList<CircularLinkedListType> original_copy) {CircularLinkedList(original_copy);}  // Converts linked list to circular type
187 		bool operator= ( const CircularLinkedList& original_copy );
188 		CircularLinkedList& operator++();  // CircularLinkedList A; ++A;
189 		CircularLinkedList& operator++( int );  // Circular_Linked List A; A++;
190 		CircularLinkedList& operator--();  // CircularLinkedList A; --A;
191 		CircularLinkedList& operator--( int );  // Circular_Linked List A; A--;
192 		bool is_in( const CircularLinkedListType& input );
193 		bool find( const CircularLinkedListType& input );
194 		void insert( const CircularLinkedListType& input );
195 
196 		CircularLinkedListType& add ( const CircularLinkedListType& input )
197 
198 			; // Adds after the current position
199 		void replace( const CircularLinkedListType& input );
200 
201 		void del( void );
202 
203 		unsigned int size( void );
204 
205 		CircularLinkedListType& peek( void );
206 
207 		const CircularLinkedListType pop( void );
208 
209 		void clear( void );
210 
211 		void sort( void );
212 
213 		void beginning( void );
214 
215 		void end( void );
216 
217 		void concatenate( const CircularLinkedList& L );
218 
219 	protected:
220 		unsigned int list_size;
221 
222 		node *root;
223 
224 		node *position;
225 
226 		node* find_pointer( const CircularLinkedListType& input );
227 
228 	private:
229 		CircularLinkedList merge( CircularLinkedList L1, CircularLinkedList L2 );
230 
231 		CircularLinkedList mergesort( const CircularLinkedList& L );
232 	};
233 
234 	template <class LinkedListType>
235 
236 	class LinkedList : public CircularLinkedList<LinkedListType>
237 	{
238 
239 	public:
LinkedList()240 		LinkedList()
241 		{}
242 
243 		LinkedList( const LinkedList& original_copy );
244 		~LinkedList();
245 		bool operator= ( const LinkedList<LinkedListType>& original_copy );
246 		LinkedList& operator++();  // LinkedList A; ++A;
247 		LinkedList& operator++( int );  // Linked List A; A++;
248 		LinkedList& operator--();  // LinkedList A; --A;
249 		LinkedList& operator--( int );  // Linked List A; A--;
250 
251 	private:
252 		LinkedList merge( LinkedList L1, LinkedList L2 );
253 		LinkedList mergesort( const LinkedList& L );
254 
255 	};
256 
257 
258 	template <class CircularLinkedListType>
beginning(void)259 		inline void CircularLinkedList<CircularLinkedListType>::beginning( void )
260 	{
261 		if ( this->root )
262 			this->position = this->root;
263 	}
264 
265 	template <class CircularLinkedListType>
end(void)266 		inline void CircularLinkedList<CircularLinkedListType>::end( void )
267 	{
268 		if ( this->root )
269 			this->position = this->root->previous;
270 	}
271 
272 	template <class LinkedListType>
273 		bool LinkedList<LinkedListType>::operator= ( const LinkedList<LinkedListType>& original_copy )
274 	{
275 		typename LinkedList::node * original_copy_pointer, *save_position;
276 
277 		if ( ( &original_copy ) != this )
278 		{
279 
280 			this->clear();
281 
282 
283 			if ( original_copy.list_size == 0 )
284 			{
285 				this->root = 0;
286 				this->position = 0;
287 				this->list_size = 0;
288 			}
289 
290 			else
291 				if ( original_copy.list_size == 1 )
292 				{
293 					this->root = new typename LinkedList::node;
294 					// root->item = new LinkedListType;
295 					this->root->next = this->root;
296 					this->root->previous = this->root;
297 					this->list_size = 1;
298 					this->position = this->root;
299 					// *(root->item)=*((original_copy.root)->item);
300 					this->root->item = original_copy.root->item;
301 				}
302 
303 				else
304 				{
305 					// Setup the first part of the root node
306 					original_copy_pointer = original_copy.root;
307 					this->root = new typename LinkedList::node;
308 					// root->item = new LinkedListType;
309 					this->position = this->root;
310 					// *(root->item)=*((original_copy.root)->item);
311 					this->root->item = original_copy.root->item;
312 
313 					if ( original_copy_pointer == original_copy.position )
314 						save_position = this->position;
315 
316 					do
317 					{
318 
319 
320 						// Save the current element
321 						this->last = this->position;
322 
323 						// Point to the next node in the source list
324 						original_copy_pointer = original_copy_pointer->next;
325 
326 						// Create a new node and point position to it
327 						this->position = new typename LinkedList::node;
328 						// position->item = new LinkedListType;
329 
330 						// Copy the item to the new node
331 						// *(position->item)=*(original_copy_pointer->item);
332 						this->position->item = original_copy_pointer->item;
333 
334 						if ( original_copy_pointer == original_copy.position )
335 							save_position = this->position;
336 
337 
338 						// Set the previous pointer for the new node
339 						( this->position->previous ) = this->last;
340 
341 						// Set the next pointer for the old node to the new node
342 						( this->last->next ) = this->position;
343 
344 					}
345 
346 					while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
347 
348 					// Complete the circle.  Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node
349 					this->position->next = this->root;
350 
351 					this->root->previous = this->position;
352 
353 					this->list_size = original_copy.list_size;
354 
355 					this->position = save_position;
356 				}
357 		}
358 
359 		return true;
360 	}
361 
362 
363 	template <class CircularLinkedListType>
CircularLinkedList()364 		CircularLinkedList<CircularLinkedListType>::CircularLinkedList()
365 	{
366 		this->root = 0;
367 		this->position = 0;
368 		this->list_size = 0;
369 	}
370 
371 	template <class CircularLinkedListType>
~CircularLinkedList()372 		CircularLinkedList<CircularLinkedListType>::~CircularLinkedList()
373 	{
374 		this->clear();
375 	}
376 
377 	template <class LinkedListType>
~LinkedList()378 		LinkedList<LinkedListType>::~LinkedList()
379 	{
380 		this->clear();
381 	}
382 
383 	template <class LinkedListType>
LinkedList(const LinkedList & original_copy)384 		LinkedList<LinkedListType>::LinkedList( const LinkedList& original_copy )
385 	{
386 		typename LinkedList::node * original_copy_pointer, *last, *save_position;
387 
388 		if ( original_copy.list_size == 0 )
389 		{
390 			this->root = 0;
391 			this->position = 0;
392 			this->list_size = 0;
393 			return ;
394 		}
395 
396 		else
397 			if ( original_copy.list_size == 1 )
398 			{
399 				this->root = new typename LinkedList::node;
400 				// root->item = new CircularLinkedListType;
401 				this->root->next = this->root;
402 				this->root->previous = this->root;
403 				this->list_size = 1;
404 				this->position = this->root;
405 				// *(root->item) = *((original_copy.root)->item);
406 				this->root->item = original_copy.root->item;
407 			}
408 
409 			else
410 			{
411 				// Setup the first part of the root node
412 				original_copy_pointer = original_copy.root;
413 				this->root = new typename LinkedList::node;
414 				// root->item = new CircularLinkedListType;
415 				this->position = this->root;
416 				// *(root->item)=*((original_copy.root)->item);
417 				this->root->item = original_copy.root->item;
418 
419 				if ( original_copy_pointer == original_copy.position )
420 					save_position = this->position;
421 
422 				do
423 				{
424 					// Save the current element
425 					this->last = this->position;
426 
427 					// Point to the next node in the source list
428 					original_copy_pointer = original_copy_pointer->next;
429 
430 					// Create a new node and point position to it
431 					this->position = new typename LinkedList::node;
432 					// position->item = new CircularLinkedListType;
433 
434 					// Copy the item to the new node
435 					// *(position->item)=*(original_copy_pointer->item);
436 					this->position->item = original_copy_pointer->item;
437 
438 					if ( original_copy_pointer == original_copy.position )
439 						save_position = this->position;
440 
441 					// Set the previous pointer for the new node
442 					( this->position->previous ) = last;
443 
444 					// Set the next pointer for the old node to the new node
445 					( this->last->next ) = this->position;
446 
447 				}
448 
449 				while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
450 
451 				// Complete the circle.  Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node
452 				this->position->next = this->root;
453 
454 				this->root->previous = this->position;
455 
456 				this->list_size = original_copy.list_size;
457 
458 				this->position = save_position;
459 			}
460 	}
461 
462 	template <class CircularLinkedListType>
CircularLinkedList(const CircularLinkedList & original_copy)463 		CircularLinkedList<CircularLinkedListType>::CircularLinkedList( const CircularLinkedList& original_copy )
464 	{
465 		node * original_copy_pointer;
466 		node *save_position;
467 
468 		if ( original_copy.list_size == 0 )
469 		{
470 			this->root = 0;
471 			this->position = 0;
472 			this->list_size = 0;
473 			return ;
474 		}
475 
476 		else
477 			if ( original_copy.list_size == 1 )
478 			{
479 				this->root = new typename CircularLinkedList::node;
480 				// root->item = new CircularLinkedListType;
481 				this->root->next = this->root;
482 				this->root->previous = this->root;
483 				this->list_size = 1;
484 				this->position = this->root;
485 				// *(root->item) = *((original_copy.root)->item);
486 				this->root->item = original_copy.root->item;
487 			}
488 
489 			else
490 			{
491 				// Setup the first part of the root node
492 				original_copy_pointer = original_copy.root;
493 				this->root = new typename CircularLinkedList::node;
494 				// root->item = new CircularLinkedListType;
495 				this->position = this->root;
496 				// *(root->item)=*((original_copy.root)->item);
497 				this->root->item = original_copy.root->item;
498 
499 				if ( original_copy_pointer == original_copy.position )
500 					save_position = this->position;
501 
502 				do
503 				{
504 
505 
506 					// Save the current element
507 					this->last = this->position;
508 
509 					// Point to the next node in the source list
510 					original_copy_pointer = original_copy_pointer->next;
511 
512 					// Create a new node and point position to it
513 					this->position = new typename CircularLinkedList::node;
514 					// position->item = new CircularLinkedListType;
515 
516 					// Copy the item to the new node
517 					// *(position->item)=*(original_copy_pointer->item);
518 					this->position->item = original_copy_pointer->item;
519 
520 					if ( original_copy_pointer == original_copy.position )
521 						save_position = position;
522 
523 					// Set the previous pointer for the new node
524 					( this->position->previous ) = this->last;
525 
526 					// Set the next pointer for the old node to the new node
527 					( this->last->next ) = this->position;
528 
529 				}
530 
531 				while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
532 
533 				// Complete the circle.  Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node
534 				this->position->next = this->root;
535 
536 				this->root->previous = position;
537 
538 				this->list_size = original_copy.list_size;
539 
540 				this->position = save_position;
541 			}
542 	}
543 
544 	template <class CircularLinkedListType>
545 		bool CircularLinkedList<CircularLinkedListType>::operator= ( const CircularLinkedList& original_copy )
546 	{
547 		node * original_copy_pointer;
548 		node *save_position;
549 
550 		if ( ( &original_copy ) != this )
551 		{
552 
553 			this->clear();
554 
555 
556 			if ( original_copy.list_size == 0 )
557 			{
558 				this->root = 0;
559 				this->position = 0;
560 				this->list_size = 0;
561 			}
562 
563 			else
564 				if ( original_copy.list_size == 1 )
565 				{
566 					this->root = new typename CircularLinkedList::node;
567 					// root->item = new CircularLinkedListType;
568 					this->root->next = this->root;
569 					this->root->previous = this->root;
570 					this->list_size = 1;
571 					this->position = this->root;
572 					// *(root->item)=*((original_copy.root)->item);
573 					this->root->item = original_copy.root->item;
574 				}
575 
576 				else
577 				{
578 					// Setup the first part of the root node
579 					original_copy_pointer = original_copy.root;
580 					this->root = new typename CircularLinkedList::node;
581 					// root->item = new CircularLinkedListType;
582 					this->position = this->root;
583 					// *(root->item)=*((original_copy.root)->item);
584 					this->root->item = original_copy.root->item;
585 
586 					if ( original_copy_pointer == original_copy.position )
587 						save_position = this->position;
588 
589 					do
590 					{
591 						// Save the current element
592 						this->last = this->position;
593 
594 						// Point to the next node in the source list
595 						original_copy_pointer = original_copy_pointer->next;
596 
597 						// Create a new node and point position to it
598 						this->position = new typename CircularLinkedList::node;
599 						// position->item = new CircularLinkedListType;
600 
601 						// Copy the item to the new node
602 						// *(position->item)=*(original_copy_pointer->item);
603 						this->position->item = original_copy_pointer->item;
604 
605 						if ( original_copy_pointer == original_copy.position )
606 							save_position = this->position;
607 
608 						// Set the previous pointer for the new node
609 						( this->position->previous ) = this->last;
610 
611 						// Set the next pointer for the old node to the new node
612 						( this->last->next ) = this->position;
613 
614 					}
615 
616 					while ( ( original_copy_pointer->next ) != ( original_copy.root ) );
617 
618 					// Complete the circle.  Set the next pointer of the newest node to the root and the previous pointer of the root to the newest node
619 					this->position->next = this->root;
620 
621 					this->root->previous = this->position;
622 
623 					this->list_size = original_copy.list_size;
624 
625 					this->position = save_position;
626 				}
627 		}
628 
629 		return true;
630 	}
631 
632 	template <class CircularLinkedListType>
insert(const CircularLinkedListType & input)633 		void CircularLinkedList<CircularLinkedListType>::insert( const CircularLinkedListType& input )
634 	{
635 		node * new_node;
636 
637 		if ( list_size == 0 )
638 		{
639 			this->root = new typename CircularLinkedList::node;
640 			// root->item = new CircularLinkedListType;
641 			//*(root->item)=input;
642 			this->root->item = input;
643 			this->root->next = this->root;
644 			this->root->previous = this->root;
645 			this->list_size = 1;
646 			this->position = this->root;
647 		}
648 
649 		else
650 			if ( list_size == 1 )
651 			{
652 				this->position = new typename CircularLinkedList::node;
653 				// position->item = new CircularLinkedListType;
654 				this->root->next = this->position;
655 				this->root->previous = this->position;
656 				this->position->previous = this->root;
657 				this->position->next = this->root;
658 				// *(position->item)=input;
659 				this->position->item = input;
660 				this->root = this->position; // Since we're inserting into a 1 element list the old root is now the second item
661 				this->list_size = 2;
662 			}
663 
664 			else
665 			{
666 				/*
667 
668 				B
669 				|
670 				A --- C
671 
672 				position->previous=A
673 				new_node=B
674 				position=C
675 
676 				Note that the order of the following statements is important  */
677 
678 				new_node = new typename CircularLinkedList::node;
679 				// new_node->item = new CircularLinkedListType;
680 
681 				// *(new_node->item)=input;
682 				new_node->item = input;
683 
684 				// Point next of A to B
685 				( this->position->previous ) ->next = new_node;
686 
687 				// Point last of B to A
688 				new_node->previous = this->position->previous;
689 
690 				// Point last of C to B
691 				this->position->previous = new_node;
692 
693 				// Point next of B to C
694 				new_node->next = this->position;
695 
696 				// Since the root pointer is bound to a node rather than an index this moves it back if you insert an element at the root
697 
698 				if ( this->position == this->root )
699 				{
700 					this->root = new_node;
701 					this->position = this->root;
702 				}
703 
704 				// Increase the recorded size of the list by one
705 				this->list_size++;
706 			}
707 	}
708 
709 	template <class CircularLinkedListType>
add(const CircularLinkedListType & input)710 		CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::add ( const CircularLinkedListType& input )
711 	{
712 		node * new_node;
713 
714 		if ( this->list_size == 0 )
715 		{
716 			this->root = new typename CircularLinkedList::node;
717 			// root->item = new CircularLinkedListType;
718 			// *(root->item)=input;
719 			this->root->item = input;
720 			this->root->next = this->root;
721 			this->root->previous = this->root;
722 			this->list_size = 1;
723 			this->position = this->root;
724 			// return *(position->item);
725 			return this->position->item;
726 		}
727 
728 		else
729 			if ( list_size == 1 )
730 			{
731 				this->position = new typename CircularLinkedList::node;
732 				// position->item = new CircularLinkedListType;
733 				this->root->next = this->position;
734 				this->root->previous = this->position;
735 				this->position->previous = this->root;
736 				this->position->next = this->root;
737 				// *(position->item)=input;
738 				this->position->item = input;
739 				this->list_size = 2;
740 				this->position = this->root; // Don't move the position from the root
741 				// return *(position->item);
742 				return this->position->item;
743 			}
744 
745 			else
746 			{
747 				/*
748 
749 				   B
750 			       |
751 				A --- C
752 
753 				new_node=B
754 				position=A
755 				position->next=C
756 
757 				Note that the order of the following statements is important  */
758 
759 				new_node = new typename CircularLinkedList::node;
760 				// new_node->item = new CircularLinkedListType;
761 
762 				// *(new_node->item)=input;
763 				new_node->item = input;
764 
765 				// Point last of B to A
766 				new_node->previous = this->position;
767 
768 				// Point next of B to C
769 				new_node->next = ( this->position->next );
770 
771 				// Point last of C to B
772 				( this->position->next ) ->previous = new_node;
773 
774 				// Point next of A to B
775 				( this->position->next ) = new_node;
776 
777 				// Increase the recorded size of the list by one
778 				this->list_size++;
779 
780 				// return *(new_node->item);
781 				return new_node->item;
782 			}
783 	}
784 
785 	template <class CircularLinkedListType>
replace(const CircularLinkedListType & input)786 		inline void CircularLinkedList<CircularLinkedListType>::replace( const CircularLinkedListType& input )
787 	{
788 		if ( this->list_size > 0 )
789 			// *(position->item)=input;
790 			this->position->item = input;
791 	}
792 
793 	template <class CircularLinkedListType>
del()794 		void CircularLinkedList<CircularLinkedListType>::del()
795 	{
796 		node * new_position;
797 
798 		if ( this->list_size == 0 )
799 			return ;
800 
801 		else
802 			if ( this->list_size == 1 )
803 			{
804 				// delete root->item;
805 				delete this->root;
806 				this->root = this->position = 0;
807 				this->list_size = 0;
808 			}
809 
810 			else
811 			{
812 				( this->position->previous ) ->next = this->position->next;
813 				( this->position->next ) ->previous = this->position->previous;
814 				new_position = this->position->next;
815 
816 				if ( this->position == this->root )
817 					this->root = new_position;
818 
819 				// delete position->item;
820 				delete this->position;
821 
822 				this->position = new_position;
823 
824 				this->list_size--;
825 			}
826 	}
827 
828 	template <class CircularLinkedListType>
is_in(const CircularLinkedListType & input)829 		bool CircularLinkedList<CircularLinkedListType>::is_in( const CircularLinkedListType& input )
830 	{
831 		node * return_value, *old_position;
832 
833 		old_position = this->position;
834 
835 		return_value = find_pointer( input );
836 		this->position = old_position;
837 
838 		if ( return_value != 0 )
839 			return true;
840 		else
841 			return false; // Can't find the item don't do anything
842 	}
843 
844 	template <class CircularLinkedListType>
find(const CircularLinkedListType & input)845 		bool CircularLinkedList<CircularLinkedListType>::find( const CircularLinkedListType& input )
846 	{
847 		node * return_value;
848 
849 		return_value = find_pointer( input );
850 
851 		if ( return_value != 0 )
852 		{
853 			this->position = return_value;
854 			return true;
855 		}
856 
857 		else
858 			return false; // Can't find the item don't do anything
859 	}
860 
861 	template <class CircularLinkedListType>
find_pointer(const CircularLinkedListType & input)862 		typename CircularLinkedList<CircularLinkedListType>::node* CircularLinkedList<CircularLinkedListType>::find_pointer( const CircularLinkedListType& input )
863 	{
864 		node * current;
865 
866 		if ( this->list_size == 0 )
867 			return 0;
868 
869 		current = this->root;
870 
871 		// Search for the item starting from the root node and incrementing the pointer after every check
872 		// If you wind up pointing at the root again you looped around the list so didn't find the item, in which case return 0
873 		do
874 		{
875 			// if (*(current->item) == input) return current;
876 
877 			if ( current->item == input )
878 				return current;
879 
880 			current = current->next;
881 		}
882 
883 		while ( current != this->root );
884 
885 		return 0;
886 
887 	}
888 
889 	template <class CircularLinkedListType>
size(void)890 		inline unsigned int CircularLinkedList<CircularLinkedListType>::size( void )
891 	{
892 		return this->list_size;
893 	}
894 
895 	template <class CircularLinkedListType>
peek(void)896 		inline CircularLinkedListType& CircularLinkedList<CircularLinkedListType>::peek( void )
897 	{
898 		// return *(position->item);
899 		return this->position->item;
900 	}
901 
902 	template <class CircularLinkedListType>
pop(void)903 		const CircularLinkedListType CircularLinkedList<CircularLinkedListType>::pop( void )
904 	{
905 		CircularLinkedListType element;
906 		element = peek();
907 		del();
908 		return CircularLinkedListType( element ); // return temporary
909 	}
910 
911 	// Prefix
912 	template <class CircularLinkedListType>
913 		CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++()
914 	{
915 		if ( this->list_size != 0 )
916 			position = position->next;
917 
918 		return *this;
919 	}
920 
921 	/*
922 	// Postfix
923 	template <class CircularLinkedListType>
924 	CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++(int)
925 	{
926 	CircularLinkedList<CircularLinkedListType> before;
927 	before=*this;
928 	operator++();
929 	return before;
930 	}
931 	*/
932 
933 	template <class CircularLinkedListType>
934 		CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator++( int )
935 	{
936 		return this->operator++();
937 	}
938 
939 	// Prefix
940 	template <class CircularLinkedListType>
941 		CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--()
942 	{
943 		if ( this->list_size != 0 )
944 			this->position = this->position->previous;
945 
946 		return *this;
947 	}
948 
949 	/*
950 	// Postfix
951 	template <class CircularLinkedListType>
952 	CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--(int)
953 	{
954 	CircularLinkedList<CircularLinkedListType> before;
955 	before=*this;
956 	operator--();
957 	return before;
958 	}
959 	*/
960 
961 	template <class CircularLinkedListType>
962 		CircularLinkedList<CircularLinkedListType>& CircularLinkedList<CircularLinkedListType>::operator--( int )
963 	{
964 		return this->operator--();
965 	}
966 
967 	template <class CircularLinkedListType>
clear(void)968 		void CircularLinkedList<CircularLinkedListType>::clear( void )
969 	{
970 		if ( this->list_size == 0 )
971 			return ;
972 		else
973 			if ( this->list_size == 1 )  // {delete root->item; delete root;}
974 			{
975 				delete this->root;
976 			}
977 
978 			else
979 			{
980 				node* current;
981 
982 				current = this->root;
983 
984 				do
985 				{
986 					node* temp = current;
987 					current = current->next;
988 					// delete temp->item;
989 					delete temp;
990 				}
991 
992 				while ( current != this->root );
993 			}
994 
995 			this->list_size = 0;
996 			this->root = 0;
997 			this->position = 0;
998 	}
999 
1000 	template <class CircularLinkedListType>
concatenate(const CircularLinkedList<CircularLinkedListType> & L)1001 		inline void CircularLinkedList<CircularLinkedListType>::concatenate( const CircularLinkedList<CircularLinkedListType>& L )
1002 	{
1003 		unsigned int counter;
1004 		node* ptr;
1005 
1006 		if ( L.list_size == 0 )
1007 			return ;
1008 
1009 		if ( this->list_size == 0 )
1010 			* this = L;
1011 
1012 		ptr = L.root;
1013 
1014 		this->position = this->root->previous;
1015 
1016 		// Cycle through each element in L and add it to the current list
1017 		for ( counter = 0; counter < L.list_size; counter++ )
1018 		{
1019 			// Add item after the current item pointed to
1020 			// add(*(ptr->item));
1021 
1022 			add ( ptr->item )
1023 
1024 				;
1025 
1026 			// Update pointers.  Moving ptr keeps the current pointer at the end of the list since the add function does not move the pointer
1027 			ptr = ptr->next;
1028 
1029 			this->position = this->position->next;
1030 		}
1031 	}
1032 
1033 	template <class CircularLinkedListType>
sort(void)1034 		inline void CircularLinkedList<CircularLinkedListType>::sort( void )
1035 	{
1036 		if ( this->list_size <= 1 )
1037 			return ;
1038 
1039 		// Call equal operator to assign result of mergesort to current object
1040 		*this = mergesort( *this );
1041 
1042 		this->position = this->root;
1043 	}
1044 
1045 	template <class CircularLinkedListType>
mergesort(const CircularLinkedList & L)1046 		CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::mergesort( const CircularLinkedList& L )
1047 	{
1048 		unsigned int counter;
1049 		node* location;
1050 		CircularLinkedList<CircularLinkedListType> L1;
1051 		CircularLinkedList<CircularLinkedListType> L2;
1052 
1053 		location = L.root;
1054 
1055 		// Split the list into two equal size sublists, L1 and L2
1056 
1057 		for ( counter = 0; counter < L.list_size / 2; counter++ )
1058 		{
1059 			// L1.add (*(location->item));
1060 			L1.add ( location->item );
1061 			location = location->next;
1062 		}
1063 
1064 		for ( ;counter < L.list_size; counter++ )
1065 		{
1066 			// L2.add(*(location->item));
1067 			L2.add ( location->item );
1068 			location = location->next;
1069 		}
1070 
1071 		// Recursively sort the sublists
1072 		if ( L1.list_size > 1 )
1073 			L1 = mergesort( L1 );
1074 
1075 		if ( L2.list_size > 1 )
1076 			L2 = mergesort( L2 );
1077 
1078 		// Merge the two sublists
1079 		return merge( L1, L2 );
1080 	}
1081 
1082 	template <class CircularLinkedListType>
merge(CircularLinkedList L1,CircularLinkedList L2)1083 		CircularLinkedList<CircularLinkedListType> CircularLinkedList<CircularLinkedListType>::merge( CircularLinkedList L1, CircularLinkedList L2 )
1084 	{
1085 		CircularLinkedList<CircularLinkedListType> X;
1086 		CircularLinkedListType element;
1087 		L1.position = L1.root;
1088 		L2.position = L2.root;
1089 
1090 		// While neither list is empty
1091 
1092 		while ( ( L1.list_size != 0 ) && ( L2.list_size != 0 ) )
1093 		{
1094 			// Compare the first items of L1 and L2
1095 			// Remove the smaller of the two items from the list
1096 
1097 			if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) )
1098 				// if ((*((L1.root)->item)) < (*((L2.root)->item)))
1099 			{
1100 				// element = *((L1.root)->item);
1101 				element = ( L1.root ) ->item;
1102 				L1.del();
1103 			}
1104 			else
1105 			{
1106 				// element = *((L2.root)->item);
1107 				element = ( L2.root ) ->item;
1108 				L2.del();
1109 			}
1110 
1111 			// Add this item to the end of X
1112 			X.add( element );
1113 
1114 			X++;
1115 		}
1116 
1117 		// Add the remaining list to X
1118 		if ( L1.list_size != 0 )
1119 			X.concatenate( L1 );
1120 		else
1121 			X.concatenate( L2 );
1122 
1123 		return X;
1124 	}
1125 
1126 	template <class LinkedListType>
mergesort(const LinkedList & L)1127 		LinkedList<LinkedListType> LinkedList<LinkedListType>::mergesort( const LinkedList& L )
1128 	{
1129 		unsigned int counter;
1130 		typename LinkedList::node* location;
1131 		LinkedList<LinkedListType> L1;
1132 		LinkedList<LinkedListType> L2;
1133 
1134 		location = L.root;
1135 
1136 		// Split the list into two equal size sublists, L1 and L2
1137 
1138 		for ( counter = 0; counter < L.LinkedList_size / 2; counter++ )
1139 		{
1140 			// L1.add (*(location->item));
1141 			L1.add ( location->item );
1142 			location = location->next;
1143 		}
1144 
1145 		for ( ;counter < L.LinkedList_size; counter++ )
1146 		{
1147 			// L2.add(*(location->item));
1148 			L2.add ( location->item );
1149 			location = location->next;
1150 		}
1151 
1152 		// Recursively sort the sublists
1153 		if ( L1.list_size > 1 )
1154 			L1 = mergesort( L1 );
1155 
1156 		if ( L2.list_size > 1 )
1157 			L2 = mergesort( L2 );
1158 
1159 		// Merge the two sublists
1160 		return merge( L1, L2 );
1161 	}
1162 
1163 	template <class LinkedListType>
merge(LinkedList L1,LinkedList L2)1164 		LinkedList<LinkedListType> LinkedList<LinkedListType>::merge( LinkedList L1, LinkedList L2 )
1165 	{
1166 		LinkedList<LinkedListType> X;
1167 		LinkedListType element;
1168 		L1.position = L1.root;
1169 		L2.position = L2.root;
1170 
1171 		// While neither list is empty
1172 
1173 		while ( ( L1.LinkedList_size != 0 ) && ( L2.LinkedList_size != 0 ) )
1174 		{
1175 			// Compare the first items of L1 and L2
1176 			// Remove the smaller of the two items from the list
1177 
1178 			if ( ( ( L1.root ) ->item ) < ( ( L2.root ) ->item ) )
1179 				// if ((*((L1.root)->item)) < (*((L2.root)->item)))
1180 			{
1181 				element = ( L1.root ) ->item;
1182 				// element = *((L1.root)->item);
1183 				L1.del();
1184 			}
1185 			else
1186 			{
1187 				element = ( L2.root ) ->item;
1188 				// element = *((L2.root)->item);
1189 				L2.del();
1190 			}
1191 
1192 			// Add this item to the end of X
1193 			X.add( element );
1194 		}
1195 
1196 		// Add the remaining list to X
1197 		if ( L1.LinkedList_size != 0 )
1198 			X.concatenate( L1 );
1199 		else
1200 			X.concatenate( L2 );
1201 
1202 		return X;
1203 	}
1204 
1205 
1206 	// Prefix
1207 	template <class LinkedListType>
1208 		LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++()
1209 	{
1210 		if ( ( this->list_size != 0 ) && ( this->position->next != this->root ) )
1211 			this->position = this->position->next;
1212 
1213 		return *this;
1214 	}
1215 
1216 	/*
1217 	// Postfix
1218 	template <class LinkedListType>
1219 	LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++(int)
1220 	{
1221 	LinkedList<LinkedListType> before;
1222 	before=*this;
1223 	operator++();
1224 	return before;
1225 	}
1226 	*/
1227 	// Postfix
1228 	template <class LinkedListType>
1229 		LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator++( int )
1230 	{
1231 		return this->operator++();
1232 	}
1233 
1234 	// Prefix
1235 	template <class LinkedListType>
1236 		LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--()
1237 	{
1238 		if ( ( this->list_size != 0 ) && ( this->position != this->root ) )
1239 			this->position = this->position->previous;
1240 
1241 		return *this;
1242 	}
1243 
1244 	/*
1245 	// Postfix
1246 	template <class LinkedListType>
1247 	LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--(int)
1248 	{
1249 	LinkedList<LinkedListType> before;
1250 	before=*this;
1251 	operator--();
1252 	return before;
1253 	}
1254 	*/
1255 
1256 	// Postfix
1257 	template <class LinkedListType>
1258 		LinkedList<LinkedListType>& LinkedList<LinkedListType>::operator--( int )
1259 	{
1260 		return this->operator--();
1261 	}
1262 
1263 } // End namespace
1264 
1265 #endif
1266