RDKit: RDValue-taggedunion.h Source File

| RDKit Open-source cheminformatics and machine learning.

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

RDValue-taggedunion.h
Go to the documentation of this file.
1 // Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following
12 // disclaimer in the documentation and/or other materials provided
13 // with the distribution.
14 // * Neither the name of Novartis Institutes for BioMedical Research Inc.
15 // nor the names of its contributors may be used to endorse or promote
16 // products derived from this software without specific prior written
17 // permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 //
31 #ifndef RDKIT_RDVALUE_TAGGED_UNION_H
32 #define RDKIT_RDVALUE_TAGGED_UNION_H
33
34 #include <cassert>
35 #include "Invariant.h"
36 #include <iostream>
37 #include <iomanip>
38 #include <sstream>
39 #include <vector>
40
41 #include <RDGeneral/BoostStartInclude.h>
42 #include <boost/cstdint.hpp>
43 #include <boost/any.hpp>
44 #include <boost/utility.hpp>
45 #include <boost/lexical_cast.hpp>
46 #include <boost/type_traits/is_floating_point.hpp>
47 #include <RDGeneral/BoostEndInclude.h>
48 #include "LocaleSwitcher.h"
49
50 #define RDVALUE_HASBOOL
51
52 namespace RDKit {
53
54 // RDValue does not dynamically create POD types (kind of like
55 // cdiggins::any) However, it doesn't use RTTI type info
56 // directly, it uses a companion short valued type
57 // to determine what to do.
58 // For unregistered types, it falls back to boost::any.
59 // The Size of an RDAny is (sizeof(double) + sizeof(short) == 10 bytes
60 // (aligned to actually 16 so hard to pass as value type)
61 //
62 // For the sake of compatibility, errors throw boost::bad_any_cast
63 //
64 // Examples:
65 //
66 // RDAny v(2.);
67 // v = 1;
68 // std::vector<double> d;
69 // v == d;
70 // v.asDoubleVect().push_back(4.)
71 // rdany_cast<std::vector<double>(v).push_back(4.)
72 //
73 // Falls back to boost::any for non registered types
74 // v = boost::shared_ptr<ROMol>(new ROMol(m));
75 //
76
77 // RDValue does not manange memory of non-pod data
78 // this must be done externally (string, Any, vector...)
79 // Tagged union
80
81 namespace RDTypeTag {
82 const short EmptyTag = 0;
83 const short IntTag = 1;
84 const short DoubleTag = 2;
85 const short StringTag = 3;
86 const short FloatTag = 4;
87 const short BoolTag = 5;
88 const short UnsignedIntTag = 6;
89 const short AnyTag = 7;
90 const short VecDoubleTag = 8;
91 const short VecFloatTag = 9;
92 const short VecIntTag = 10;
93 const short VecUnsignedIntTag = 11;
94 const short VecStringTag = 12;
95 template <class T>
96 inline short GetTag() {
97 return AnyTag;
98 }
99 template <>
100 inline short GetTag<double>() {
101 return DoubleTag;
102 }
103 template <>
104 inline short GetTag<float>() {
105 return FloatTag;
106 }
107 template <>
108 inline short GetTag<int>() {
109 return IntTag;
110 }
111 template <>
112 inline short GetTag<unsigned int>() {
113 return UnsignedIntTag;
114 }
115 template <>
116 inline short GetTag<bool>() {
117 return BoolTag;
118 }
119 template <>
120 inline short GetTag<std::string>() {
121 return StringTag;
122 }
123 template <>
124 inline short GetTag<std::vector<double> >() {
125 return VecDoubleTag;
126 }
127 template <>
128 inline short GetTag<std::vector<float> >() {
129 return VecFloatTag;
130 }
131 template <>
132 inline short GetTag<std::vector<int> >() {
133 return VecIntTag;
134 }
135 template <>
136 inline short GetTag<std::vector<unsigned int> >() {
137 return VecUnsignedIntTag;
138 }
139 template <>
140 inline short GetTag<std::vector<std::string> >() {
141 return VecStringTag;
142 }
143 template <>
144 inline short GetTag<boost::any>() {
145 return AnyTag;
146 }
147
148 namespace detail {
149 union Value {
150 double d;
151 float f;
152 int i;
153 unsigned u;
154 bool b;
155 std::string *s;
156 boost::any *a;
157 std::vector<double> *vd;
158 std::vector<float> *vf;
159 std::vector<int> *vi;
160 std::vector<unsigned int> *vu;
161 std::vector<std::string> *vs;
162
163 inline Value() {}
164 inline Value(double v) : d(v) {}
165 inline Value(float v) : f(v) {}
166 inline Value(int v) : i(v) {}
167 inline Value(unsigned int v) : u(v) {}
168 inline Value(bool v) : b(v) {}
169 inline Value(std::string *v) : s(v) {}
170 inline Value(boost::any *v) : a(v) {}
171 inline Value(std::vector<double> *v) : vd(v) {}
172 inline Value(std::vector<float> *v) : vf(v) {}
173 inline Value(std::vector<int> *v) : vi(v) {}
174 inline Value(std::vector<unsigned int> *v) : vu(v) {}
175 inline Value(std::vector<std::string> *v) : vs(v) {}
176 };
177
178 template <class T>
179 inline T *valuePtrCast(Value value) {
180 return boost::any_cast<T *>(*value.a);
181 }
182 template <>
183 inline boost::any *valuePtrCast<boost::any>(Value value) {
184 return value.a;
185 }
186
187 template <>
188 inline std::string *valuePtrCast<std::string>(Value value) {
189 return value.s;
190 }
191 template <>
192 inline std::vector<double> *valuePtrCast<std::vector<double> >(Value value) {
193 return value.vd;
194 }
195 template <>
196 inline std::vector<float> *valuePtrCast<std::vector<float> >(Value value) {
197 return value.vf;
198 }
199 template <>
200 inline std::vector<int> *valuePtrCast<std::vector<int> >(Value value) {
201 return value.vi;
202 }
203 template <>
204 inline std::vector<unsigned int> *valuePtrCast<std::vector<unsigned int> >(
205 Value value) {
206 return value.vu;
207 }
208 template <>
209 inline std::vector<std::string> *valuePtrCast<std::vector<std::string> >(
210 Value value) {
211 return value.vs;
212 }
213 }
214 }
215
216 struct RDValue {
217 RDTypeTag::detail::Value value;
218 short type;
219 short reserved_tag; // 16 bit alignment
220
221 inline RDValue() : value(0.0), type(RDTypeTag::EmptyTag) {}
222 // Pod Style (Direct storage)
223 inline RDValue(double v) : value(v), type(RDTypeTag::DoubleTag) {}
224 inline RDValue(float v) : value(v), type(RDTypeTag::FloatTag) {}
225 inline RDValue(int v) : value(v), type(RDTypeTag::IntTag) {}
226 inline RDValue(unsigned v) : value(v), type(RDTypeTag::UnsignedIntTag) {}
227 inline RDValue(bool v) : value(v), type(RDTypeTag::BoolTag) {}
228
229 inline RDValue(boost::any *v) : value(v), type(RDTypeTag::AnyTag) {}
230
231 // Copies passed in pointers
232 inline RDValue(const boost::any &v)
233 : value(new boost::any(v)), type(RDTypeTag::AnyTag) {}
234 inline RDValue(const std::string &v)
235 : value(new std::string(v)), type(RDTypeTag::StringTag){};
236 template <class T>
237 inline RDValue(const T &v)
238 : value(new boost::any(v)), type(RDTypeTag::AnyTag) {}
239
240 inline RDValue(const std::vector<double> &v)
241 : value(new std::vector<double>(v)), type(RDTypeTag::VecDoubleTag) {}
242 inline RDValue(const std::vector<float> &v)
243 : value(new std::vector<float>(v)), type(RDTypeTag::VecFloatTag) {}
244 inline RDValue(const std::vector<int> &v)
245 : value(new std::vector<int>(v)), type(RDTypeTag::VecIntTag) {}
246 inline RDValue(const std::vector<unsigned int> &v)
247 : value(new std::vector<unsigned int>(v)),
248 type(RDTypeTag::VecUnsignedIntTag) {}
249 inline RDValue(const std::vector<std::string> &v)
250 : value(new std::vector<std::string>(v)), type(RDTypeTag::VecStringTag) {}
251
252 short getTag() const { return type; }
253
254 // ptrCast - unsafe, use rdvalue_cast instead.
255 template <class T>
256 inline T *ptrCast() const {
257 return RDTypeTag::detail::valuePtrCast<T>(value);
258 }
259
260 // RDValue doesn't have an explicit destructor, it must
261 // be wrapped in a container.
262 // The idea is that POD types don't need to be destroyed
263 // and this allows the container optimization possibilities.
264 void destroy() {
265 switch (type) {
266 case RDTypeTag::StringTag:
267 delete value.s;
268 break;
269 case RDTypeTag::AnyTag:
270 delete value.a;
271 break;
272 case RDTypeTag::VecDoubleTag:
273 delete value.vd;
274 break;
275 case RDTypeTag::VecFloatTag:
276 delete value.vf;
277 break;
278 case RDTypeTag::VecIntTag:
279 delete value.vi;
280 break;
281 case RDTypeTag::VecUnsignedIntTag:
282 delete value.vu;
283 break;
284 case RDTypeTag::VecStringTag:
285 delete value.vs;
286 break;
287 default:
288 break;
289 }
290 type = RDTypeTag::EmptyTag;
291 }
292
293 static // Given a type and an RDAnyValue - delete the appropriate structure
294 inline void
295 cleanup_rdvalue(RDValue &rdvalue) {
296 rdvalue.destroy();
297 }
298 };
299
300 /////////////////////////////////////////////////////////////////////////////////////
301 // Given two RDValue::Values - copy the appropriate structure
302 // RDValue doesn't have a copy constructor, the default
303 // copy act's like a move for better value semantics.
304 // Containers may need to copy though.
305 inline void copy_rdvalue(RDValue &dest, const RDValue &src) {
306 if (&dest == &src) // don't copy over yourself
307 return;
308 dest.destroy();
309 dest.type = src.type;
310 switch (src.type) {
311 case RDTypeTag::StringTag:
312 dest.value.s = new std::string(*src.value.s);
313 break;
314 case RDTypeTag::AnyTag:
315 dest.value.a = new boost::any(*src.value.a);
316 break;
317 case RDTypeTag::VecDoubleTag:
318 dest.value.vd = new std::vector<double>(*src.value.vd);
319 break;
320 case RDTypeTag::VecFloatTag:
321 dest.value.vf = new std::vector<float>(*src.value.vf);
322 break;
323 case RDTypeTag::VecIntTag:
324 dest.value.vi = new std::vector<int>(*src.value.vi);
325 break;
326 case RDTypeTag::VecUnsignedIntTag:
327 dest.value.vu = new std::vector<unsigned int>(*src.value.vu);
328 break;
329 case RDTypeTag::VecStringTag:
330 dest.value.vs = new std::vector<std::string>(*src.value.vs);
331 break;
332 default:
333 dest = src;
334 }
335 }
336
337 /////////////////////////////////////////////////////////////////////////////////////
338 // rdvalue_is<T>
339
340 template <class T>
341 inline bool rdvalue_is(RDValue v) {
342 return v.getTag() ==
343 RDTypeTag::GetTag<typename boost::remove_reference<T>::type>();
344 }
345
346 /////////////////////////////////////////////////////////////////////////////////////
347 // rdvalue_cast<T>
348 //
349 // POD types do not support reference semantics. Other types do.
350 // rdvalue_cast<const std::vector<double> &>(RDValue); // ok
351 // rdvalue_cast<const float &>(RDValue); // bad_any_cast
352
353 #ifdef RDK_32BIT_BUILD
354 // avoid register pressure and spilling on 32 bit systems
355 typedef const RDValue &RDValue_cast_t;
356 #else
357 typedef RDValue RDValue_cast_t;
358 #endif
359
360 // Get stuff stored in boost any
361 template <class T>
362 inline T rdvalue_cast(RDValue_cast_t v) {
363 // Disable reference and pointer casts to POD data.
364 BOOST_STATIC_ASSERT(!(
365 (boost::is_pointer<T>::value &&
366 (boost::is_integral<typename boost::remove_pointer<T>::type>::value ||
367 boost::is_floating_point<
368 typename boost::remove_pointer<T>::type>::value)) ||
369 (boost::is_reference<T>::value &&
370 (boost::is_integral<typename boost::remove_reference<T>::type>::value ||
371 boost::is_floating_point<
372 typename boost::remove_reference<T>::type>::value))));
373
374 if (rdvalue_is<boost::any>(v)) {
375 return boost::any_cast<T>(*v.ptrCast<boost::any>());
376 }
377 throw boost::bad_any_cast();
378 }
379
380 // POD casts
381 template <>
382 inline double rdvalue_cast<double>(RDValue_cast_t v) {
383 if (rdvalue_is<double>(v)) return v.value.d;
384 throw boost::bad_any_cast();
385 }
386
387 template <>
388 inline float rdvalue_cast<float>(RDValue_cast_t v) {
389 if (rdvalue_is<float>(v)) return v.value.f;
390 throw boost::bad_any_cast();
391 }
392
393 template <>
394 inline int rdvalue_cast<int>(RDValue_cast_t v) {
395 if (rdvalue_is<int>(v)) return v.value.i;
396 throw boost::bad_any_cast();
397 }
398 template <>
399 inline unsigned int rdvalue_cast<unsigned int>(RDValue_cast_t v) {
400 if (rdvalue_is<unsigned int>(v)) return v.value.u;
401 throw boost::bad_any_cast();
402 }
403
404 template <>
405 inline bool rdvalue_cast<bool>(RDValue_cast_t v) {
406 if (rdvalue_is<bool>(v)) return v.value.b;
407 throw boost::bad_any_cast();
408 }
409
410 } // namespace rdkit
411 #endif
RDKit::rdvalue_is< double >
bool rdvalue_is< double >(RDValue v)
Definition: RDValue-doublemagic.h:328
RDKit::RDTypeTag::detail::Value::i
int i
Definition: RDValue-taggedunion.h:152
RDKit::RDValue::RDValue
RDValue(const std::vector< unsigned int > &v)
Definition: RDValue-taggedunion.h:246
RDKit::RDValue::RDValue
RDValue(float v)
Definition: RDValue-taggedunion.h:224
RDKit::RDTypeTag::GetTag< float >
boost::uint64_t GetTag< float >()
Definition: RDValue-doublemagic.h:116
BoostStartInclude.h
RDKit::RDTypeTag::detail::Value::Value
Value(bool v)
Definition: RDValue-taggedunion.h:168
RDKit::RDTypeTag::detail::Value::Value
Value(boost::any *v)
Definition: RDValue-taggedunion.h:170
RDKit::RDTypeTag::detail::Value::a
boost::any * a
Definition: RDValue-taggedunion.h:156
boost
Definition: RDLog.h:20
RDKit::copy_rdvalue
void copy_rdvalue(RDValue &dest, const RDValue &src)
Definition: RDValue-doublemagic.h:289
RDKit::RDTypeTag::detail::Value::f
float f
Definition: RDValue-taggedunion.h:151
RDKit::RDTypeTag::detail::Value::Value
Value(unsigned int v)
Definition: RDValue-taggedunion.h:167
RDKit::RDValue::reserved_tag
short reserved_tag
Definition: RDValue-taggedunion.h:219
RDKit::RDValue::RDValue
RDValue(unsigned v)
Definition: RDValue-taggedunion.h:226
RDKit::RDTypeTag::VecDoubleTag
static const boost::uint64_t VecDoubleTag
Definition: RDValue-doublemagic.h:104
RDKit::RDTypeTag::GetTag< int >
boost::uint64_t GetTag< int >()
Definition: RDValue-doublemagic.h:117
RDKit::RDTypeTag::UnsignedIntTag
static const boost::uint64_t UnsignedIntTag
Definition: RDValue-doublemagic.h:98
Invariant.h
RDKit::RDValue
Definition: RDValue-doublemagic.h:130
RDKit::rdvalue_cast
T rdvalue_cast(RDValue v)
Definition: RDValue-doublemagic.h:362
RDKit::RDTypeTag::AnyTag
static const boost::uint64_t AnyTag
Definition: RDValue-doublemagic.h:109
RDKit::RDTypeTag::detail::Value::vi
std::vector< int > * vi
Definition: RDValue-taggedunion.h:159
RDKit::RDTypeTag::detail::Value::s
std::string * s
Definition: RDValue-taggedunion.h:155
RDKit::RDTypeTag::DoubleTag
static const boost::uint64_t DoubleTag
Definition: RDValue-doublemagic.h:95
std
STL namespace.
RDKit::RDValue::RDValue
RDValue()
Definition: RDValue-taggedunion.h:221
RDKit::RDValue::RDValue
RDValue(const std::vector< float > &v)
Definition: RDValue-taggedunion.h:242
RDKit::RDTypeTag::detail::Value::Value
Value(std::vector< int > *v)
Definition: RDValue-taggedunion.h:173
RDKit::RDTypeTag::FloatTag
static const boost::uint64_t FloatTag
Definition: RDValue-doublemagic.h:96
RDKit::RDValue::RDValue
RDValue(int v)
Definition: RDValue-taggedunion.h:225
RDKit::RDValue::destroy
void destroy()
Definition: RDValue-taggedunion.h:264
RDKit::RDTypeTag::detail::Value::vu
std::vector< unsigned int > * vu
Definition: RDValue-taggedunion.h:160
RDKit::RDValue::ptrCast
T * ptrCast() const
Definition: RDValue-taggedunion.h:256
RDKit::RDValue::RDValue
RDValue(const T &v)
Definition: RDValue-taggedunion.h:237
RDKit::RDTypeTag::StringTag
static const boost::uint64_t StringTag
Definition: RDValue-doublemagic.h:103
RDKit::rdvalue_is
bool rdvalue_is(RDValue v)
Definition: RDValue-doublemagic.h:323
RDKit::RDValue::RDValue
RDValue(const std::vector< std::string > &v)
Definition: RDValue-taggedunion.h:249
BoostEndInclude.h
RDKit::RDValue::cleanup_rdvalue
static void cleanup_rdvalue(RDValue &rdvalue)
Definition: RDValue-taggedunion.h:295
RDKit::RDTypeTag::detail::Value::vf
std::vector< float > * vf
Definition: RDValue-taggedunion.h:158
RDKit::RDTypeTag::VecIntTag
static const boost::uint64_t VecIntTag
Definition: RDValue-doublemagic.h:106
RDKit::RDTypeTag::VecUnsignedIntTag
static const boost::uint64_t VecUnsignedIntTag
Definition: RDValue-doublemagic.h:107
RDKit::RDValue::type
short type
Definition: RDValue-taggedunion.h:218
RDKit::RDTypeTag::detail::valuePtrCast
T * valuePtrCast(Value value)
Definition: RDValue-taggedunion.h:179
LocaleSwitcher.h
RDKit::RDValue::RDValue
RDValue(bool v)
Definition: RDValue-taggedunion.h:227
RDKit::RDValue::getTag
short getTag() const
Definition: RDValue-taggedunion.h:252
RDKit::RDTypeTag::detail::Value::b
bool b
Definition: RDValue-taggedunion.h:154
RDKit::RDTypeTag::detail::Value::Value
Value(float v)
Definition: RDValue-taggedunion.h:165
RDKit
Std stuff.
Definition: Atom.h:29
RDKit::RDTypeTag::detail::Value::d
double d
Definition: RDValue-taggedunion.h:150
RDKit::RDTypeTag::VecStringTag
static const boost::uint64_t VecStringTag
Definition: RDValue-doublemagic.h:108
RDKit::RDTypeTag::EmptyTag
const short EmptyTag
Definition: RDValue-taggedunion.h:82
RDKit::RDTypeTag::GetTag
boost::uint64_t GetTag()
Definition: RDValue-doublemagic.h:113
RDKit::RDTypeTag::detail::Value::Value
Value(std::vector< float > *v)
Definition: RDValue-taggedunion.h:172
RDKit::RDTypeTag::detail::Value::Value
Value(int v)
Definition: RDValue-taggedunion.h:166
RDKit::RDTypeTag::IntTag
static const boost::uint64_t IntTag
Definition: RDValue-doublemagic.h:97
RDKit::RDTypeTag::detail::Value
Definition: RDValue-taggedunion.h:149
RDKit::RDTypeTag::detail::Value::Value
Value(std::vector< std::string > *v)
Definition: RDValue-taggedunion.h:175
RDKit::RDValue::RDValue
RDValue(const boost::any &v)
Definition: RDValue-taggedunion.h:232
RDKit::RDTypeTag::GetTag< unsigned int >
boost::uint64_t GetTag< unsigned int >()
Definition: RDValue-doublemagic.h:118
RDKit::RDTypeTag::detail::Value::Value
Value(std::vector< unsigned int > *v)
Definition: RDValue-taggedunion.h:174
RDKit::RDValue_cast_t
RDValue RDValue_cast_t
Definition: RDValue-doublemagic.h:359
RDKit::RDValue::RDValue
RDValue(double v)
Definition: RDValue-taggedunion.h:223
RDKit::RDTypeTag::detail::Value::Value
Value()
Definition: RDValue-taggedunion.h:163
RDKit::RDTypeTag::detail::Value::Value
Value(std::vector< double > *v)
Definition: RDValue-taggedunion.h:171
RDKit::RDTypeTag::BoolTag
static const boost::uint64_t BoolTag
Definition: RDValue-doublemagic.h:99
RDKit::RDTypeTag::detail::Value::Value
Value(double v)
Definition: RDValue-taggedunion.h:164
RDKit::RDTypeTag::VecFloatTag
static const boost::uint64_t VecFloatTag
Definition: RDValue-doublemagic.h:105
RDKit::RDValue::getTag
boost::uint64_t getTag() const
Definition: RDValue-doublemagic.h:229
RDKit::RDValue::RDValue
RDValue(const std::vector< double > &v)
Definition: RDValue-taggedunion.h:240
RDKit::RDTypeTag::detail::Value::Value
Value(std::string *v)
Definition: RDValue-taggedunion.h:169
RDKit::RDTypeTag::GetTag< double >
boost::uint64_t GetTag< double >()
Definition: RDValue-doublemagic.h:115
RDKit::RDValue::RDValue
RDValue(boost::any *v)
Definition: RDValue-taggedunion.h:229
RDKit::RDTypeTag::detail::Value::vs
std::vector< std::string > * vs
Definition: RDValue-taggedunion.h:161
RDKit::RDValue::value
RDTypeTag::detail::Value value
Definition: RDValue-taggedunion.h:217
RDKit::RDTypeTag::GetTag< bool >
boost::uint64_t GetTag< bool >()
Definition: RDValue-doublemagic.h:119
RDKit::RDTypeTag::detail::Value::vd
std::vector< double > * vd
Definition: RDValue-taggedunion.h:157
RDKit::RDTypeTag::detail::Value::u
unsigned u
Definition: RDValue-taggedunion.h:153
RDKit::RDValue::RDValue
RDValue(const std::vector< int > &v)
Definition: RDValue-taggedunion.h:244
RDKit::RDValue::RDValue
RDValue(const std::string &v)
Definition: RDValue-taggedunion.h:234