Merged changes from SH:List
Fixed bug where natives did not use the debugger (experimental) Removed array size detection :(
This commit is contained in:
		@@ -79,15 +79,6 @@
 | 
				
			|||||||
  #endif
 | 
					  #endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_ALLOCA_H
 | 
					 | 
				
			||||||
  #include <alloca.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
 | 
					 | 
				
			||||||
  #if !defined alloca
 | 
					 | 
				
			||||||
    #define alloca(n)   _alloca(n)
 | 
					 | 
				
			||||||
  #endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined arraysize
 | 
					#if !defined arraysize
 | 
				
			||||||
  #define arraysize(array)  (sizeof(array) / sizeof((array)[0]))
 | 
					  #define arraysize(array)  (sizeof(array) / sizeof((array)[0]))
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -450,6 +450,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
 | 
				
			|||||||
			amx_err = AMX_ERR_NOTFOUND;*/
 | 
								amx_err = AMX_ERR_NOTFOUND;*/
 | 
				
			||||||
		//if (!amx_err)
 | 
							//if (!amx_err)
 | 
				
			||||||
			size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
 | 
								size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
	} else if (error == AMX_ERR_BOUNDS) {
 | 
						} else if (error == AMX_ERR_BOUNDS) {
 | 
				
			||||||
		tagAMX_DBG *pDbg = m_pAmxDbg;
 | 
							tagAMX_DBG *pDbg = m_pAmxDbg;
 | 
				
			||||||
		int symbols = pDbg->hdr->symbols;
 | 
							int symbols = pDbg->hdr->symbols;
 | 
				
			||||||
@@ -649,6 +650,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
 | 
				
			|||||||
			_msgbuf[0] = '\0';
 | 
								_msgbuf[0] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size += _snprintf(buffer, maxLength, "%s", _msgbuf);
 | 
							size += _snprintf(buffer, maxLength, "%s", _msgbuf);
 | 
				
			||||||
 | 
					#endif	//0 - NOT USED!
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return size;
 | 
						return size;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,7 @@
 | 
				
			|||||||
#include "amxmodx.h"
 | 
					#include "amxmodx.h"
 | 
				
			||||||
#include "sh_stack.h"
 | 
					#include "sh_stack.h"
 | 
				
			||||||
#include "natives.h"
 | 
					#include "natives.h"
 | 
				
			||||||
 | 
					#include "Debugger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __linux__
 | 
					#ifdef __linux__
 | 
				
			||||||
#include <malloc.h>
 | 
					#include <malloc.h>
 | 
				
			||||||
@@ -87,18 +88,26 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
 | 
				
			|||||||
		for (int i=numParams; i>=1; i--)
 | 
							for (int i=numParams; i>=1; i--)
 | 
				
			||||||
			amx_Push(pNative->amx, params[i]);
 | 
								amx_Push(pNative->amx, params[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
 | 
						Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
 | 
				
			||||||
	{
 | 
						if (pDebugger)
 | 
				
			||||||
		g_NativeStack.pop();
 | 
							pDebugger->BeginExec();
 | 
				
			||||||
		LogError(pNative->amx, err, "");
 | 
						err=amx_Exec(pNative->amx, &ret, pNative->func);
 | 
				
			||||||
		return 0;
 | 
						if (err != AMX_ERR_NONE)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (g_errorNum)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							if (pDebugger && pDebugger->ErrorExists())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								//don't care
 | 
				
			||||||
 | 
							} else if (err != -1) {
 | 
				
			||||||
 | 
								//nothing logged the error
 | 
				
			||||||
 | 
								LogError(amx, err, NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							amx->error = AMX_ERR_NONE;
 | 
				
			||||||
 | 
						} else if (g_errorNum) {
 | 
				
			||||||
		g_NativeStack.pop();
 | 
							g_NativeStack.pop();
 | 
				
			||||||
		LogError(amx, g_errorNum, g_errorStr);
 | 
							LogError(amx, g_errorNum, g_errorStr);
 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (pDebugger)
 | 
				
			||||||
 | 
							pDebugger->EndExec();
 | 
				
			||||||
	g_NativeStack.pop();
 | 
						g_NativeStack.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,311 +11,280 @@
 | 
				
			|||||||
#ifndef _INCLUDE_SMM_LIST_H
 | 
					#ifndef _INCLUDE_SMM_LIST_H
 | 
				
			||||||
#define _INCLUDE_SMM_LIST_H
 | 
					#define _INCLUDE_SMM_LIST_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "sh_stack.h"
 | 
					#include <new>
 | 
				
			||||||
 | 
					#include <malloc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//namespace SourceHook
 | 
					//namespace SourceHook
 | 
				
			||||||
//{
 | 
					//{
 | 
				
			||||||
//This class is from CSDM for AMX Mod X
 | 
						//This class is from CSDM for AMX Mod X
 | 
				
			||||||
template <class T>
 | 
						/*
 | 
				
			||||||
class List
 | 
							A circular, doubly-linked list with one sentinel node
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
public:
 | 
							Empty:
 | 
				
			||||||
	class iterator;
 | 
								m_Head = sentinel
 | 
				
			||||||
	friend class iterator;
 | 
								m_Head->next = m_Head;
 | 
				
			||||||
	class ListNode
 | 
								m_Head->prev = m_Head;
 | 
				
			||||||
 | 
							One element:
 | 
				
			||||||
 | 
								m_Head = sentinel
 | 
				
			||||||
 | 
								m_Head->next = node1
 | 
				
			||||||
 | 
								m_Head->prev = node1
 | 
				
			||||||
 | 
								node1->next = m_Head
 | 
				
			||||||
 | 
								node1->prev = m_Head
 | 
				
			||||||
 | 
							Two elements:
 | 
				
			||||||
 | 
								m_Head = sentinel
 | 
				
			||||||
 | 
								m_Head->next = node1
 | 
				
			||||||
 | 
								m_Head->prev = node2
 | 
				
			||||||
 | 
								node1->next = node2
 | 
				
			||||||
 | 
								node1->prev = m_Head
 | 
				
			||||||
 | 
								node2->next = m_Head
 | 
				
			||||||
 | 
								node2->prev = node1
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						template <class T>
 | 
				
			||||||
 | 
						class List
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		ListNode(const T & o) : obj(o) { };
 | 
							class iterator;
 | 
				
			||||||
		ListNode() { };
 | 
							friend class iterator;
 | 
				
			||||||
		void Set(const T & o) { obj = o; }
 | 
							class ListNode
 | 
				
			||||||
		~ListNode()
 | 
							{
 | 
				
			||||||
		{ 
 | 
							public:
 | 
				
			||||||
 | 
								ListNode(const T & o) : obj(o) { };
 | 
				
			||||||
 | 
								ListNode() { };
 | 
				
			||||||
 | 
								T obj;
 | 
				
			||||||
 | 
								ListNode *next;
 | 
				
			||||||
 | 
								ListNode *prev;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		T obj;
 | 
						private:
 | 
				
			||||||
		ListNode *next;
 | 
							// Initializes the sentinel node.
 | 
				
			||||||
		ListNode *prev;
 | 
							// BAIL used malloc instead of new in order to bypass the need for a constructor.
 | 
				
			||||||
	};
 | 
							ListNode *_Initialize()
 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	ListNode *_Initialize()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ListNode *n = (ListNode *)malloc(sizeof(ListNode));
 | 
					 | 
				
			||||||
		n->next = NULL;
 | 
					 | 
				
			||||||
		n->prev = NULL;
 | 
					 | 
				
			||||||
		return n;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	List() : m_Head(_Initialize()), m_Size(0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	List(const List &src) : m_Head(_Initialize()), m_Size(0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		iterator iter;
 | 
					 | 
				
			||||||
		for (iter=src.begin(); iter!=src.end(); iter++)
 | 
					 | 
				
			||||||
			push_back( (*iter) );
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	~List()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		clear();
 | 
					 | 
				
			||||||
		if (m_Head)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			free(m_Head);
 | 
								ListNode *n = (ListNode *)malloc(sizeof(ListNode));
 | 
				
			||||||
			m_Head = NULL;
 | 
								n->next = n;
 | 
				
			||||||
 | 
								n->prev = n;
 | 
				
			||||||
 | 
								return n;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						public:
 | 
				
			||||||
	void unshift(const T &obj)
 | 
							List() : m_Head(_Initialize()), m_Size(0)
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (!m_Head->next)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			push_back(obj);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							List(const List &src) : m_Head(_Initialize()), m_Size(0)
 | 
				
			||||||
		ListNode *node;
 | 
					 | 
				
			||||||
		if (m_FreeStack.empty())
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			node = new ListNode(obj);
 | 
								iterator iter;
 | 
				
			||||||
		} else {
 | 
								for (iter=src.begin(); iter!=src.end(); iter++)
 | 
				
			||||||
			node = m_FreeStack.front();
 | 
									push_back( (*iter) );
 | 
				
			||||||
			m_FreeStack.pop();
 | 
					 | 
				
			||||||
			node->Set(obj);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							~List()
 | 
				
			||||||
		//is the list one item circular?
 | 
					 | 
				
			||||||
		/*bool realign = false;
 | 
					 | 
				
			||||||
		if (m_Head->next == m_Head->prev)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_Head->next->next = 
 | 
								clear();
 | 
				
			||||||
		}*/
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
		node->next = m_Head->next;
 | 
					 | 
				
			||||||
		node->prev = m_Head;
 | 
					 | 
				
			||||||
		m_Head->next->prev = node;
 | 
					 | 
				
			||||||
		m_Head->next = node;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_Size++;
 | 
								// Don't forget to free the sentinel
 | 
				
			||||||
	}
 | 
								if (m_Head)
 | 
				
			||||||
	void push_back(const T &obj)
 | 
								{
 | 
				
			||||||
	{
 | 
									free(m_Head);
 | 
				
			||||||
		ListNode *node;
 | 
									m_Head = NULL;
 | 
				
			||||||
		if (m_FreeStack.empty())
 | 
								}
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			node = new ListNode(obj);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			node = m_FreeStack.front();
 | 
					 | 
				
			||||||
			m_FreeStack.pop();
 | 
					 | 
				
			||||||
			node->Set(obj);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							void push_back(const T &obj)
 | 
				
			||||||
		if (!m_Head->prev)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			//link in the node as the first item 
 | 
								ListNode *node = new ListNode(obj);
 | 
				
			||||||
			node->next = m_Head;
 | 
					
 | 
				
			||||||
			node->prev = m_Head;
 | 
					 | 
				
			||||||
			m_Head->prev = node;
 | 
					 | 
				
			||||||
			m_Head->next = node;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			node->prev = m_Head->prev;
 | 
								node->prev = m_Head->prev;
 | 
				
			||||||
			node->next = m_Head;
 | 
								node->next = m_Head;
 | 
				
			||||||
			m_Head->prev->next = node;
 | 
								m_Head->prev->next = node;
 | 
				
			||||||
			m_Head->prev = node;
 | 
								m_Head->prev = node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								m_Size++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_Size++;
 | 
							size_t size()
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	size_t size()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_Size;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	void clear()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ListNode *node = m_Head->next;
 | 
					 | 
				
			||||||
		ListNode *temp;
 | 
					 | 
				
			||||||
		m_Head->next = NULL;
 | 
					 | 
				
			||||||
		m_Head->prev = NULL;
 | 
					 | 
				
			||||||
		while (node && node != m_Head)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			temp = node->next;
 | 
								return m_Size;
 | 
				
			||||||
			delete node;
 | 
					 | 
				
			||||||
			node = temp;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_Size = 0;
 | 
					
 | 
				
			||||||
		while (!m_FreeStack.empty())
 | 
							void clear()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			delete m_FreeStack.front();
 | 
								ListNode *node = m_Head->next;
 | 
				
			||||||
			m_FreeStack.pop();
 | 
								ListNode *temp;
 | 
				
			||||||
 | 
								m_Head->next = m_Head;
 | 
				
			||||||
 | 
								m_Head->prev = m_Head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Iterate through the nodes until we find g_Head (the sentinel) again
 | 
				
			||||||
 | 
								while (node != m_Head)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									temp = node->next;
 | 
				
			||||||
 | 
									delete node;
 | 
				
			||||||
 | 
									node = temp;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								m_Size = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
							bool empty()
 | 
				
			||||||
	bool empty()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return (m_Head->next == NULL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	T & back()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_Head->prev->obj;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
#if defined __GNUC__
 | 
					 | 
				
			||||||
	CStack<List::ListNode *> m_FreeStack;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	typename CStack<List::ListNode *> m_FreeStack;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	ListNode *m_Head;
 | 
					 | 
				
			||||||
	size_t m_Size;
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	class iterator
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	friend class List;
 | 
					 | 
				
			||||||
	public:
 | 
					 | 
				
			||||||
		iterator()
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_This = NULL;
 | 
								return (m_Size == 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		iterator(const List &src)
 | 
							T & back()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_This = src.m_Head;
 | 
								return m_Head->prev->obj;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		iterator(ListNode *n) : m_This(n)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		iterator(const iterator &where)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_This = where.m_This;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		//pre decrement
 | 
					 | 
				
			||||||
		iterator & operator--()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (m_This)
 | 
					 | 
				
			||||||
				m_This = m_This->prev;
 | 
					 | 
				
			||||||
			return *this;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		//post decrement
 | 
					 | 
				
			||||||
		iterator operator--(int)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			iterator old(*this);
 | 
					 | 
				
			||||||
			if (m_This)
 | 
					 | 
				
			||||||
				m_This = m_This->prev;
 | 
					 | 
				
			||||||
			return old;
 | 
					 | 
				
			||||||
		}	
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		//pre increment
 | 
					 | 
				
			||||||
		iterator & operator++()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (m_This)
 | 
					 | 
				
			||||||
				m_This = m_This->next;
 | 
					 | 
				
			||||||
			return *this;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		//post increment
 | 
					 | 
				
			||||||
		iterator operator++(int)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			iterator old(*this);
 | 
					 | 
				
			||||||
			if (m_This)
 | 
					 | 
				
			||||||
				m_This = m_This->next;
 | 
					 | 
				
			||||||
			return old;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		const T & operator * () const
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return m_This->obj;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		T & operator * ()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return m_This->obj;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		T * operator -> ()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return &(m_This->obj);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		const T * operator -> () const
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return &(m_This->obj);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		bool operator != (const iterator &where) const
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return (m_This != where.m_This);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		bool operator ==(const iterator &where) const
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return (m_This == where.m_This);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		ListNode *m_This;
 | 
							ListNode *m_Head;
 | 
				
			||||||
	};
 | 
							size_t m_Size;
 | 
				
			||||||
public:
 | 
						public:
 | 
				
			||||||
	iterator begin() const
 | 
							class iterator
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (m_Size)
 | 
					 | 
				
			||||||
			return iterator(m_Head->next);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			return iterator(m_Head);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	iterator end() const
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return iterator(m_Head);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	iterator erase(iterator &where)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ListNode *pNode = where.m_This;
 | 
					 | 
				
			||||||
		iterator iter(where);
 | 
					 | 
				
			||||||
		iter++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		//If we are both the head and tail...
 | 
					 | 
				
			||||||
		if (m_Head->next == pNode && m_Head->prev == pNode)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_Head->next = NULL;
 | 
							friend class List;
 | 
				
			||||||
			m_Head->prev = NULL;
 | 
							public:
 | 
				
			||||||
		} else if (m_Head->next == pNode) {
 | 
								iterator()
 | 
				
			||||||
			//we are only the first
 | 
								{
 | 
				
			||||||
			pNode->next->prev = m_Head;
 | 
									m_This = NULL;
 | 
				
			||||||
			m_Head->next = pNode->next;
 | 
								}
 | 
				
			||||||
		} else if (m_Head->prev == pNode) {
 | 
								iterator(const List &src)
 | 
				
			||||||
			//we are the tail
 | 
								{
 | 
				
			||||||
			pNode->prev->next = m_Head;
 | 
									m_This = src.m_Head;
 | 
				
			||||||
			m_Head->prev = pNode->prev;
 | 
								}
 | 
				
			||||||
		} else {
 | 
								iterator(ListNode *n) : m_This(n)
 | 
				
			||||||
			//middle unlink
 | 
								{
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								iterator(const iterator &where)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									m_This = where.m_This;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//pre decrement
 | 
				
			||||||
 | 
								iterator & operator--()
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (m_This)
 | 
				
			||||||
 | 
										m_This = m_This->prev;
 | 
				
			||||||
 | 
									return *this;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//post decrement
 | 
				
			||||||
 | 
								iterator operator--(int)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									iterator old(*this);
 | 
				
			||||||
 | 
									if (m_This)
 | 
				
			||||||
 | 
										m_This = m_This->prev;
 | 
				
			||||||
 | 
									return old;
 | 
				
			||||||
 | 
								}	
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								//pre increment
 | 
				
			||||||
 | 
								iterator & operator++()
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (m_This)
 | 
				
			||||||
 | 
										m_This = m_This->next;
 | 
				
			||||||
 | 
									return *this;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//post increment
 | 
				
			||||||
 | 
								iterator operator++(int)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									iterator old(*this);
 | 
				
			||||||
 | 
									if (m_This)
 | 
				
			||||||
 | 
										m_This = m_This->next;
 | 
				
			||||||
 | 
									return old;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								const T & operator * () const
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return m_This->obj;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								T & operator * ()
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return m_This->obj;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								T * operator -> ()
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return &(m_This->obj);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								const T * operator -> () const
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return &(m_This->obj);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								bool operator != (const iterator &where) const
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return (m_This != where.m_This);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								bool operator ==(const iterator &where) const
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return (m_This == where.m_This);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							private:
 | 
				
			||||||
 | 
								ListNode *m_This;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							iterator begin() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return iterator(m_Head->next);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							iterator end() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return iterator(m_Head);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							iterator erase(iterator &where)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ListNode *pNode = where.m_This;
 | 
				
			||||||
 | 
								iterator iter(where);
 | 
				
			||||||
 | 
								iter++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
 | 
				
			||||||
			pNode->prev->next = pNode->next;
 | 
								pNode->prev->next = pNode->next;
 | 
				
			||||||
			pNode->next->prev = pNode->prev;
 | 
								pNode->next->prev = pNode->prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								delete pNode;
 | 
				
			||||||
 | 
								m_Size--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return iter;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_FreeStack.push(pNode);
 | 
							iterator insert(iterator where, const T &obj)
 | 
				
			||||||
		m_Size--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return iter;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	void remove(const T & obj)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		iterator b;
 | 
					 | 
				
			||||||
		for (b=begin(); b!=end(); b++)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( (*b) == obj )
 | 
								// Insert obj right before where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ListNode *node = new ListNode(obj);
 | 
				
			||||||
 | 
								ListNode *pWhereNode = where.m_This;
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								pWhereNode->prev->next = node;
 | 
				
			||||||
 | 
								node->prev = pWhereNode->prev;
 | 
				
			||||||
 | 
								pWhereNode->prev = node;
 | 
				
			||||||
 | 
								node->next = pWhereNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								m_Size++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return iterator(node);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							void remove(const T & obj)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								iterator b;
 | 
				
			||||||
 | 
								for (b=begin(); b!=end(); b++)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				erase( b );
 | 
									if ( (*b) == obj )
 | 
				
			||||||
				break;
 | 
									{
 | 
				
			||||||
 | 
										erase( b );
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
							template <typename U>
 | 
				
			||||||
	template <typename U>
 | 
							iterator find(const U & equ)
 | 
				
			||||||
	iterator find(const U & equ)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		iterator iter;
 | 
					 | 
				
			||||||
		for (iter=begin(); iter!=end(); iter++)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( (*iter) == equ )
 | 
								iterator iter;
 | 
				
			||||||
				return iter;
 | 
								for (iter=begin(); iter!=end(); iter++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ( (*iter) == equ )
 | 
				
			||||||
 | 
										return iter;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return end();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return end();
 | 
							List & operator =(const List &src)
 | 
				
			||||||
	}
 | 
							{
 | 
				
			||||||
	List & operator =(List &src)
 | 
								clear();
 | 
				
			||||||
	{
 | 
								iterator iter;
 | 
				
			||||||
		clear();
 | 
								for (iter=src.begin(); iter!=src.end(); iter++)
 | 
				
			||||||
		iterator iter;
 | 
									push_back( (*iter) );
 | 
				
			||||||
		for (iter=src.begin(); iter!=src.end(); iter++)
 | 
								return *this;
 | 
				
			||||||
			push_back( (*iter) );
 | 
							}
 | 
				
			||||||
		return *this;
 | 
						};
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
//};	//NAMESPACE
 | 
					//};	//NAMESPACE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //_INCLUDE_CSDM_LIST_H
 | 
					#endif //_INCLUDE_CSDM_LIST_H
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user