Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLUtils/src/ICLUtils/MultiTypeMap.h ** 00010 ** Module : ICLUtils ** 00011 ** Authors: Christof Elbrechter ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 #pragma once 00032 00033 #include <ICLUtils/CompatMacros.h> 00034 #include <ICLUtils/Mutex.h> 00035 #include <ICLUtils/SmartPtr.h> 00036 00037 #include <string> 00038 #include <map> 00039 #include <typeinfo> 00040 #include <cstdio> 00041 #include <vector> 00042 00043 namespace icl{ 00044 namespace utils{ 00045 00047 00067 class ICLUtils_API MultiTypeMap{ 00068 public: 00070 MultiTypeMap(); 00071 00073 ~MultiTypeMap(); 00074 00076 template<class T> 00077 static inline const std::string &get_type_name(){ 00078 static std::string NAME = typeid(T).name(); 00079 return NAME; 00080 } 00081 00083 00087 template<class T> 00088 inline T *allocArray(const std::string &id,unsigned int n){ 00089 if(!n){ 00090 ERROR_LOG("unable to create an array of size 0 for id " << id << "!"); 00091 return 0; 00092 } 00093 if(contains(id)){ 00094 ERROR_LOG("id " << id << "is already defined"); 00095 return 0; 00096 } 00097 DataArray &da = (*m_oDataMapPtr)[id]; 00098 da.data = new T[n]; 00099 da.len = n; 00100 da.type = get_type_name<T>(); 00101 da.release_func = DataArray::release_data_array<T>; 00102 return reinterpret_cast<T*>(da.data); 00103 } 00104 00106 00110 template<class T> 00111 inline T &allocValue(const std::string &id, const T &val=T()){ 00112 static T _NULL = T(); 00113 if(contains(id)){ 00114 ERROR_LOG("id " << id << "is already defined"); 00115 return _NULL; 00116 } 00117 DataArray &da = (*m_oDataMapPtr)[id]; 00118 da.data = new T(val); 00119 da.len = 0; // indicates a single value ! 00120 da.type = get_type_name<T>(); 00121 00122 da.release_func = DataArray::release_data_array<T>; 00123 return *(reinterpret_cast<T*>(da.data)); 00124 } 00125 00127 00128 template<class T> 00129 inline void release(const std::string &id){ 00130 if(!contains(id)){ 00131 ERROR_LOG("id "<< id << " not found \n"); 00132 return; 00133 } 00134 DataArray &da = (*m_oDataMapPtr)[id]; 00135 if(da.type != get_type_name<T>()){ 00136 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00137 ERROR_LOG("type is " << da.type << "\n"); 00138 return; 00139 } 00140 da.release_func(&da); 00141 m_oDataMapPtr->erase(m_oDataMapPtr->find(id)); 00142 } 00143 00145 00149 template<class T> 00150 inline T* getArray(const std::string &id, int *lenDst=0){ 00151 if(!contains(id)){ 00152 ERROR_LOG("id "<< id << " not found \n"); 00153 return 0; 00154 } 00155 00156 DataArray &da = (*m_oDataMapPtr)[id]; 00157 00158 if(da.type != get_type_name<T>()){ 00159 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00160 return 0; 00161 } 00162 if(!da.len){ 00163 ERROR_LOG("unable to access entry " << id << " as array, because it is a value!"); 00164 return 0; 00165 } 00166 if(lenDst) *lenDst = da.len; 00167 return reinterpret_cast<T*>(da.data); 00168 } 00169 00171 00175 template<class T> 00176 inline T &getValue(const std::string &id, bool checkType=true){ 00177 static T _NULL; 00178 if(!contains(id)){ 00179 ERROR_LOG("id "<< id << " not found \n"); 00180 return _NULL; 00181 } 00182 00183 // orig 00184 DataArray &da = (*m_oDataMapPtr)[id]; 00185 //DEBUG_LOG("type of da is " << da.type); 00186 if(checkType && (da.type != get_type_name<T>())){ 00187 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00188 ERROR_LOG("type is " << da.type << "\n"); 00189 return _NULL; 00190 } 00191 if(da.len){ 00192 ERROR_LOG("unable to access entry " << id << " as value, because it is an array!"); 00193 return _NULL; 00194 } 00195 return *reinterpret_cast<T*>(da.data); 00196 } 00197 00198 template<class T> 00199 inline const T &getValue(const std::string &id, bool checkType=true) const{ 00200 return const_cast<MultiTypeMap*>(this)->getValue<T>(id,checkType); 00201 } 00202 00203 00204 00206 00209 const std::string &getType(const std::string &id) const; 00210 00212 00214 template<class T> 00215 inline bool checkType(const std::string &id) const{ 00216 return check_type_internal(id,get_type_name<T>()); 00217 } 00218 00220 00223 bool isArray(const std::string &id) const; 00224 00226 00228 bool contains(const std::string &id) const; 00229 00230 00231 // internally locks the datastore 00232 inline void lock() const { m_oMutexPtr->lock(); } 00233 00235 inline void unlock() const { m_oMutexPtr->unlock(); } 00236 protected: 00237 00238 bool check_type_internal(const std::string &id, const std::string &typestr) const; 00239 00241 struct DataArray{ 00242 00244 00246 template<class T> 00247 static void release_data_array(DataArray *da){ 00248 ICLASSERT_RETURN(da->type == get_type_name<T>()); 00249 if(da->len) delete [] reinterpret_cast<T*>(da->data); 00250 else delete reinterpret_cast<T*>(da->data); 00251 } 00253 DataArray(void *data=0, int len=0):data(data),len(len),type(""),release_func(0){} 00254 void *data; //<! identified using the type string 00255 int len; //<! length of the data array or 0 if it was created using () instead of [] 00256 std::string type; //<! created using RTTI 00257 void (*release_func)(DataArray*); //<! data release function called by the parent MultiTypeMap object 00258 }; 00259 00260 public: 00262 void listContents() const; 00263 00264 // removes all data from this data store 00265 void clear(); 00266 00267 00269 struct Entry{ 00270 Entry(){} 00271 Entry(const std::string &key,const std::string &type, int len): 00272 key(key),type(type),len(len){} 00273 std::string key; 00274 std::string type; 00275 int len; 00276 }; 00277 00279 std::vector<Entry> getEntryList() const; 00280 00281 protected: 00282 00284 typedef std::map<std::string,DataArray> DataMap; 00285 00287 typedef SmartPtr<DataMap> SmartDataMapPtr; 00288 00290 typedef SmartPtr<Mutex> SmartMutexPtr; 00291 00293 mutable SmartDataMapPtr m_oDataMapPtr; 00294 00296 mutable SmartMutexPtr m_oMutexPtr; 00297 }; 00298 } // namespace utils 00299 } 00300 00301