Dict.h

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC
00003 //
00004 //  @@ All Rights Reserved @@
00005 //  This file is part of the RDKit.
00006 //  The contents are covered by the terms of the BSD license
00007 //  which is included in the file license.txt, found at the root
00008 //  of the RDKit source tree.
00009 //
00010 /*! \file Dict.h
00011 
00012   \brief Defines the Dict class
00013 
00014 */  
00015 #ifndef __RD_DICT_H__
00016 #define __RD_DICT_H__
00017 
00018 #include <map>
00019 #include <string>
00020 #include <vector>
00021 #include <boost/any.hpp>
00022 #include <RDBoost/Exceptions.h>
00023 #include <boost/lexical_cast.hpp>
00024 
00025 namespace RDKit{
00026   typedef std::vector<std::string> STR_VECT;
00027 
00028   //! \brief The \c Dict class can be used to store objects of arbitrary
00029   //!        type keyed by \c strings.
00030   //!
00031   //!  The actual storage is done using \c boost::any objects.
00032   //!
00033   class Dict {
00034     //! \brief this function is used solely to force the instantiation of particular
00035     //!    types of the \c Dict.toAny() and \c Dict.fromAny() methods in order to
00036     //!    avoid link errors.
00037     friend void force_types();
00038   public:
00039     typedef std::map<const std::string, boost::any> DataType;
00040     Dict(){
00041       _data.clear();
00042     };
00043 
00044     Dict(const Dict &other) {
00045       _data = other._data;
00046     };
00047 
00048     Dict &operator=(const Dict &other) {
00049       _data = other._data;
00050       return *this;
00051     };
00052 
00053     //----------------------------------------------------------
00054     //! \brief Returns whether or not the dictionary contains a particular
00055     //!        key.
00056     bool hasVal(const char *what) const{
00057       std::string key(what);
00058       return hasVal(key);
00059     };
00060     bool hasVal(const std::string &what) const {
00061       return _data.find(what)!=_data.end();
00062     };
00063 
00064     //----------------------------------------------------------
00065     //! Returns the set of keys in the dictionary
00066     /*!
00067        \return  a \c STR_VECT
00068     */
00069     STR_VECT keys() const {
00070       STR_VECT res;
00071       DataType::const_iterator item;
00072       for (item = _data.begin(); item != _data.end(); item++) {
00073         res.push_back(item->first);
00074       }
00075       return res;
00076     }
00077 
00078     //----------------------------------------------------------
00079     //! \brief Gets the value associated with a particular key
00080     /*!
00081        \param what  the key to lookup
00082        \param res   a reference used to return the result
00083     
00084        <B>Notes:</b>
00085         - If \c res is a \c std::string, every effort will be made
00086           to convert the specified element to a string using the
00087           \c boost::lexical_cast machinery.
00088         - If the dictionary does not contain the key \c what,
00089           a KeyErrorException will be thrown.
00090     */
00091     template <typename T>
00092     void getVal(const std::string &what,T &res) const {
00093       DataType::const_iterator pos=_data.find(what);
00094       if(pos==_data.end())
00095         throw KeyErrorException(what);
00096       const boost::any &val = pos->second;
00097       res = fromany<T>(val);
00098     };
00099     //! \overload
00100     template <typename T>
00101     T getVal(const std::string &what) const {
00102       T res;
00103       getVal(what,res);
00104       return res;
00105     }
00106 
00107     //! \overload
00108     template <typename T>
00109     T getVal(const char *what,T &res) const {
00110       std::string key(what);
00111       getVal(key, res);
00112       return res;
00113     };
00114     //! \overload
00115     template <typename T>
00116     T getVal(const char *what) const {
00117       std::string key(what);
00118       return getVal<T>(key);
00119     };
00120 
00121     //! \overload
00122     void getVal(const std::string &what, std::string &res) const;
00123 
00124     //----------------------------------------------------------
00125     //! \brief Sets the value associated with a key
00126     /*!
00127       
00128        \param what the key to set
00129        \param val  the value to store
00130     
00131        <b>Notes:</b>
00132           - If \c val is a <tt>const char *</tt>, it will be converted
00133              to a \c std::string for storage.
00134           - If the dictionary already contains the key \c what,
00135             the value will be replaced.
00136     */
00137     template <typename T>
00138     void setVal(const std::string &what, T &val){
00139       std::string key = what;
00140       _data[key] = toany(val);
00141     };
00142     //! \overload
00143     template <typename T>
00144     void setVal(const char *what, T &val){
00145       std::string key = what;
00146       setVal(key,val);
00147     };
00148     //! \overload
00149     void setVal(const std::string &what, const char *val){
00150       std::string h(val);
00151       setVal(what,h);
00152     }
00153 
00154 
00155 
00156     //----------------------------------------------------------
00157     //! \brief Clears the value associated with a particular key,
00158     //!     removing the key from the dictionary.
00159     /*!
00160      
00161        \param what the key to clear
00162     
00163      <b>Notes:</b>
00164         - If the dictionary does not contain the key \c what,
00165           a KeyErrorException will be thrown.
00166     */
00167     void clearVal(const std::string &what) {
00168       if(! this->hasVal(what) ) throw KeyErrorException(what);
00169       _data.erase(what);
00170     };
00171 
00172     //! \overload
00173     void clearVal(const char *what) {
00174       std::string key=what;
00175       clearVal(key);
00176     };
00177 
00178     //----------------------------------------------------------
00179     //! \brief Clears all keys (and values) from the dictionary.
00180     //!
00181     void reset(){
00182       _data.clear();
00183     };
00184 
00185     //----------------------------------------------------------
00186     //! Converts a \c boost::any to type \c T
00187     /*!
00188        \param arg a \c boost::any reference
00189 
00190        \returns the converted object of type \c T
00191     */
00192     template <typename T>
00193       T fromany(const boost::any &arg) const;
00194     
00195 
00196     //----------------------------------------------------------
00197     //! Converts an instance of type \c T to \c boost::any
00198     /*!
00199        \param arg the object to be converted
00200 
00201        \returns a \c boost::any instance
00202     */
00203     template <typename T>
00204       boost::any toany(T arg) const;
00205 
00206   private:
00207     DataType _data; //!< the actual dictionary
00208   };
00209 }
00210 #endif