RDKit
Open-source cheminformatics and machine learning.
Dict.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 /*! \file Dict.h
11 
12  \brief Defines the Dict class
13 
14 */
15 #ifndef __RD_DICT_H__
16 #define __RD_DICT_H__
17 
18 #include <map>
19 #include <string>
20 #include <vector>
21 #include "RDValue.h"
22 #include "Exceptions.h"
23 #include <boost/lexical_cast.hpp>
24 
25 namespace RDKit {
26 typedef std::vector<std::string> STR_VECT;
27 
28 //! \brief The \c Dict class can be used to store objects of arbitrary
29 //! type keyed by \c strings.
30 //!
31 //! The actual storage is done using \c RDValue objects.
32 //!
33 class Dict {
34  struct Pair {
35  std::string key;
36  RDValue val;
37 
38  Pair() : key(), val() {}
39  Pair(const std::string &s, const RDValue &v) : key(s), val(v) {
40  }
41  };
42 
43  typedef std::vector<Pair> DataType;
44 public:
45  Dict() : _data(), _hasNonPodData(false) { };
46 
47  Dict(const Dict &other) : _data(other._data) {
48  _hasNonPodData = other._hasNonPodData;
49  if (_hasNonPodData) {
50  std::vector<Pair> data(other._data.size());
51  _data.swap(data);
52  for (size_t i=0; i< _data.size(); ++i) {
53  _data[i].key = other._data[i].key;
54  copy_rdvalue(_data[i].val, other._data[i].val);
55  }
56  }
57  }
58 
59  ~Dict() {
60  reset(); // to clear pointers if necessary
61  }
62 
63  Dict &operator=(const Dict &other) {
64  _hasNonPodData = other._hasNonPodData;
65  if (_hasNonPodData) {
66  std::vector<Pair> data(other._data.size());
67  _data.swap(data);
68  for (size_t i=0; i< _data.size(); ++i) {
69  _data[i].key = other._data[i].key;
70  copy_rdvalue(_data[i].val, other._data[i].val);
71  }
72  } else {
73  _data = other._data;
74  }
75  return *this;
76  };
77 
78  //----------------------------------------------------------
79  //! \brief Returns whether or not the dictionary contains a particular
80  //! key.
81  bool hasVal(const std::string &what) const {
82  for(size_t i=0 ; i< _data.size(); ++i) {
83  if (_data[i].key == what ) return true;
84  }
85  return false;
86  };
87 
88  //----------------------------------------------------------
89  //! Returns the set of keys in the dictionary
90  /*!
91  \return a \c STR_VECT
92  */
93  STR_VECT keys() const {
94  STR_VECT res;
95  DataType::const_iterator item;
96  for (item = _data.begin(); item != _data.end(); item++) {
97  res.push_back(item->key);
98  }
99  return res;
100  }
101 
102  //----------------------------------------------------------
103  //! \brief Gets the value associated with a particular key
104  /*!
105  \param what the key to lookup
106  \param res a reference used to return the result
107 
108  <B>Notes:</b>
109  - If \c res is a \c std::string, every effort will be made
110  to convert the specified element to a string using the
111  \c boost::lexical_cast machinery.
112  - If the dictionary does not contain the key \c what,
113  a KeyErrorException will be thrown.
114  */
115  template <typename T>
116  void getVal(const std::string &what, T &res) const {
117  res = getVal<T>(what);
118  };
119  //! \overload
120  template <typename T>
121  T getVal(const std::string &what) const {
122  for(size_t i=0; i< _data.size(); ++i) {
123  if (_data[i].key == what) {
124  return from_rdvalue<T>(_data[i].val);
125  }
126  }
127  throw KeyErrorException(what);
128  }
129 
130  //! \overload
131  void getVal(const std::string &what, std::string &res) const;
132 
133  //----------------------------------------------------------
134  //! \brief Potentially gets the value associated with a particular key
135  //! returns true on success/false on failure.
136  /*!
137  \param what the key to lookup
138  \param res a reference used to return the result
139 
140  <B>Notes:</b>
141  - If \c res is a \c std::string, every effort will be made
142  to convert the specified element to a string using the
143  \c boost::lexical_cast machinery.
144  - If the dictionary does not contain the key \c what,
145  a KeyErrorException will be thrown.
146  */
147 
148  template <typename T>
149  bool getValIfPresent(const std::string &what, T &res) const {
150  for(size_t i=0; i< _data.size(); ++i) {
151  if (_data[i].key == what) {
152  res = from_rdvalue<T>(_data[i].val);
153  return true;
154  }
155  }
156  return false;
157  };
158 
159 
160  //! \overload
161  bool getValIfPresent(const std::string &what, std::string &res) const;
162 
163  //----------------------------------------------------------
164  //! \brief Sets the value associated with a key
165  /*!
166 
167  \param what the key to set
168  \param val the value to store
169 
170  <b>Notes:</b>
171  - If \c val is a <tt>const char *</tt>, it will be converted
172  to a \c std::string for storage.
173  - If the dictionary already contains the key \c what,
174  the value will be replaced.
175  */
176  template <typename T>
177  void setVal(const std::string &what, T &val) {
178  _hasNonPodData = true;
179  for(size_t i=0; i< _data.size(); ++i) {
180  if (_data[i].key == what) {
181  RDValue::cleanup_rdvalue(_data[i].val);
182  _data[i].val = val;
183  return;
184  }
185  }
186  _data.push_back(Pair(what, val));
187  };
188 
189  template <typename T>
190  void setPODVal(const std::string &what, T val) {
191  // don't change the hasNonPodData status
192  for(size_t i=0; i< _data.size(); ++i) {
193  if (_data[i].key == what) {
194  RDValue::cleanup_rdvalue(_data[i].val);
195  _data[i].val = val;
196  return;
197  }
198  }
199  _data.push_back(Pair(what, val));
200  };
201 
202  void setVal(const std::string &what, bool val) {
203  setPODVal(what, val);
204  }
205 
206  void setVal(const std::string &what, double val) {
207  setPODVal(what, val);
208  }
209 
210  void setVal(const std::string &what, float val) {
211  setPODVal(what, val);
212  }
213 
214  void setVal(const std::string &what, int val) {
215  setPODVal(what, val);
216  }
217 
218  void setVal(const std::string &what, unsigned int val) {
219  setPODVal(what, val);
220  }
221 
222  //! \overload
223  void setVal(const std::string &what, const char *val) {
224  std::string h(val);
225  setVal(what, h);
226  }
227 
228  //----------------------------------------------------------
229  //! \brief Clears the value associated with a particular key,
230  //! removing the key from the dictionary.
231  /*!
232 
233  \param what the key to clear
234 
235  <b>Notes:</b>
236  - If the dictionary does not contain the key \c what,
237  a KeyErrorException will be thrown.
238  */
239  void clearVal(const std::string &what) {
240  for(DataType::iterator it = _data.begin(); it < _data.end() ; ++it) {
241  if (it->key == what) {
242  if (_hasNonPodData) {
243  RDValue::cleanup_rdvalue(it->val);
244  }
245  _data.erase(it);
246  return;
247  }
248  }
249  throw KeyErrorException(what);
250  };
251 
252  //----------------------------------------------------------
253  //! \brief Clears all keys (and values) from the dictionary.
254  //!
255  void reset() {
256  if (_hasNonPodData) {
257  for (size_t i=0; i< _data.size(); ++i) {
258  RDValue::cleanup_rdvalue(_data[i].val);
259  }
260  }
261  DataType data;
262  _data.swap(data);
263  };
264 
265  //----------------------------------------------------------
266  //! Converts a \c RDAny to type \c T
267  /*!
268  \param arg a \c RDAny reference
269 
270  \returns the converted object of type \c T
271  */
272  /*
273  template <typename T>
274  T fromany(const RDAny &arg) const {
275  return from_rdany<T>(arg);
276  }
277  */
278  //----------------------------------------------------------
279  //! Converts an instance of type \c T to \c RDAny
280  /*!
281  \param arg the object to be converted
282 
283  \returns a \c RDAny instance
284  */
285  /*
286  template <typename T>
287  RDAny toany(T arg) const {
288  return RDAny(arg);
289  };
290  */
291  private:
292  DataType _data; //!< the actual dictionary
293  bool _hasNonPodData; // if true, need a deep copy
294  // (copy_rdvalue)
295 };
296 }
297 #endif
bool hasVal(const std::string &what) const
Returns whether or not the dictionary contains a particular key.
Definition: Dict.h:81
void setVal(const std::string &what, T &val)
Sets the value associated with a key.
Definition: Dict.h:177
void copy_rdvalue(RDValue &dest, const RDValue &src)
T getVal(const std::string &what) const
Definition: Dict.h:121
void setVal(const std::string &what, int val)
Definition: Dict.h:214
STR_VECT keys() const
Returns the set of keys in the dictionary.
Definition: Dict.h:93
Dict()
Definition: Dict.h:45
void setVal(const std::string &what, float val)
Definition: Dict.h:210
void setVal(const std::string &what, bool val)
Definition: Dict.h:202
bool getValIfPresent(const std::string &what, T &res) const
Potentially gets the value associated with a particular key returns true on success/false on failure...
Definition: Dict.h:149
void setVal(const std::string &what, double val)
Definition: Dict.h:206
static void cleanup_rdvalue(RDValue v)
void setVal(const std::string &what, const char *val)
Definition: Dict.h:223
void setVal(const std::string &what, unsigned int val)
Definition: Dict.h:218
void clearVal(const std::string &what)
Clears the value associated with a particular key, removing the key from the dictionary.
Definition: Dict.h:239
void getVal(const std::string &what, T &res) const
Gets the value associated with a particular key.
Definition: Dict.h:116
Dict(const Dict &other)
Definition: Dict.h:47
Includes a bunch of functionality for handling Atom and Bond queries.
Definition: Atom.h:29
Dict & operator=(const Dict &other)
Definition: Dict.h:63
void setPODVal(const std::string &what, T val)
Definition: Dict.h:190
void reset()
Clears all keys (and values) from the dictionary.
Definition: Dict.h:255
~Dict()
Definition: Dict.h:59
The Dict class can be used to store objects of arbitrary type keyed by strings.
Definition: Dict.h:33
std::vector< std::string > STR_VECT
Definition: Dict.h:26
Class to allow us to throw a KeyError from C++ and have it make it back to Python.
Definition: Exceptions.h:48