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 explicit Pair(std::string_view s) :
key(std::string(s)),
val() {}
57 _hasNonPodData = other._hasNonPodData;
58 if (other._hasNonPodData) {
59 std::vector<Pair> data(other._data.size());
61 for (size_t i = 0; i < _data.size(); ++i) {
62 _data[i].key = other._data[i].key;
63 copy_rdvalue(_data[i].val, other._data[i].val);
74 void update(
const Dict &other,
bool preserveExisting =
false) {
75 if (!preserveExisting) {
78 if (other._hasNonPodData) {
79 _hasNonPodData =
true;
81 for (
const auto &opair : other._data) {
82 Pair *target =
nullptr;
83 for (
auto &dpair : _data) {
84 if (dpair.key == opair.key) {
92 _data.push_back(
Pair(opair.key));
103 if (
this == &other) {
106 if (_hasNonPodData) {
110 if (other._hasNonPodData) {
111 std::vector<Pair> data(other._data.size());
113 for (
size_t i = 0; i < _data.size(); ++i) {
114 _data[i].key = other._data[i].key;
120 _hasNonPodData = other._hasNonPodData;
125 if (
this == &other) {
128 if (_hasNonPodData) {
131 _hasNonPodData = other._hasNonPodData;
132 other._hasNonPodData =
false;
133 _data = std::move(other._data);
139 std::size_t
size()
const {
return _data.size(); }
142 bool empty()
const {
return _data.empty(); }
150 _hasNonPodData |= pair.val.needsCleanup();
151 _data.push_back(std::move(pair));
156 for (
auto &p : pairs) {
157 _hasNonPodData |= p.val.needsCleanup();
159 _data.insert(_data.end(), std::make_move_iterator(pairs.begin()),
160 std::make_move_iterator(pairs.end()));
166 for (
const auto &data : _data) {
167 if (data.key == what) {
178 bool hasVal(
const std::string_view what)
const {
179 for (
const auto &data : _data) {
180 if (data.key == what) {
194 res.reserve(_data.size());
195 for (
const auto &item : _data) {
196 res.push_back(item.key);
214 template <
typename T>
215 void getVal(
const std::string_view what, T &res)
const {
220 template <
typename T>
221 T
getVal(
const std::string_view what)
const {
222 for (
auto &data : _data) {
223 if (data.key == what) {
231 void getVal(
const std::string_view what, std::string &res)
const {
232 for (
const auto &i : _data) {
255 template <
typename T>
257 for (
const auto &data : _data) {
258 if (data.key == what) {
268 for (
const auto &i : _data) {
290 template <
typename T>
291 void setVal(
const std::string_view what, T &val) {
292 static_assert(!std::is_same_v<T, std::string_view>,
293 "T cannot be string_view");
297 _hasNonPodData =
true;
298 for (
auto &&data : _data) {
299 if (data.key == what) {
305 _data.push_back(
Pair(what, val));
308 template <
typename T>
310 static_assert(!std::is_same_v<T, std::string_view>,
311 "T cannot be string_view");
316 for (
auto &&data : _data) {
317 if (data.key == what) {
323 _data.push_back(
Pair(what, val));
326 void setVal(
const std::string_view what,
bool val) {
333 void setVal(
const std::string_view what,
double val) {
340 void setVal(
const std::string_view what,
float val) {
346 void setVal(
const std::string_view what,
int val) {
353 void setVal(
const std::string_view what,
unsigned int val) {
361 void setVal(
const std::string_view what,
const char *val) {
378 for (
auto it = _data.begin(); it < _data.end(); ++it) {
379 if (it->key == what) {
380 if (_hasNonPodData) {
393 if (_hasNonPodData) {
394 for (
auto &&data : _data) {
404 bool _hasNonPodData{
false};
410 const std::string_view what)
const {
Class to allow us to throw a KeyError from C++ and have it make it back to Python.
void setVal(const std::string_view what, float val)
void setVal(const std::string_view what, int val)
DataType::const_iterator const_iterator
Dict(Dict &&other) noexcept=default
T getVal(const std::string_view what) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void extend(std::vector< Pair > &&pairs)
Bulk-appends a vector of Pairs, moving them into the dictionary.
void setPODVal(const std::string_view what, T val)
void reset()
Clears all keys (and values) from the dictionary.
Dict & operator=(const Dict &other)
STR_VECT keys() const
Returns the set of keys in the dictionary.
void insert(Pair &&pair)
Appends a populated Pair to the dictionary.
const_iterator end() const
void setVal(const std::string_view what, T &val)
Sets the value associated with a key.
bool hasVal(const std::string_view what) const
Returns whether or not the dictionary contains a particular key.
bool getValIfPresent(const std::string_view what, std::string &res) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const_iterator begin() const
void clearVal(const std::string_view what)
Clears the value associated with a particular key, removing the key from the dictionary.
void setVal(const std::string_view what, const char *val)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const RDValue & getRDValue(const std::string_view what) const
Returns a const reference to the RDValue for a key. Throws KeyErrorException if the key is not found.
void setVal(const std::string_view what, bool val)
void getVal(const std::string_view what, std::string &res) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< Pair > DataType
void setVal(const std::string_view what, double val)
Dict & operator=(Dict &&other) noexcept
void update(const Dict &other, bool preserveExisting=false)
void setVal(const std::string_view what, unsigned int val)
void getVal(const std::string_view what, T &res) const
Gets the value associated with a particular key.
bool empty() const
Returns whether the dictionary is empty.
bool getValIfPresent(const std::string_view what, T &res) const
Potentially gets the value associated with a particular key returns true on success/false on failure.
std::size_t size() const
Returns the number of entries in the dictionary.
PairHolder(PairHolder &&p)
PairHolder(Dict::Pair &&p)
PairHolder(const PairHolder &p)
Class to allow us to throw a ValueError from C++ and have it make it back to Python.
#define RDKIT_RDGENERAL_EXPORT
std::vector< std::string > STR_VECT
bool rdvalue_tostring(RDValue_cast_t val, std::string &res)
void copy_rdvalue(RDValue &dest, const RDValue &src)
boost::enable_if< boost::is_arithmetic< T >, T >::type from_rdvalue(RDValue_cast_t arg)
Pair(std::string s, const RDValue &v)
Pair(std::string_view s, const RDValue &v)
static void cleanup_rdvalue(RDValue v)