16#ifndef RD_DICT_H_012020
17#define RD_DICT_H_012020
25#include <boost/lexical_cast.hpp>
43 explicit Pair(std::string s) : key(std::move(s)), val() {}
44 Pair(std::string s,
const RDValue &v) : key(std::move(s)), val(v) {}
47 void cleanup() { RDValue::cleanup_rdvalue(val); }
55 _hasNonPodData = other._hasNonPodData;
56 if (other._hasNonPodData) {
57 std::vector<Pair> data(other._data.size());
59 for (
size_t i = 0; i < _data.size(); ++i) {
60 _data[i].key = other._data[i].key;
72 void update(
const Dict &other,
bool preserveExisting =
false) {
73 if (!preserveExisting) {
76 if (other._hasNonPodData) {
77 _hasNonPodData =
true;
79 for (
const auto &opair : other._data) {
80 Pair *target =
nullptr;
81 for (
auto &dpair : _data) {
82 if (dpair.key == opair.key) {
90 _data.push_back(
Pair(opair.key));
101 if (
this == &other) {
104 if (_hasNonPodData) {
108 if (other._hasNonPodData) {
109 std::vector<Pair> data(other._data.size());
111 for (
size_t i = 0; i < _data.size(); ++i) {
112 _data[i].key = other._data[i].key;
118 _hasNonPodData = other._hasNonPodData;
123 if (
this == &other) {
126 if (_hasNonPodData) {
129 _hasNonPodData = other._hasNonPodData;
130 other._hasNonPodData =
false;
131 _data = std::move(other._data);
149 bool hasVal(
const std::string &what)
const {
150 for (
const auto &data : _data) {
151 if (data.key == what) {
165 res.reserve(_data.size());
166 for (
const auto &item : _data) {
167 res.push_back(item.key);
185 template <
typename T>
186 void getVal(
const std::string &what, T &res)
const {
187 res = getVal<T>(what);
191 template <
typename T>
192 T
getVal(
const std::string &what)
const {
193 for (
auto &data : _data) {
194 if (data.key == what) {
195 return from_rdvalue<T>(data.val);
202 void getVal(
const std::string &what, std::string &res)
const {
203 for (
const auto &i : _data) {
226 template <
typename T>
228 for (
const auto &data : _data) {
229 if (data.key == what) {
230 res = from_rdvalue<T>(data.val);
239 for (
const auto &i : _data) {
261 template <
typename T>
262 void setVal(
const std::string &what, T &val) {
263 static_assert(!std::is_same_v<T, std::string_view>,
264 "T cannot be string_view");
265 _hasNonPodData =
true;
266 for (
auto &&data : _data) {
267 if (data.key == what) {
268 RDValue::cleanup_rdvalue(data.val);
273 _data.push_back(
Pair(what, val));
276 template <
typename T>
278 static_assert(!std::is_same_v<T, std::string_view>,
279 "T cannot be string_view");
281 for (
auto &&data : _data) {
282 if (data.key == what) {
283 RDValue::cleanup_rdvalue(data.val);
288 _data.push_back(
Pair(what, val));
291 void setVal(
const std::string &what,
bool val) { setPODVal(what, val); }
293 void setVal(
const std::string &what,
double val) { setPODVal(what, val); }
295 void setVal(
const std::string &what,
float val) { setPODVal(what, val); }
297 void setVal(
const std::string &what,
int val) { setPODVal(what, val); }
299 void setVal(
const std::string &what,
unsigned int val) {
300 setPODVal(what, val);
304 void setVal(
const std::string &what,
const char *val) {
318 for (DataType::iterator it = _data.begin(); it < _data.end(); ++it) {
319 if (it->key == what) {
320 if (_hasNonPodData) {
321 RDValue::cleanup_rdvalue(it->val);
333 if (_hasNonPodData) {
334 for (
auto &&data : _data) {
335 RDValue::cleanup_rdvalue(data.val);
344 bool _hasNonPodData{
false};
349inline std::string Dict::getVal<std::string>(
const std::string &what)
const {
Class to allow us to throw a KeyError from C++ and have it make it back to Python.
The Dict class can be used to store objects of arbitrary type keyed by strings.
void setVal(const std::string &what, const char *val)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const DataType & getData() const
Access to the underlying data.
T getVal(const std::string &what) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Dict(Dict &&other) noexcept=default
void reset()
Clears all keys (and values) from the dictionary.
void setPODVal(const std::string &what, T val)
Dict & operator=(const Dict &other)
STR_VECT keys() const
Returns the set of keys in the dictionary.
void setVal(const std::string &what, float val)
void setVal(const std::string &what, double val)
bool hasVal(const std::string &what) const
Returns whether or not the dictionary contains a particular key.
void setVal(const std::string &what, bool val)
void setVal(const std::string &what, unsigned int val)
void getVal(const std::string &what, std::string &res) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool & getNonPODStatus()
Access to the underlying non-POD containment flag This is meant to be used only in bulk updates of _d...
std::vector< Pair > DataType
Dict & operator=(Dict &&other) noexcept
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.
void update(const Dict &other, bool preserveExisting=false)
void getVal(const std::string &what, T &res) const
Gets the value associated with a particular key.
bool getValIfPresent(const std::string &what, std::string &res) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setVal(const std::string &what, int val)
void clearVal(const std::string &what)
Clears the value associated with a particular key, removing the key from the dictionary.
void setVal(const std::string &what, T &val)
Sets the value associated with a key.
PairHolder(PairHolder &&p)
PairHolder(Dict::Pair &&p)
PairHolder(const PairHolder &p)
#define RDKIT_RDGENERAL_EXPORT
std::vector< std::string > STR_VECT
bool rdvalue_is(const RDValue_cast_t)
bool rdvalue_tostring(RDValue_cast_t val, std::string &res)
void copy_rdvalue(RDValue &dest, const RDValue &src)
Pair(std::string s, const RDValue &v)
static void cleanup_rdvalue(RDValue v)