aboutsummaryrefslogtreecommitdiff
path: root/src/framework/Utilities
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/framework/Utilities
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'src/framework/Utilities')
-rw-r--r--src/framework/Utilities/ByteConverter.h57
-rw-r--r--src/framework/Utilities/Callback.h382
-rw-r--r--src/framework/Utilities/CountedReference/Reference.h97
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceHolder.h39
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceImpl.h130
-rw-r--r--src/framework/Utilities/EventProcessor.cpp88
-rw-r--r--src/framework/Utilities/EventProcessor.h68
-rw-r--r--src/framework/Utilities/HashMap.h63
-rw-r--r--src/framework/Utilities/LinkedList.h216
-rw-r--r--src/framework/Utilities/LinkedReference/RefManager.h53
-rw-r--r--src/framework/Utilities/LinkedReference/Reference.h84
-rw-r--r--src/framework/Utilities/TypeList.h43
12 files changed, 1320 insertions, 0 deletions
diff --git a/src/framework/Utilities/ByteConverter.h b/src/framework/Utilities/ByteConverter.h
new file mode 100644
index 00000000000..fade287ed0a
--- /dev/null
+++ b/src/framework/Utilities/ByteConverter.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_BYTECONVERTER_H
+#define MANGOS_BYTECONVERTER_H
+
+/** ByteConverter reverse your byte order. This is use
+ for cross platform where they have different endians.
+ */
+
+#include<Platform/Define.h>
+#include<algorithm>
+
+namespace ByteConverter
+{
+ template<size_t T>
+ inline void convert(char *val)
+ {
+ std::swap(*val, *(val + T - 1));
+ convert<T - 2>(val + 1);
+ }
+
+ template<> inline void convert<0>(char *) {}
+ template<> inline void convert<1>(char *) {} // ignore central byte
+
+ template<typename T> inline void apply(T *val)
+ {
+ convert<sizeof(T)>((char *)(val));
+ }
+}
+
+#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
+template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); }
+#else
+template<typename T> inline void EndianConvert(T&) { }
+#endif
+
+template<typename T> inline void EndianConvert(T*) { }
+inline void EndianConvert(uint8&) { }
+inline void EndianConvert( int8&) { }
+
+#endif
diff --git a/src/framework/Utilities/Callback.h b/src/framework/Utilities/Callback.h
new file mode 100644
index 00000000000..d794821a892
--- /dev/null
+++ b/src/framework/Utilities/Callback.h
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_CALLBACK_H
+#define MANGOS_CALLBACK_H
+
+/// ------------ BASE CLASSES ------------
+
+namespace MaNGOS
+{
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class _Callback
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ ParamType4 m_param4;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
+ : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
+ class _Callback < Class, ParamType1, ParamType2, ParamType3 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb)
+ : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class _Callback < Class, ParamType1, ParamType2 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2 > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class _Callback < Class, ParamType1 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ void _Execute() { (m_object->*m_method)(m_param1); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1)
+ : m_object(object), m_method(method), m_param1(param1) {}
+ _Callback(_Callback < Class, ParamType1 > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1) {}
+ };
+
+ template < class Class >
+ class _Callback < Class >
+ {
+ protected:
+ typedef void (Class::*Method)();
+ Class *m_object;
+ Method m_method;
+ void _Execute() { (m_object->*m_method)(); }
+ public:
+ _Callback(Class *object, Method method)
+ : m_object(object), m_method(method) {}
+ _Callback(_Callback < Class > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method) {}
+ };
+
+ /// ---- Statics ----
+
+ template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class _SCallback
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ ParamType4 m_param4;
+ void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
+ _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
+ };
+
+ template < typename ParamType1, typename ParamType2, typename ParamType3 >
+ class _SCallback < ParamType1, ParamType2, ParamType3 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2, ParamType3);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ void _Execute() { (*m_method)(m_param1, m_param2, m_param3); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : m_method(method), m_param1(param1), m_param2(param2) {}
+ _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
+ };
+
+ template < typename ParamType1, typename ParamType2 >
+ class _SCallback < ParamType1, ParamType2 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ void _Execute() { (*m_method)(m_param1, m_param2); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2)
+ : m_method(method), m_param1(param1), m_param2(param2) {}
+ _SCallback(_SCallback < ParamType1, ParamType2 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
+ };
+
+ template < typename ParamType1 >
+ class _SCallback < ParamType1 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1);
+ Method m_method;
+ ParamType1 m_param1;
+ void _Execute() { (*m_method)(m_param1); }
+ public:
+ _SCallback(Method method, ParamType1 param1)
+ : m_method(method), m_param1(param1) {}
+ _SCallback(_SCallback < ParamType1 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1) {}
+ };
+
+ template < >
+ class _SCallback < >
+ {
+ protected:
+ typedef void (*Method)();
+ Method m_method;
+ void _Execute() { (*m_method)(); }
+ public:
+ _SCallback(Method method)
+ : m_method(method) {}
+ _SCallback(_SCallback <> const& cb)
+ : m_method(cb.m_method) {}
+ };
+}
+
+/// --------- GENERIC CALLBACKS ----------
+
+namespace MaNGOS
+{
+ class ICallback
+ {
+ public:
+ virtual void Execute() = 0;
+ virtual ~ICallback() {}
+ };
+
+ template < class CB >
+ class _ICallback : public CB, public ICallback
+ {
+ public:
+ _ICallback(CB const& cb) : CB(cb) {}
+ void Execute() { CB::_Execute(); }
+ };
+
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class Callback :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > C4;
+ public:
+ Callback(Class *object, typename C4::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : _ICallback< C4 >(C4(object, method, param1, param2, param3, param4)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
+ class Callback < Class, ParamType1, ParamType2, ParamType3 > :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2, ParamType3 > C3;
+ public:
+ Callback(Class *object, typename C3::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _ICallback< C3 >(C3(object, method, param1, param2, param3)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class Callback < Class, ParamType1, ParamType2 > :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2 > C2;
+ public:
+ Callback(Class *object, typename C2::Method method, ParamType1 param1, ParamType2 param2)
+ : _ICallback< C2 >(C2(object, method, param1, param2)) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class Callback < Class, ParamType1 > :
+ public _ICallback< _Callback < Class, ParamType1 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1 > C1;
+ public:
+ Callback(Class *object, typename C1::Method method, ParamType1 param1)
+ : _ICallback< C1 >(C1(object, method, param1)) {}
+ };
+
+ template < class Class >
+ class Callback < Class > : public _ICallback< _Callback < Class > >
+ {
+ private:
+ typedef _Callback < Class > C0;
+ public:
+ Callback(Class *object, typename C0::Method method)
+ : _ICallback< C0 >(C0(object, method)) {}
+ };
+}
+
+/// ---------- QUERY CALLBACKS -----------
+
+class QueryResult;
+
+namespace MaNGOS
+{
+ class IQueryCallback
+ {
+ public:
+ virtual void Execute() = 0;
+ virtual ~IQueryCallback() {}
+ virtual void SetResult(QueryResult* result) = 0;
+ virtual QueryResult* GetResult() = 0;
+ };
+
+ template < class CB >
+ class _IQueryCallback : public CB, public IQueryCallback
+ {
+ public:
+ _IQueryCallback(CB const& cb) : CB(cb) {}
+ void Execute() { CB::_Execute(); }
+ void SetResult(QueryResult* result) { CB::m_param1 = result; }
+ QueryResult* GetResult() { return CB::m_param1; }
+ };
+
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
+ class QueryCallback :
+ public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > QC3;
+ public:
+ QueryCallback(Class *object, typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class QueryCallback < Class, ParamType1, ParamType2 > :
+ public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult*, ParamType1, ParamType2 > QC2;
+ public:
+ QueryCallback(Class *object, typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2)
+ : _IQueryCallback< QC2 >(QC2(object, method, result, param1, param2)) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class QueryCallback < Class, ParamType1 > :
+ public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult*, ParamType1 > QC1;
+ public:
+ QueryCallback(Class *object, typename QC1::Method method, QueryResult* result, ParamType1 param1)
+ : _IQueryCallback< QC1 >(QC1(object, method, result, param1)) {}
+ };
+
+ template < class Class >
+ class QueryCallback < Class > : public _IQueryCallback< _Callback < Class, QueryResult* > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult* > QC0;
+ public:
+ QueryCallback(Class *object, typename QC0::Method method, QueryResult* result)
+ : _IQueryCallback< QC0 >(QC0(object, method, result)) {}
+ };
+
+ /// ---- Statics ----
+
+ template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
+ class SQueryCallback :
+ public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > QC3;
+ public:
+ SQueryCallback(typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {}
+ };
+
+ template < typename ParamType1, typename ParamType2 >
+ class SQueryCallback < ParamType1, ParamType2 > :
+ public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _SCallback < QueryResult*, ParamType1, ParamType2 > QC2;
+ public:
+ SQueryCallback(typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2)
+ : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {}
+ };
+
+ template < typename ParamType1 >
+ class SQueryCallback < ParamType1 > :
+ public _IQueryCallback< _SCallback < QueryResult*, ParamType1 > >
+ {
+ private:
+ typedef _SCallback < QueryResult*, ParamType1 > QC1;
+ public:
+ SQueryCallback(typename QC1::Method method, QueryResult* result, ParamType1 param1)
+ : _IQueryCallback< QC1 >(QC1(method, result, param1)) {}
+ };
+
+ template < >
+ class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult* > >
+ {
+ private:
+ typedef _SCallback < QueryResult* > QC0;
+ public:
+ SQueryCallback(QC0::Method method, QueryResult* result)
+ : _IQueryCallback< QC0 >(QC0(method, result)) {}
+ };
+}
+
+#endif
diff --git a/src/framework/Utilities/CountedReference/Reference.h b/src/framework/Utilities/CountedReference/Reference.h
new file mode 100644
index 00000000000..581c6399a1b
--- /dev/null
+++ b/src/framework/Utilities/CountedReference/Reference.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_REFERENCE_H
+#define MANGOS_REFERENCE_H
+
+/**
+ * Referencer<T>
+ * Referencer is an object that holds a reference holder that hold a reference
+ * counted object. When an object's reference count drop to zero, it removes
+ * the object. This is a non intrusive mechanism and any object at any point
+ * in time can be referenced. When and object is reference counted, do not
+ * pass the object directly to other methods but rather, pass its
+ * reference around. Objects can be reference counted in both single threaded
+ * model and multi-threaded model
+ */
+
+#include <stdexcept>
+#include "Platform/Define.h"
+#include "Policies/ThreadingModel.h"
+#include "ReferenceHolder.h"
+
+template
+<
+typename T,
+class THREADING_MODEL = MaNGOS::SingleThreaded<T>
+>
+class MANGOS_DLL_DECL Referencer
+{
+ typedef typename THREADING_MODEL::Lock Lock;
+ typedef ReferenceHolder<T, THREADING_MODEL> ReferenceeHolder;
+ public:
+
+ /// Constructs a referencer.
+ Referencer(T *ref = NULL);
+
+ /// Copy constructor
+ Referencer(const Referencer &obj) : i_holder(NULL) { *this = obj; }
+
+ /// Destructor
+ ~Referencer();
+
+ /// Referencee accessor
+ T* referencee(void) { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T* referencee(void) const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ //T& referencee(void){ return _referencee(); }
+ //const T& referencee(void) const { return const_cast<Referencer *>(this)->_referencee(); }
+ operator T&(void) { return _referencee(); }
+ operator const T&(void) const { return *const_cast<Referencer *>(this)->_referencee(); }
+
+ /// cast operators
+ T* operator*() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ T const * operator*() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// overload operators
+ T* operator->() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T * operator->() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// operator =
+ Referencer& operator=(const Referencer &obj);
+ Referencer& operator=(T *);
+
+ /// returns true if i_referencee is null
+ bool isNull(void) const { return i_holder == NULL; }
+
+ private:
+
+ T& _referencee(void)
+ {
+ if( i_holder == NULL )
+ throw std::runtime_error("Invalid access to null pointer");
+ return *i_holder->i_referencee;
+ }
+
+ void deReference(ReferenceeHolder *);
+ void addReference(ReferenceeHolder *);
+
+ // private data
+ ReferenceeHolder *i_holder;
+};
+#endif
diff --git a/src/framework/Utilities/CountedReference/ReferenceHolder.h b/src/framework/Utilities/CountedReference/ReferenceHolder.h
new file mode 100644
index 00000000000..5387b14107a
--- /dev/null
+++ b/src/framework/Utilities/CountedReference/ReferenceHolder.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_REFERENCEHOLDER_H
+#define MANGOS_REFERENCEHOLDER_H
+
+/** ReferenceHolder holds the actualy referenced obejct as well the refence
+ count. The ReferenecHolder implements as a policy base object and
+ will decided by the Reference class to be consnsitent.
+ */
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+struct ReferenceHolder : public THREADING_MODEL
+{
+ explicit ReferenceHolder(T *ref) : i_referencee(ref), i_referenceCount(0) {}
+ T *i_referencee;
+ unsigned int i_referenceCount;
+ typedef typename THREADING_MODEL::Lock Lock;
+};
+#endif
diff --git a/src/framework/Utilities/CountedReference/ReferenceImpl.h b/src/framework/Utilities/CountedReference/ReferenceImpl.h
new file mode 100644
index 00000000000..dffd05c52c4
--- /dev/null
+++ b/src/framework/Utilities/CountedReference/ReferenceImpl.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_REFERENCEIMPL_H
+#define MANGOS_REFERENCEIMPL_H
+
+#include "Reference.h"
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::Referencer(T *ref)
+: i_holder(NULL)
+{
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::~Referencer()
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(const Referencer<T, THREADING_MODEL> &obj)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ if( obj.i_holder != NULL )
+ addReference(obj.i_holder);
+ i_holder = obj.i_holder;
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(T *ref)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::deReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( holder != NULL && holder->i_referenceCount > 0);
+ bool delete_object = false;
+
+ {
+ // The guard is within the scope due to the guard
+ // must release earlier than expected.
+ Lock guard(*holder);
+ Guard(&guard);
+
+ --holder->i_referenceCount;
+ if( holder->i_referenceCount == 0 )
+ delete_object = true;
+ }
+
+ if( delete_object )
+ {
+ delete holder->i_referencee;
+ delete holder;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::addReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( i_holder != NULL );
+ Lock guard(*holder);
+ Guard(&guard);
+
+ ++holder->i_referenceCount;
+}
+#endif
diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp
new file mode 100644
index 00000000000..55581ff7f8c
--- /dev/null
+++ b/src/framework/Utilities/EventProcessor.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "EventProcessor.h"
+
+EventProcessor::EventProcessor()
+{
+ m_time = 0;
+ m_aborting = false;
+}
+
+EventProcessor::~EventProcessor()
+{
+ KillAllEvents();
+}
+
+void EventProcessor::Update(uint32 p_time)
+{
+ // update time
+ m_time += p_time;
+
+ // main event loop
+ EventList::iterator i;
+ while (((i = m_events.begin()) != m_events.end()) && i->first <= m_time)
+ {
+ // get and remove event from queue
+ BasicEvent* Event = i->second;
+ m_events.erase(i);
+
+ if (!Event->to_Abort)
+ {
+ if (Event->Execute(m_time, p_time))
+ {
+ // completely destroy event if it is not re-added
+ delete Event;
+ }
+ }
+ else
+ {
+ Event->Abort(m_time);
+ delete Event;
+ }
+ }
+}
+
+void EventProcessor::KillAllEvents()
+{
+ // prevent event insertions
+ m_aborting = true;
+
+ // first, abort all existing events
+ for (EventList::iterator i = m_events.begin(); i != m_events.end(); ++i)
+ {
+ i->second->to_Abort = true;
+ i->second->Abort(m_time);
+ delete i->second;
+ }
+
+ // clear event list
+ m_events.clear();
+}
+
+void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime)
+{
+ if (set_addtime) Event->m_addTime = m_time;
+ Event->m_execTime = e_time;
+ m_events.insert(std::pair<uint64, BasicEvent*>(e_time, Event));
+}
+
+uint64 EventProcessor::CalculateTime(uint64 t_offset)
+{
+ return(m_time + t_offset);
+}
diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h
new file mode 100644
index 00000000000..d0a94ce08ae
--- /dev/null
+++ b/src/framework/Utilities/EventProcessor.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __EVENTPROCESSOR_H
+#define __EVENTPROCESSOR_H
+
+#include "Platform/Define.h"
+
+#include<map>
+
+// Note. All times are in milliseconds here.
+
+class BasicEvent
+{
+ public:
+ BasicEvent() { to_Abort = false; }
+ virtual ~BasicEvent() // override destructor to perform some actions on event removal
+ {
+ };
+
+ // this method executes when the event is triggered
+ // return false if event does not want to be deleted
+ // e_time is execution time, p_time is update interval
+ virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; }
+
+ virtual void Abort(uint64 /*e_time*/) {} // this method executes when the event is aborted
+
+ bool to_Abort; // set by externals when the event is aborted, aborted events don't execute
+ // and get Abort call when deleted
+
+ // these can be used for time offset control
+ uint64 m_addTime; // time when the event was added to queue, filled by event handler
+ uint64 m_execTime; // planned time of next execution, filled by event handler
+};
+
+typedef std::multimap<uint64, BasicEvent*> EventList;
+
+class EventProcessor
+{
+ public:
+ EventProcessor();
+ ~EventProcessor();
+
+ void Update(uint32 p_time);
+ void KillAllEvents();
+ void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
+ uint64 CalculateTime(uint64 t_offset);
+ protected:
+ uint64 m_time;
+ EventList m_events;
+ bool m_aborting;
+};
+#endif
diff --git a/src/framework/Utilities/HashMap.h b/src/framework/Utilities/HashMap.h
new file mode 100644
index 00000000000..2f887bd1943
--- /dev/null
+++ b/src/framework/Utilities/HashMap.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_HASHMAP_H
+#define MANGOS_HASHMAP_H
+
+#include "Platform/CompilerDefs.h"
+#include "Platform/Define.h"
+
+#if COMPILER == COMPILER_INTEL
+#include <ext/hash_map>
+#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+
+#ifdef _STLPORT_VERSION
+#define HM_NAMESPACE std
+using std::hash_map;
+#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
+#define HM_NAMESPACE stdext
+using stdext::hash_map;
+#elif COMPILER == COMPILER_INTEL
+#define HM_NAMESPACE std
+using std::hash_map;
+#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
+#define HM_NAMESPACE __gnu_cxx
+using __gnu_cxx::hash_map;
+
+namespace __gnu_cxx
+{
+ template<> struct hash<unsigned long long>
+ {
+ size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }
+ };
+ template<typename T> struct hash<T *>
+ {
+ size_t operator()(T * const &__x) const { return (size_t)__x; }
+ };
+
+};
+
+#else
+#define HM_NAMESPACE std
+using std::hash_map;
+#endif
+#endif
diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h
new file mode 100644
index 00000000000..3686c12c34c
--- /dev/null
+++ b/src/framework/Utilities/LinkedList.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LINKEDLIST
+#define _LINKEDLIST
+
+#include "Common.h"
+
+//============================================
+class LinkedListHead;
+
+class LinkedListElement
+{
+ private:
+ friend class LinkedListHead;
+
+ LinkedListElement* iNext;
+ LinkedListElement* iPrev;
+ public:
+ LinkedListElement() { iNext = NULL; iPrev = NULL; }
+ ~LinkedListElement() { delink(); }
+
+ bool hasNext() const { return(iNext->iNext != NULL); }
+ bool hasPrev() const { return(iPrev->iPrev != NULL); }
+ bool isInList() const { return(iNext != NULL && iPrev != NULL); }
+
+ LinkedListElement * next() { return hasNext() ? iNext : NULL; }
+ LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
+ LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
+ LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
+
+ void delink()
+ {
+ if(isInList())
+ {
+ iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
+ }
+ }
+
+ void insertBefore(LinkedListElement* pElem)
+ {
+ pElem->iNext = this;
+ pElem->iPrev = iPrev;
+ iPrev->iNext = pElem;
+ iPrev = pElem;
+ }
+
+ void insertAfter(LinkedListElement* pElem)
+ {
+ pElem->iPrev = this;
+ pElem->iNext = iNext;
+ iNext->iPrev = pElem;
+ iNext = pElem;
+ }
+};
+
+//============================================
+
+class LinkedListHead
+{
+ private:
+ LinkedListElement iFirst;
+ LinkedListElement iLast;
+ uint32 iSize;
+ public:
+ LinkedListHead()
+ {
+ // create empty list
+
+ iFirst.iNext = &iLast;
+ iLast.iPrev = &iFirst;
+ iSize = 0;
+ }
+
+ bool isEmpty() const { return(!iFirst.iNext->isInList()); }
+
+ LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
+ LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
+
+ LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
+ LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
+
+ void insertFirst(LinkedListElement* pElem)
+ {
+ iFirst.insertAfter(pElem);
+ }
+
+ void insertLast(LinkedListElement* pElem)
+ {
+ iLast.insertBefore(pElem);
+ }
+
+ uint32 getSize() const
+ {
+ if(!iSize)
+ {
+ uint32 result = 0;
+ LinkedListElement const* e = getFirst();
+ while(e)
+ {
+ ++result;
+ e = e->next();
+ }
+ return result;
+ }
+ else
+ return iSize;
+ }
+
+ void incSize() { ++iSize; }
+ void decSize() { --iSize; }
+
+ template<class _Ty>
+ class Iterator
+ {
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef _Ty value_type;
+ typedef ptrdiff_t difference_type;
+ typedef ptrdiff_t distance_type;
+ typedef _Ty* pointer;
+ typedef _Ty& reference;
+
+ Iterator() : _Ptr(0)
+ { // construct with null node pointer
+ }
+
+ Iterator(pointer _Pnode) : _Ptr(_Pnode)
+ { // construct with node pointer _Pnode
+ }
+
+ reference operator*()
+ { // return designated value
+ return *_Ptr;
+ }
+
+ pointer operator->()
+ { // return pointer to class object
+ return _Ptr;
+ }
+
+ Iterator& operator++()
+ { // preincrement
+ _Ptr = _Ptr->next();
+ return (*this);
+ }
+
+ Iterator operator++(int)
+ { // postincrement
+ iterator _Tmp = *this;
+ ++*this;
+ return (_Tmp);
+ }
+
+ Iterator& operator--()
+ { // predecrement
+ _Ptr = _Ptr->prev();
+ return (*this);
+ }
+
+ Iterator operator--(int)
+ { // postdecrement
+ iterator _Tmp = *this;
+ --*this;
+ return (_Tmp);
+ }
+
+ bool operator==(Iterator const &_Right) const
+ { // test for iterator equality
+ return (_Ptr == _Right._Ptr);
+ }
+
+ bool operator!=(Iterator const &_Right) const
+ { // test for iterator inequality
+ return (!(*this == _Right));
+ }
+
+ bool operator==(pointer const &_Right) const
+ { // test for pointer equality
+ return (_Ptr != _Right);
+ }
+
+ bool operator!=(pointer const &_Right) const
+ { // test for pointer equality
+ return (!(*this == _Right));
+ }
+
+ pointer _Mynode()
+ { // return node pointer
+ return (_Ptr);
+ }
+
+ protected:
+ pointer _Ptr; // pointer to node
+ };
+
+ typedef Iterator<LinkedListElement> iterator;
+};
+
+//============================================
+#endif
diff --git a/src/framework/Utilities/LinkedReference/RefManager.h b/src/framework/Utilities/LinkedReference/RefManager.h
new file mode 100644
index 00000000000..4e71ec7f2ed
--- /dev/null
+++ b/src/framework/Utilities/LinkedReference/RefManager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _REFMANAGER_H
+#define _REFMANAGER_H
+//=====================================================
+
+#include "Utilities/LinkedList.h"
+#include "Utilities/LinkedReference/Reference.h"
+
+template <class TO, class FROM> class RefManager : public LinkedListHead
+{
+ public:
+ typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
+ RefManager() { }
+ virtual ~RefManager() { clearReferences(); }
+
+ Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
+ Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
+
+ iterator begin() { return iterator(getFirst()); }
+ iterator end() { return iterator(NULL); }
+ iterator rbegin() { return iterator(getLast()); }
+ iterator rend() { return iterator(NULL); }
+
+ void clearReferences()
+ {
+ LinkedListElement* ref;
+ while((ref = getFirst()) != NULL)
+ {
+ ((Reference<TO, FROM>*) ref)->invalidate();
+ ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
+ }
+ }
+};
+
+//=====================================================
+#endif
diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h
new file mode 100644
index 00000000000..682bfd82162
--- /dev/null
+++ b/src/framework/Utilities/LinkedReference/Reference.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _REFERENCE_H
+#define _REFERENCE_H
+
+#include "Utilities/LinkedList.h"
+
+//=====================================================
+
+template <class TO, class FROM> class Reference : public LinkedListElement
+{
+ private:
+ TO* iRefTo;
+ FROM* iRefFrom;
+ protected:
+ // Tell our refTo (target) object that we have a link
+ virtual void targetObjectBuildLink() = 0;
+
+ // Tell our refTo (taget) object, that the link is cut
+ virtual void targetObjectDestroyLink() = 0;
+
+ // Tell our refFrom (source) object, that the link is cut (Target destroyed)
+ virtual void sourceObjectDestroyLink() = 0;
+ public:
+ Reference() { iRefTo = NULL; iRefFrom = NULL; }
+ virtual ~Reference() {}
+
+ // Create new link
+ inline void link(TO* toObj, FROM* fromObj)
+ {
+ assert(fromObj); // fromObj MUST not be NULL
+ if(isValid())
+ unlink();
+ if(toObj != NULL)
+ {
+ iRefTo = toObj;
+ iRefFrom = fromObj;
+ targetObjectBuildLink();
+ }
+ }
+
+ // We don't need the reference anymore. Call comes from the refFrom object
+ // Tell our refTo object, that the link is cut
+ inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
+
+ // Link is invalid due to destruction of referenced target object. Call comes from the refTo object
+ // Tell our refFrom object, that the link is cut
+ inline void invalidate() // the iRefFrom MUST remain!!
+ {
+ sourceObjectDestroyLink(); delink(); iRefTo = NULL;
+ }
+
+ inline bool isValid() const // Only check the iRefTo
+ {
+ return iRefTo != NULL;
+ }
+
+ Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); }
+ Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); }
+
+ inline TO* operator ->() const { return iRefTo; }
+ inline TO* getTarget() const { return iRefTo; }
+
+ inline FROM* getSource() const { return iRefFrom; }
+};
+
+//=====================================================
+#endif
diff --git a/src/framework/Utilities/TypeList.h b/src/framework/Utilities/TypeList.h
new file mode 100644
index 00000000000..074f5eb2483
--- /dev/null
+++ b/src/framework/Utilities/TypeList.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_TYPELIST_H
+#define MANGOS_TYPELIST_H
+
+/*
+ @struct TypeList
+ TypeList is the most simple but yet the most powerfull class of all. It holds
+ at compile time the different type of objects in a linked list.
+ */
+
+class TypeNull;
+
+template<typename HEAD, typename TAIL>
+struct TypeList
+{
+ typedef HEAD Head;
+ typedef TAIL Tail;
+};
+
+// enough for now.. can be expand at any point in time as needed
+#define TYPELIST_1(T1) TypeList<T1,TypeNull>
+#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) >
+#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) >
+#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) >
+#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) >
+#endif