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.GPL ** 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 <string> 00034 #include <map> 00035 #include <typeinfo> 00036 #include <cstdio> 00037 #include <vector> 00038 00039 #include <ICLUtils/Mutex.h> 00040 #include <ICLUtils/SmartPtr.h> 00041 00042 namespace icl{ 00043 namespace utils{ 00044 00046 00066 class MultiTypeMap{ 00067 public: 00069 MultiTypeMap(); 00070 00072 ~MultiTypeMap(); 00073 00075 template<class T> 00076 static inline const std::string &get_type_name(){ 00077 static std::string NAME = typeid(T).name(); 00078 return NAME; 00079 } 00080 00082 00086 template<class T> 00087 inline T *allocArray(const std::string &id,unsigned int n){ 00088 if(!n){ 00089 ERROR_LOG("unable to create an array of size 0 for id " << id << "!"); 00090 return 0; 00091 } 00092 if(contains(id)){ 00093 ERROR_LOG("id " << id << "is already defined"); 00094 return 0; 00095 } 00096 DataArray &da = (*m_oDataMapPtr)[id]; 00097 da.data = new T[n]; 00098 da.len = n; 00099 da.type = get_type_name<T>(); 00100 da.release_func = DataArray::release_data_array<T>; 00101 return reinterpret_cast<T*>(da.data); 00102 } 00103 00105 00109 template<class T> 00110 inline T &allocValue(const std::string &id, const T &val=T()){ 00111 static T _NULL = T(); 00112 if(contains(id)){ 00113 ERROR_LOG("id " << id << "is already defined"); 00114 return _NULL; 00115 } 00116 DataArray &da = (*m_oDataMapPtr)[id]; 00117 da.data = new T(val); 00118 da.len = 0; // indicates a single value ! 00119 da.type = get_type_name<T>(); 00120 00121 da.release_func = DataArray::release_data_array<T>; 00122 return *(reinterpret_cast<T*>(da.data)); 00123 } 00124 00126 00127 template<class T> 00128 inline void release(const std::string &id){ 00129 if(!contains(id)){ 00130 ERROR_LOG("id "<< id << " not found \n"); 00131 return; 00132 } 00133 DataArray &da = (*m_oDataMapPtr)[id]; 00134 if(da.type != get_type_name<T>()){ 00135 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00136 ERROR_LOG("type is " << da.type << "\n"); 00137 return; 00138 } 00139 da.release_func(&da); 00140 m_oDataMapPtr->erase(m_oDataMapPtr->find(id)); 00141 } 00142 00144 00148 template<class T> 00149 inline T* getArray(const std::string &id, int *lenDst=0){ 00150 if(!contains(id)){ 00151 ERROR_LOG("id "<< id << " not found \n"); 00152 return 0; 00153 } 00154 00155 DataArray &da = (*m_oDataMapPtr)[id]; 00156 00157 if(da.type != get_type_name<T>()){ 00158 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00159 return 0; 00160 } 00161 if(!da.len){ 00162 ERROR_LOG("unable to access entry " << id << " as array, because it is a value!"); 00163 return 0; 00164 } 00165 if(lenDst) *lenDst = da.len; 00166 return reinterpret_cast<T*>(da.data); 00167 } 00168 00170 00174 template<class T> 00175 inline T &getValue(const std::string &id, bool checkType=true){ 00176 static T _NULL; 00177 if(!contains(id)){ 00178 ERROR_LOG("id "<< id << " not found \n"); 00179 return _NULL; 00180 } 00181 00182 // orig 00183 DataArray &da = (*m_oDataMapPtr)[id]; 00184 //DEBUG_LOG("type of da is " << da.type); 00185 if(checkType && (da.type != get_type_name<T>())){ 00186 ERROR_LOG("unable to cast "<< id << " to a given type "<< get_type_name<T>() <<"\n"); 00187 ERROR_LOG("type is " << da.type << "\n"); 00188 return _NULL; 00189 } 00190 if(da.len){ 00191 ERROR_LOG("unable to access entry " << id << " as value, because it is an array!"); 00192 return _NULL; 00193 } 00194 return *reinterpret_cast<T*>(da.data); 00195 } 00196 00197 template<class T> 00198 inline const T &getValue(const std::string &id, bool checkType=true) const{ 00199 return const_cast<MultiTypeMap*>(this)->getValue<T>(id,checkType); 00200 } 00201 00202 00203 00205 00208 const std::string &getType(const std::string &id) const; 00209 00211 00213 template<class T> 00214 inline bool checkType(const std::string &id) const{ 00215 return check_type_internal(id,get_type_name<T>()); 00216 } 00217 00219 00222 bool isArray(const std::string &id) const; 00223 00225 00227 bool contains(const std::string &id) const; 00228 00229 00230 // internally locks the datastore 00231 inline void lock() const { m_oMutexPtr->lock(); } 00232 00234 inline void unlock() const { m_oMutexPtr->unlock(); } 00235 protected: 00236 00237 bool check_type_internal(const std::string &id, const std::string &typestr) const; 00238 00240 struct DataArray{ 00241 00243 00245 template<class T> 00246 static void release_data_array(DataArray *da){ 00247 ICLASSERT_RETURN(da->type == get_type_name<T>()); 00248 if(da->len) delete [] reinterpret_cast<T*>(da->data); 00249 else delete reinterpret_cast<T*>(da->data); 00250 } 00252 DataArray(void *data=0, int len=0):data(data),len(len),type(""),release_func(0){} 00253 void *data; //<! identified using the type string 00254 int len; //<! length of the data array or 0 if it was created using () instead of [] 00255 std::string type; //<! created using RTTI 00256 void (*release_func)(DataArray*); //<! data release function called by the parent MultiTypeMap object 00257 }; 00258 00259 public: 00261 void listContents() const; 00262 00263 // removes all data from this data store 00264 void clear(); 00265 00266 00268 struct Entry{ 00269 Entry(){} 00270 Entry(const std::string &key,const std::string &type, int len): 00271 key(key),type(type),len(len){} 00272 std::string key; 00273 std::string type; 00274 int len; 00275 }; 00276 00278 std::vector<Entry> getEntryList() const; 00279 00280 protected: 00281 00283 typedef std::map<std::string,DataArray> DataMap; 00284 00286 typedef SmartPtr<DataMap> SmartDataMapPtr; 00287 00289 typedef SmartPtr<Mutex> SmartMutexPtr; 00290 00292 mutable SmartDataMapPtr m_oDataMapPtr; 00293 00295 mutable SmartMutexPtr m_oMutexPtr; 00296 }; 00297 } // namespace utils 00298 } 00299 00300