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