Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MultiTypeMap.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines