00001 // @(#)root/reflex:$Id: PropertyList.h 29288 2009-07-01 13:03:35Z axel $ 00002 // Author: Stefan Roiser 2004 00003 00004 // Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved. 00005 // 00006 // Permission to use, copy, modify, and distribute this software for any 00007 // purpose is hereby granted without fee, provided that this copyright and 00008 // permissions notice appear in all copies and derivatives. 00009 // 00010 // This software is provided "as is" without express or implied warranty. 00011 00012 #ifndef Reflex_PropertyList 00013 #define Reflex_PropertyList 00014 00015 00016 // Include files 00017 #include "Reflex/Kernel.h" 00018 #include <iostream> 00019 00020 namespace Reflex { 00021 // forward declarations 00022 class PropertyListImpl; 00023 class Any; 00024 00025 /** 00026 * @class PropertyList PropertyList.h Reflex/PropertyList.h 00027 * @author Stefan Roiser 00028 * @date 24/11/2003 00029 * @ingroup Ref 00030 */ 00031 class RFLX_API PropertyList { 00032 friend class OwnedPropertyList; 00033 friend RFLX_API std::ostream& operator <<(std::ostream& s, 00034 const PropertyList& p); 00035 00036 public: 00037 /** default constructor */ 00038 PropertyList(PropertyListImpl * propertyListImpl = 0); 00039 00040 00041 /** copy constructor */ 00042 PropertyList(const PropertyList &pl); 00043 00044 00045 /** destructor */ 00046 ~PropertyList(); 00047 00048 00049 /** 00050 * operator bool will return true if the property list is implemented 00051 * @return true if property list is not a fake one 00052 */ 00053 operator bool() const; 00054 00055 00056 /** 00057 * AddProperty will add a key value pair to the property list 00058 * @param key the key of the property 00059 * @param value the value of the property (as any object) 00060 * @return the property key of this property 00061 */ 00062 size_t AddProperty(const std::string& key, 00063 const Any& value) const; 00064 00065 00066 /** 00067 * AddProperty will add a property value pair to the property list 00068 * @param key the key of the property 00069 * @param value the value of the property (as any object) 00070 */ 00071 void AddProperty(size_t key, 00072 const Any& value) const; 00073 00074 00075 /** 00076 * AddProperty will add a key value pair to the property lsit 00077 * @param key the key of the property 00078 * @param value the value of the property (as any object) 00079 * @return the property key of this property 00080 */ 00081 size_t AddProperty(const std::string& key, 00082 const char* value) const; 00083 00084 00085 /** 00086 * AddProperty will add a key value pair to the property list 00087 * @param key the key of the property 00088 * @param value the value of the property (as any object) 00089 */ 00090 void AddProperty(size_t key, 00091 const char* value) const; 00092 00093 00094 /** 00095 * ClearProperties will remove all properties from the list 00096 */ 00097 void ClearProperties() const; 00098 00099 00100 /** 00101 * HasKey is deprecated. Use HasProperty instead with exactly the same functionality 00102 * The reason for deprecating this function is the misleading name. The function checks 00103 * if a given property (with a key) is attached to this item. 00104 */ 00105 bool HasKey(const std::string& key) const 00106 #if defined(__GNUC__) && !defined(__CINT__) 00107 __attribute__((deprecated)) 00108 #endif 00109 ; 00110 00111 00112 /** 00113 * HasProperty will return true if the property list contains a valid property with key 00114 * @param key the property key 00115 * @return true if key exists and property for key is valid 00116 */ 00117 bool HasProperty(const std::string& key) const; 00118 00119 00120 /** 00121 * HasProperty will return true if the property list contains a valid property with key 00122 * @param key the property key 00123 * @return true if key exists and property for key is valid 00124 */ 00125 bool HasProperty(size_t key) const; 00126 00127 00128 /** 00129 * Key_Begin will return the begin iterator of the key container 00130 * @return begin iterator of key container 00131 */ 00132 static StdString_Iterator Key_Begin(); 00133 00134 00135 /** 00136 * Key_End will return the end iterator of the key container 00137 * @return end iterator of key container 00138 */ 00139 static StdString_Iterator Key_End(); 00140 00141 00142 /** 00143 * Key_RBegin will return the rbegin iterator of the key container 00144 * @return rbegin iterator of key container 00145 */ 00146 static Reverse_StdString_Iterator Key_RBegin(); 00147 00148 00149 /** 00150 * Key_REnd will return the rend iterator of the key container 00151 * @return rend iterator of key container 00152 */ 00153 static Reverse_StdString_Iterator Key_REnd(); 00154 00155 00156 /** 00157 * KeysAsString will return a space separated list of all keys 00158 * @return a list of all currently allocated keys 00159 */ 00160 static std::string KeysAsString(); 00161 00162 00163 /** 00164 * KeyAt will return the nth key allocated 00165 * @param nth key currently allocated 00166 * @return key as a string 00167 */ 00168 static const std::string& KeyAt(size_t nth); 00169 00170 00171 /** 00172 * Key is the static getter function to return the index of a key. If allocateNew is 00173 * set to true a new key will be allocated if it doesn't exist and it's index returned. 00174 * Otherwise if the key exists the function returns it's index or 0 if no key exists. 00175 * @param key the key to look for 00176 * @param allocateNew allocate a new key if the key doesn't exist 00177 * @return key index or 0 if no key exists and allocateNew is set to false 00178 */ 00179 static size_t KeyByName(const std::string& key, 00180 bool allocateNew = false); 00181 00182 00183 /** 00184 * KeySize will return the number of currently allocated keys 00185 * @return number of allocated keys 00186 */ 00187 static size_t KeySize(); 00188 00189 00190 /** 00191 * PropertyAsString will return the nth property as a string if printable 00192 * @param key the property key 00193 * @return nth property value as string 00194 */ 00195 std::string PropertyAsString(const std::string& key) const; 00196 00197 00198 /** 00199 * PropertyAsString will return the property value as a string if it exists 00200 * The parameter is a property key which can be aquired with the PropertyKey method. 00201 * @param key property key to look for 00202 * @return string representation of the property 00203 */ 00204 std::string PropertyAsString(size_t key) const; 00205 00206 00207 /** 00208 * PropertyKey will return the the key value corresponding to the parameter given 00209 * @param key the string denoting the key value to lookup 00210 * @param allocateNew if set to true a new key will be allocated if it doesn't exist 00211 if set to false and the key doesn't exist the function returns 0 00212 * @return the key value corresponding to the key param 00213 */ 00214 size_t PropertyKey(const std::string& key, 00215 bool allocateNew = false) const; 00216 00217 00218 /** 00219 * PropertyKeys will return all keys of this property list 00220 * @return all property keys 00221 */ 00222 std::string PropertyKeys() const; 00223 00224 00225 /** 00226 * PropertyCount will return the number of properties attached 00227 * to this item. Attention!! Don't use the return value of this function for 00228 * iteration over the properties. Use KeySize() instead. 00229 * @return number of properties 00230 */ 00231 size_t PropertyCount() const; 00232 00233 00234 /** 00235 * This function is deprecated, use PropertyCount instead. The reason is, that 00236 * XSize() functions in Reflex usually return the size of a container while this 00237 * function now returns only the number of properties attached. The container it 00238 * self can be larger, because it may have holes 00239 */ 00240 size_t PropertySize() const 00241 #if defined(__GNUC__) && !defined(__CINT__) 00242 __attribute__((deprecated)) 00243 #endif 00244 ; 00245 00246 00247 /** 00248 * PropertyValue will return the nth property value 00249 * @param key the property key 00250 * @return nth property value 00251 */ 00252 Any& PropertyValue(const std::string& key) const; 00253 00254 00255 /** 00256 * PropertyAsString will return the property value as an Any object if it exists 00257 * The parameter is a property key which can be aquired with the PropertyKey method. 00258 * @param key property key to look for 00259 * @return Any representation of the property 00260 */ 00261 Any& PropertyValue(size_t key) const; 00262 00263 00264 /** 00265 * RemoveProperty will remove property value from the property list 00266 * @param key of the property identified by the string 00267 */ 00268 void RemoveProperty(const std::string& key) const; 00269 00270 00271 /** 00272 * RemoveProperty will remove a property value from the property list 00273 * @param key of the property identified by the property key number 00274 */ 00275 void RemoveProperty(size_t key) const; 00276 00277 private: 00278 /** 00279 * the properties of the item 00280 * @link aggregation 00281 * @clentCardinality 1 00282 * @supplierCardinality 0..1 00283 * @label propertylist impl 00284 */ 00285 PropertyListImpl* fPropertyListImpl; 00286 00287 }; // class Propertylist 00288 00289 /** 00290 * will put the property (key and value) on the ostream if printable 00291 * @param s the reference to the stream 00292 * @return the stream 00293 */ 00294 RFLX_API std::ostream& operator <<(std::ostream& s, 00295 const PropertyList& p); 00296 00297 } //namespace Reflex 00298 00299 #include "Reflex/internal/PropertyListImpl.h" 00300 00301 //------------------------------------------------------------------------------- 00302 inline 00303 Reflex::PropertyList::operator bool() const { 00304 //------------------------------------------------------------------------------- 00305 return 0 != fPropertyListImpl; 00306 } 00307 00308 00309 //------------------------------------------------------------------------------- 00310 inline Reflex::PropertyList::PropertyList(PropertyListImpl* propertyListImpl) 00311 //------------------------------------------------------------------------------- 00312 : fPropertyListImpl(propertyListImpl) { 00313 } 00314 00315 00316 //------------------------------------------------------------------------------- 00317 inline Reflex::PropertyList::PropertyList(const PropertyList& pl) 00318 //------------------------------------------------------------------------------- 00319 : fPropertyListImpl(pl.fPropertyListImpl) { 00320 } 00321 00322 00323 //------------------------------------------------------------------------------- 00324 inline Reflex::PropertyList::~PropertyList() { 00325 //------------------------------------------------------------------------------- 00326 } 00327 00328 00329 //------------------------------------------------------------------------------- 00330 inline size_t 00331 Reflex::PropertyList::AddProperty(const std::string& key, 00332 const Any& value) const { 00333 //------------------------------------------------------------------------------- 00334 if (fPropertyListImpl) { 00335 return fPropertyListImpl->AddProperty(key, value); 00336 } 00337 return 0; 00338 } 00339 00340 00341 //------------------------------------------------------------------------------- 00342 inline void 00343 Reflex::PropertyList::AddProperty(size_t key, 00344 const Any& value) const { 00345 //------------------------------------------------------------------------------- 00346 if (fPropertyListImpl) { 00347 return fPropertyListImpl->AddProperty(key, value); 00348 } 00349 } 00350 00351 00352 //------------------------------------------------------------------------------- 00353 inline size_t 00354 Reflex::PropertyList::AddProperty(const std::string& key, 00355 const char* value) const { 00356 //------------------------------------------------------------------------------- 00357 if (fPropertyListImpl) { 00358 return fPropertyListImpl->AddProperty(key, value); 00359 } 00360 return 0; 00361 } 00362 00363 00364 //------------------------------------------------------------------------------- 00365 inline void 00366 Reflex::PropertyList::AddProperty(size_t key, 00367 const char* value) const { 00368 //------------------------------------------------------------------------------- 00369 if (fPropertyListImpl) { 00370 return fPropertyListImpl->AddProperty(key, value); 00371 } 00372 } 00373 00374 00375 //------------------------------------------------------------------------------- 00376 inline void 00377 Reflex::PropertyList::ClearProperties() const { 00378 //------------------------------------------------------------------------------- 00379 if (fPropertyListImpl) { 00380 fPropertyListImpl->ClearProperties(); 00381 } 00382 } 00383 00384 00385 //------------------------------------------------------------------------------- 00386 inline bool 00387 Reflex::PropertyList::HasProperty(const std::string& key) const { 00388 //------------------------------------------------------------------------------- 00389 if (fPropertyListImpl) { 00390 return fPropertyListImpl->HasProperty(key); 00391 } 00392 return false; 00393 } 00394 00395 00396 //------------------------------------------------------------------------------- 00397 inline bool 00398 Reflex::PropertyList::HasProperty(size_t key) const { 00399 //------------------------------------------------------------------------------- 00400 if (fPropertyListImpl) { 00401 return fPropertyListImpl->HasProperty(key); 00402 } 00403 return false; 00404 } 00405 00406 00407 //------------------------------------------------------------------------------- 00408 inline bool 00409 Reflex::PropertyList::HasKey(const std::string& key) const { 00410 //------------------------------------------------------------------------------- 00411 return HasProperty(key); 00412 } 00413 00414 00415 //------------------------------------------------------------------------------- 00416 inline std::string 00417 Reflex::PropertyList::PropertyAsString(const std::string& key) const { 00418 //------------------------------------------------------------------------------- 00419 if (fPropertyListImpl) { 00420 return fPropertyListImpl->PropertyAsString(key); 00421 } 00422 return ""; 00423 } 00424 00425 00426 //------------------------------------------------------------------------------- 00427 inline std::string 00428 Reflex::PropertyList::PropertyAsString(size_t key) const { 00429 //------------------------------------------------------------------------------- 00430 if (fPropertyListImpl) { 00431 return fPropertyListImpl->PropertyAsString(key); 00432 } 00433 return ""; 00434 } 00435 00436 00437 //------------------------------------------------------------------------------- 00438 inline size_t 00439 Reflex::PropertyList::PropertyKey(const std::string& key, 00440 bool allocateNew) const { 00441 //------------------------------------------------------------------------------- 00442 if (fPropertyListImpl) { 00443 return fPropertyListImpl->PropertyKey(key, allocateNew); 00444 } 00445 return 0; 00446 } 00447 00448 00449 //------------------------------------------------------------------------------- 00450 inline std::string 00451 Reflex::PropertyList::PropertyKeys() const { 00452 //------------------------------------------------------------------------------- 00453 if (fPropertyListImpl) { 00454 return fPropertyListImpl->PropertyKeys(); 00455 } 00456 return ""; 00457 } 00458 00459 00460 //------------------------------------------------------------------------------- 00461 inline size_t 00462 Reflex::PropertyList::PropertyCount() const { 00463 //------------------------------------------------------------------------------- 00464 if (fPropertyListImpl) { 00465 return fPropertyListImpl->PropertyCount(); 00466 } 00467 return 0; 00468 } 00469 00470 00471 //------------------------------------------------------------------------------- 00472 inline size_t 00473 Reflex::PropertyList::PropertySize() const { 00474 //------------------------------------------------------------------------------- 00475 return PropertyCount(); 00476 } 00477 00478 00479 //------------------------------------------------------------------------------- 00480 inline void 00481 Reflex::PropertyList::RemoveProperty(const std::string& key) const { 00482 //------------------------------------------------------------------------------- 00483 if (fPropertyListImpl) { 00484 fPropertyListImpl->RemoveProperty(key); 00485 } 00486 } 00487 00488 00489 //------------------------------------------------------------------------------- 00490 inline void 00491 Reflex::PropertyList::RemoveProperty(size_t key) const { 00492 //------------------------------------------------------------------------------- 00493 if (fPropertyListImpl) { 00494 fPropertyListImpl->RemoveProperty(key); 00495 } 00496 } 00497 00498 00499 #endif // Reflex_PropertyList