language/duchain
duchainregister.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef DUCHAINREGISTER_H
00020 #define DUCHAINREGISTER_H
00021
00022 #include "duchainbase.h"
00023
00024 namespace KDevelop {
00025 class DUChainBase;
00026 class DUChainBaseData;
00027
00031 class KDEVPLATFORMLANGUAGE_EXPORT DUChainBaseFactory {
00032 public:
00033 virtual DUChainBase* create(DUChainBaseData* data) const = 0;
00034 virtual void callDestructor(DUChainBaseData* data) const = 0;
00035 virtual void freeDynamicData(DUChainBaseData* data) const = 0;
00036 virtual void copy(const DUChainBaseData& from, DUChainBaseData& to, bool constant) const = 0;
00037 virtual DUChainBaseData* cloneData(const DUChainBaseData& data) const = 0;
00038 virtual uint dynamicSize(const DUChainBaseData& data) const = 0;
00039
00040 virtual ~DUChainBaseFactory() {
00041 }
00042 };
00043
00045 template<class T, class Data>
00046 class DUChainItemFactory : public DUChainBaseFactory {
00047 public:
00048 DUChainBase* create(DUChainBaseData* data) const {
00049 return new T(*static_cast<Data*>(data));
00050 }
00051
00052 void copy(const DUChainBaseData& from, DUChainBaseData& to, bool constant) const {
00053 Q_ASSERT(from.classId == T::Identity);
00054
00055 bool previousConstant = DUChainBaseData::shouldCreateConstantData();
00056 DUChainBaseData::setShouldCreateConstantData(constant);
00057
00058 new (&to) Data(static_cast<const Data&>(from));
00059
00060 DUChainBaseData::setShouldCreateConstantData(previousConstant);
00061 }
00062
00063 void callDestructor(DUChainBaseData* data) const {
00064 Q_ASSERT(data->classId == T::Identity);
00065 static_cast<Data*>(data)->~Data();
00066 }
00067
00068 void freeDynamicData(DUChainBaseData* data) const {
00069 Q_ASSERT(data->classId == T::Identity);
00070 static_cast<Data*>(data)->freeDynamicData();
00071 }
00072
00073 uint dynamicSize(const DUChainBaseData& data) const {
00074 Q_ASSERT(data.classId == T::Identity);
00075 return static_cast<const Data&>(data).dynamicSize();
00076 }
00077
00078 DUChainBaseData* cloneData(const DUChainBaseData& data) const {
00079 Q_ASSERT(data.classId == T::Identity);
00080 return new Data(static_cast<const Data&>(data));
00081 }
00082 };
00083
00090 class KDEVPLATFORMLANGUAGE_EXPORT DUChainItemSystem {
00091 public:
00095 template<class T, class Data>
00096 void registerTypeClass() {
00097 if(m_factories.size() <= T::Identity) {
00098 m_factories.resize(T::Identity+1);
00099 m_dataClassSizes.resize(T::Identity+1);
00100 }
00101
00102 Q_ASSERT(!m_factories[T::Identity]);
00103 m_factories[T::Identity] = new DUChainItemFactory<T, Data>();
00104 m_dataClassSizes[T::Identity] = sizeof(Data);
00105 }
00106
00110 template<class T, class Data>
00111 void unregisterTypeClass() {
00112 Q_ASSERT(m_factories.size() > T::Identity);
00113 Q_ASSERT(m_factories[T::Identity]);
00114 delete m_factories[T::Identity];
00115 m_factories[T::Identity] = 0;
00116 m_dataClassSizes[T::Identity] = 0;
00117 }
00118
00123 DUChainBase* create(DUChainBaseData* data) const;
00124
00126 DUChainBaseData* cloneData(const DUChainBaseData& data) const;
00127
00132 void copy(const DUChainBaseData& from, DUChainBaseData& to, bool constant) const;
00133
00135 uint dynamicSize(const DUChainBaseData& data) const;
00136
00139 size_t dataClassSize(const DUChainBaseData& data) const;
00140
00143 void callDestructor(DUChainBaseData* data) const;
00144
00147 void freeDynamicData(DUChainBaseData* data) const;
00148
00150 static DUChainItemSystem& self();
00151
00152 private:
00153 QVector<DUChainBaseFactory*> m_factories;
00154 QVector<size_t> m_dataClassSizes;
00155 };
00156
00160 template<class T, class Data>
00161 struct DUChainItemRegistrator {
00162 DUChainItemRegistrator() {
00163 DUChainItemSystem::self().registerTypeClass<T, Data>();
00164 }
00165 ~DUChainItemRegistrator() {
00166 DUChainItemSystem::self().unregisterTypeClass<T, Data>();
00167 }
00168 };
00169
00173 #define REGISTER_DUCHAIN_ITEM(Class) KDevelop::DUChainItemRegistrator<Class, Class ## Data> register ## Class
00174 #define REGISTER_DUCHAIN_ITEM_WITH_DATA(Class, Data) KDevelop::DUChainItemRegistrator<Class, Data> register ## Class
00175
00176 }
00177
00178 #endif