PropertyMap.h
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @class PropertyMap 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @date Fall 2008 00005 00006 @brief 00007 Bare-bones map used throughout Milton for holding custom initialization 00008 parameters/options/information 00009 00010 @TODO: Try using QHash instead of std::map for efficiency reasons? 00011 <!-------------------------------------------------------------------->**/ 00012 00013 #ifndef PROPERTY_MAP_H_ 00014 #define PROPERTY_MAP_H_ 00015 00016 #include <boost/any.hpp> 00017 #include <common/common.h> 00018 #include <ostream> 00019 #include <map> 00020 00021 class PropertyMap { 00022 protected: 00023 DECLARE_STL_TYPEDEF2(std::map<std::string, boost::any>, STLPropertyMap); 00024 00025 public: 00026 ///@name Constructors 00027 //@{----------------------------------------------------------------- 00028 00029 inline PropertyMap() 00030 { } 00031 00032 inline PropertyMap(const PropertyMap ©) { 00033 // Note: cannot just call 'inherit' which does the same thing 00034 // because it is virtual and the subclass' vtables may not be 00035 // initialized yet.. 00036 FOREACH(STLPropertyMapConstIter, copy.m_propertyMap, iter) { 00037 insert(iter->first, iter->second); 00038 } 00039 } 00040 00041 virtual ~PropertyMap() 00042 { } 00043 00044 00045 //@}----------------------------------------------------------------- 00046 ///@name Main usage interface 00047 //@{----------------------------------------------------------------- 00048 00049 /** 00050 * Resets all properties to their default values 00051 */ 00052 void clear(); 00053 00054 virtual void inherit(const PropertyMap &m, bool overwrite = true) { 00055 FOREACH(STLPropertyMapConstIter, m.m_propertyMap, iter) { 00056 const std::string &key = iter->first; 00057 00058 if (overwrite || !contains(key)) 00059 (*this)[key] = iter->second; 00060 } 00061 } 00062 00063 /** 00064 * @returns whether or not this map contains a value for the given key 00065 */ 00066 inline bool contains(const std::string &key) const { 00067 STLPropertyMapConstIter iter = m_propertyMap.find(key); 00068 00069 return ((iter != m_propertyMap.end()) && !iter->second.empty()); 00070 } 00071 00072 /** 00073 * Inserts the given key, value pair into this map 00074 */ 00075 template<typename T> 00076 inline void insert(const std::string &key, const T &value) { 00077 // value will implicitly be converted to boost::any 00078 //m_propertyMap.insert(STLPropertyMap::value_type(key, boost::any(value))); 00079 m_propertyMap[key] = value; 00080 } 00081 00082 /** 00083 * @returns a reference to the value associated with the given key 00084 */ 00085 template<typename T> 00086 inline T &getValue(const std::string &key) { 00087 ASSERT(contains(key)); 00088 00089 try { 00090 T &ret = boost::any_cast<T&>((*this)[key]); 00091 00092 return ret; 00093 } catch(boost::bad_any_cast &e) { 00094 std::cerr << "PropertyMap::getValue(" << key << ") " << std::endl; 00095 ASSERT(0); 00096 throw e; 00097 } 00098 } 00099 00100 /** 00101 * @returns a reference to the value associated with the given key or 00102 * the given defaultValue if no custom value exists 00103 */ 00104 template<typename T> 00105 inline T &getValue(const std::string &key, const T &defaultValue) { 00106 if (!contains(key)) 00107 m_propertyMap[key] = defaultValue; 00108 00109 return boost::any_cast<T&>((*this)[key]); 00110 } 00111 00112 /** 00113 * @returns a reference to the variant wrapper around the value 00114 * associated with the given key 00115 */ 00116 inline boost::any &operator[](const std::string &key) { 00117 return m_propertyMap[key]; 00118 } 00119 00120 00121 //@}----------------------------------------------------------------- 00122 00123 protected: 00124 /// Internal std::map 00125 STLPropertyMap m_propertyMap; 00126 00127 friend std::ostream &operator<<(std::ostream &os, const PropertyMap &m); 00128 }; 00129 00130 template<> 00131 inline unsigned &PropertyMap::getValue(const std::string &key, const unsigned &defaultValue) { 00132 if (!contains(key)) 00133 m_propertyMap[key] = defaultValue; 00134 00135 boost::any &v = m_propertyMap[key]; 00136 00137 try { 00138 return boost::any_cast<unsigned&>(v); 00139 } catch(boost::bad_any_cast &e) { 00140 v = static_cast<unsigned>(boost::any_cast<int>(v)); 00141 00142 return boost::any_cast<unsigned&>(v); 00143 } 00144 } 00145 00146 template<> 00147 inline real_t &PropertyMap::getValue(const std::string &key, const real_t &defaultValue) { 00148 if (!contains(key)) 00149 m_propertyMap[key] = defaultValue; 00150 00151 boost::any &v = m_propertyMap[key]; 00152 00153 if (v.type() == typeid(real_t)) 00154 return boost::any_cast<real_t&>(v); 00155 00156 if (v.type() == typeid(int)) { 00157 v = static_cast<real_t>(boost::any_cast<int>(v)); 00158 return boost::any_cast<real_t&>(v); 00159 } 00160 00161 if (v.type() == typeid(unsigned)) { 00162 v = static_cast<real_t>(boost::any_cast<unsigned>(v)); 00163 return boost::any_cast<real_t&>(v); 00164 } 00165 00166 if (v.type() == typeid(float)) { 00167 v = static_cast<real_t>(boost::any_cast<float>(v)); 00168 return boost::any_cast<real_t&>(v); 00169 } 00170 00171 if (v.type() == typeid(double)) { 00172 v = static_cast<real_t>(boost::any_cast<double>(v)); 00173 return boost::any_cast<real_t&>(v); 00174 } 00175 00176 ASSERT(0 && "PropertyMap::getValue<real_t> found invalid value\n\n"); 00177 return boost::any_cast<real_t&>(v); 00178 } 00179 00180 /// Prints a PropertyMap to an output stream for debugging purposes 00181 std::ostream &operator<<(std::ostream &os, const PropertyMap &m); 00182 00183 #endif // PROPERTY_MAP_H_ 00184
Generated on 28 Feb 2009 for Milton by
1.5.6