/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant 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. GtkRadiant 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 GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(INCLUDED_TYPESYSTEM_H) #define INCLUDED_TYPESYSTEM_H #include #include "generic/callback.h" #include "generic/static.h" class InitialiserList { typedef std::list Initialisers; Initialisers m_initialisers; mutable bool m_initialised; public: InitialiserList() : m_initialised(false) { } void addInitialiser(const Callback& callback) { m_initialisers.push_back(callback); } void initialise() const { if(!m_initialised) { m_initialised = true; for(Initialisers::const_iterator i = m_initialisers.begin(); i != m_initialisers.end(); ++i) { (*i)(); } } } }; //--Type System------------------- class TypeSystemInitialiser : public InitialiserList { }; typedef SmartStatic StaticTypeSystemInitialiser; class TypeSystemRef : public StaticTypeSystemInitialiser { public: TypeSystemRef() { StaticTypeSystemInitialiser::instance().initialise(); } }; typedef std::size_t TypeId; typedef void*(*TypeCast)(void*); template class TypeCastTable { TypeCast m_casts[SIZE]; public: TypeCastTable() { std::uninitialized_fill(m_casts, m_casts + SIZE, TypeCast(0)); } void install(TypeId typeId, TypeCast typeCast) { m_casts[typeId] = typeCast; } void* cast(TypeId typeId, void* p) { TypeCast typeCast = m_casts[typeId]; if(typeCast != 0) { return typeCast(p); } return 0; } }; template class CastInstaller { public: static void install(TypeCastTable& table) { table.install(Type::getTypeId(), Cast::cast); } }; template class IdentityCast { public: static void* cast(void* p) { return p; } }; template class StaticCast { public: static void* cast(void* p) { return static_cast(reinterpret_cast(p)); } }; template class NullType { }; template class ContainedCast { public: static void* cast(void* p) { return &reinterpret_cast(p)->get(NullType()); } }; #endif