typesystem.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined(INCLUDED_TYPESYSTEM_H)
00023 #define INCLUDED_TYPESYSTEM_H
00024 
00025 #include <list>
00026 #include "generic/callback.h"
00027 #include "generic/static.h"
00028 
00029 class InitialiserList
00030 {
00031         typedef std::list<Callback> Initialisers;
00032         Initialisers m_initialisers;
00033         mutable bool m_initialised;
00034     public:
00035         InitialiserList () :
00036             m_initialised(false)
00037         {
00038         }
00039         void addInitialiser (const Callback& callback)
00040         {
00041             m_initialisers.push_back(callback);
00042         }
00043         void initialise () const
00044         {
00045             if (!m_initialised) {
00046                 m_initialised = true;
00047 
00048                 for (Initialisers::const_iterator i = m_initialisers.begin(); i != m_initialisers.end(); ++i) {
00049                     (*i)();
00050                 }
00051             }
00052         }
00053 };
00054 
00055 //--Type System-------------------
00056 
00057 class TypeSystemInitialiser: public InitialiserList
00058 {
00059 };
00060 
00061 typedef SmartStatic<TypeSystemInitialiser> StaticTypeSystemInitialiser;
00062 
00063 class TypeSystemRef: public StaticTypeSystemInitialiser
00064 {
00065     public:
00066         TypeSystemRef ()
00067         {
00068             StaticTypeSystemInitialiser::instance().initialise();
00069         }
00070 };
00071 
00072 typedef std::size_t TypeId;
00073 typedef void*(*TypeCast) (void*);
00074 
00075 template<std::size_t SIZE>
00076 class TypeCastTable
00077 {
00078         TypeCast m_casts[SIZE];
00079     public:
00080         TypeCastTable ()
00081         {
00082             std::uninitialized_fill(m_casts, m_casts + SIZE, TypeCast(0));
00083         }
00084         void install (TypeId typeId, TypeCast typeCast)
00085         {
00086             m_casts[typeId] = typeCast;
00087         }
00088         void* cast (TypeId typeId, void* p)
00089         {
00090             TypeCast typeCast = m_casts[typeId];
00091             if (typeCast != 0) {
00092                 return typeCast(p);
00093             }
00094             return 0;
00095         }
00096 };
00097 
00098 template<typename Type, typename Cast>
00099 class CastInstaller
00100 {
00101     public:
00102         static void install (TypeCastTable<Type::SIZE>& table)
00103         {
00104             table.install(Type::getTypeId(), Cast::cast);
00105         }
00106 };
00107 
00108 template<typename Type>
00109 class IdentityCast
00110 {
00111     public:
00112         static void* cast (void* p)
00113         {
00114             return p;
00115         }
00116 };
00117 
00118 template<typename Type, typename Base>
00119 class StaticCast
00120 {
00121     public:
00122         static void* cast (void* p)
00123         {
00124             return static_cast<Base*> (reinterpret_cast<Type*> (p));
00125         }
00126 };
00127 
00128 template<typename Type>
00129 class NullType
00130 {
00131 };
00132 
00133 template<typename Type, typename Contained>
00134 class ContainedCast
00135 {
00136     public:
00137         static void* cast (void* p)
00138         {
00139             return &reinterpret_cast<Type*> (p)->get(NullType<Contained> ());
00140         }
00141 };
00142 
00143 #endif

Generated by  doxygen 1.6.2