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.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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines