RDKit: Dict.h Source File

| RDKit Open-source cheminformatics and machine learning.

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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