RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
RDValue.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#include <RDGeneral/export.h>
32#ifndef RDKIT_RDVALUE_H
33#define RDKIT_RDVALUE_H
34
35// #define UNSAFE_RDVALUE
36#ifdef UNSAFE_RDVALUE
37#include "RDValue-doublemagic.h"
38#else
39#include "RDValue-taggedunion.h"
40#endif
41
42namespace RDKit {
43// Common Casts (POD Casts are implementation dependent)
44// string casts
45template <>
48 return *v.ptrCast<std::string>();
49 }
50 throw std::bad_any_cast();
51}
52
53template <>
56 return *v.ptrCast<std::string>();
57 }
58 throw std::bad_any_cast();
59}
60
61// Special Vecor Casts
62template <>
63inline std::vector<double> rdvalue_cast<std::vector<double>>(RDValue_cast_t v) {
64 if (rdvalue_is<std::vector<double>>(v)) {
65 return *v.ptrCast<std::vector<double>>();
66 }
67 throw std::bad_any_cast();
68}
69
70template <>
71inline std::vector<double> &rdvalue_cast<std::vector<double> &>(
73 if (rdvalue_is<std::vector<double>>(v)) {
74 return *v.ptrCast<std::vector<double>>();
75 }
76 throw std::bad_any_cast();
77}
78
79template <>
80inline std::vector<float> rdvalue_cast<std::vector<float>>(RDValue_cast_t v) {
81 if (rdvalue_is<std::vector<float>>(v)) {
82 return *v.ptrCast<std::vector<float>>();
83 }
84 throw std::bad_any_cast();
85}
86
87template <>
88inline std::vector<float> &rdvalue_cast<std::vector<float> &>(
90 if (rdvalue_is<std::vector<float>>(v)) {
91 return *v.ptrCast<std::vector<float>>();
92 }
93 throw std::bad_any_cast();
94}
95
96template <>
97inline std::vector<std::string> rdvalue_cast<std::vector<std::string>>(
99 if (rdvalue_is<std::vector<std::string>>(v)) {
100 return *v.ptrCast<std::vector<std::string>>();
101 }
102 throw std::bad_any_cast();
103}
104
105template <>
106inline std::vector<std::string> &rdvalue_cast<std::vector<std::string> &>(
107 RDValue_cast_t v) {
108 if (rdvalue_is<std::vector<std::string>>(v)) {
109 return *v.ptrCast<std::vector<std::string>>();
110 }
111 throw std::bad_any_cast();
112}
113
114template <>
115inline std::vector<int> rdvalue_cast<std::vector<int>>(RDValue_cast_t v) {
116 if (rdvalue_is<std::vector<int>>(v)) {
117 return *v.ptrCast<std::vector<int>>();
118 }
119 throw std::bad_any_cast();
120}
121
122template <>
123inline std::vector<int> &rdvalue_cast<std::vector<int> &>(RDValue_cast_t v) {
124 if (rdvalue_is<std::vector<int>>(v)) {
125 return *v.ptrCast<std::vector<int>>();
126 }
127 throw std::bad_any_cast();
128}
129
130template <>
131inline std::vector<unsigned int> rdvalue_cast<std::vector<unsigned int>>(
132 RDValue_cast_t v) {
133 if (rdvalue_is<std::vector<unsigned int>>(v)) {
134 return *v.ptrCast<std::vector<unsigned int>>();
135 }
136 throw std::bad_any_cast();
137}
138
139template <>
140inline std::vector<unsigned int> &rdvalue_cast<std::vector<unsigned int> &>(
141 RDValue_cast_t v) {
142 if (rdvalue_is<std::vector<unsigned int>>(v)) {
143 return *v.ptrCast<std::vector<unsigned int>>();
144 }
145 throw std::bad_any_cast();
146}
147
148// Get boost any
149template <>
151 if (rdvalue_is<std::any>(v)) {
152 return *v.ptrCast<std::any>();
153 }
154 throw std::bad_any_cast();
155}
156
157template <>
159 if (rdvalue_is<std::any>(v)) {
160 return *v.ptrCast<std::any>();
161 }
162 throw std::bad_any_cast();
163}
164
165template <>
167 if (rdvalue_is<std::any>(v)) {
168 return *v.ptrCast<std::any>();
169 }
170 throw std::bad_any_cast();
171}
172
173/////////////////////////////////////////////////////////////////////////////////////
174// lexical casts...
175template <class T>
176std::string vectToString(RDValue val) {
177 const std::vector<T> &tv = rdvalue_cast<std::vector<T> &>(val);
178 std::ostringstream sstr;
179 sstr.imbue(std::locale("C"));
180 sstr << std::setprecision(17);
181 sstr << "[";
182 if (!tv.empty()) {
183 std::copy(tv.begin(), tv.end() - 1, std::ostream_iterator<T>(sstr, ","));
184 sstr << tv.back();
185 }
186 sstr << "]";
187 return sstr.str();
188}
189
190inline bool rdvalue_tostring(RDValue_cast_t val, std::string &res) {
191 switch (val.getTag()) {
194 break;
196 res = boost::lexical_cast<std::string>(rdvalue_cast<int>(val));
197 break;
199 Utils::LocaleSwitcher ls; // for lexical cast...
200 res = boost::lexical_cast<std::string>(rdvalue_cast<double>(val));
201 break;
202 }
204 res = boost::lexical_cast<std::string>(rdvalue_cast<unsigned int>(val));
205 break;
206#ifdef RDVALUE_HASBOOL
208 res = boost::lexical_cast<std::string>(rdvalue_cast<bool>(val));
209 break;
210#endif
211 case RDTypeTag::FloatTag: {
212 Utils::LocaleSwitcher ls; // for lexical cast...
213 res = boost::lexical_cast<std::string>(rdvalue_cast<float>(val));
214 break;
215 }
217 // vectToString uses std::imbue for locale
219 break;
220 }
222 // vectToString uses std::imbue for locale
224 break;
225 }
227 res = vectToString<int>(val);
228 break;
231 break;
234 break;
235 case RDTypeTag::AnyTag: {
236 Utils::LocaleSwitcher ls; // for lexical cast...
237 try {
238 res = std::any_cast<std::string>(rdvalue_cast<std::any &>(val));
239 } catch (const std::bad_any_cast &) {
240 auto &rdtype = rdvalue_cast<std::any &>(val).type();
241 if (rdtype == typeid(long)) {
242 res = boost::lexical_cast<std::string>(
243 std::any_cast<long>(rdvalue_cast<std::any &>(val)));
244 } else if (rdtype == typeid(int64_t)) {
245 res = boost::lexical_cast<std::string>(
246 std::any_cast<int64_t>(rdvalue_cast<std::any &>(val)));
247 } else if (rdtype == typeid(uint64_t)) {
248 res = boost::lexical_cast<std::string>(
249 std::any_cast<uint64_t>(rdvalue_cast<std::any &>(val)));
250 } else if (rdtype == typeid(unsigned long)) {
251 res = boost::lexical_cast<std::string>(
252 std::any_cast<unsigned long>(rdvalue_cast<std::any &>(val)));
253 } else {
254 throw;
255 return false;
256 }
257 }
258 break;
259 }
260 default:
261 res = "";
262 }
263 return true;
264}
265
266// from_rdvalue -> converts string values to appropriate types
267template <class T>
268typename boost::enable_if<boost::is_arithmetic<T>, T>::type from_rdvalue(
270 T res;
271 if (arg.getTag() == RDTypeTag::StringTag) {
273 try {
275 } catch (const std::bad_any_cast &exc) {
276 try {
277 res = boost::lexical_cast<T>(rdvalue_cast<std::string>(arg));
278 } catch (...) {
279 throw exc;
280 }
281 }
282 } else {
284 }
285 return res;
286}
287
288template <class T>
289typename boost::disable_if<boost::is_arithmetic<T>, T>::type from_rdvalue(
291 return rdvalue_cast<T>(arg);
292}
293} // namespace RDKit
294#endif
static const boost::uint64_t UnsignedIntTag
static const boost::uint64_t StringTag
static const boost::uint64_t VecStringTag
static const boost::uint64_t VecIntTag
static const boost::uint64_t FloatTag
static const boost::uint64_t VecUnsignedIntTag
static const boost::uint64_t DoubleTag
static const boost::uint64_t IntTag
static const boost::uint64_t AnyTag
static const boost::uint64_t VecFloatTag
static const boost::uint64_t VecDoubleTag
static const boost::uint64_t BoolTag
Std stuff.
int rdvalue_cast< int >(RDValue_cast_t v)
unsigned int rdvalue_cast< unsigned int >(RDValue_cast_t v)
std::string rdvalue_cast< std::string >(RDValue_cast_t v)
Definition RDValue.h:46
bool rdvalue_is(const RDValue_cast_t)
std::string vectToString(RDValue val)
Definition RDValue.h:176
std::any rdvalue_cast< std::any >(RDValue_cast_t v)
Definition RDValue.h:150
double rdvalue_cast< double >(RDValue_cast_t v)
bool rdvalue_tostring(RDValue_cast_t val, std::string &res)
Definition RDValue.h:190
const std::any & rdvalue_cast< const std::any & >(RDValue_cast_t v)
Definition RDValue.h:166
std::any & rdvalue_cast< std::any & >(RDValue_cast_t v)
Definition RDValue.h:158
std::string & rdvalue_cast< std::string & >(RDValue_cast_t v)
Definition RDValue.h:54
RDValue RDValue_cast_t
bool rdvalue_cast< bool >(RDValue_cast_t v)
float rdvalue_cast< float >(RDValue_cast_t v)
boost::enable_if< boost::is_arithmetic< T >, T >::type from_rdvalue(RDValue_cast_t arg)
Definition RDValue.h:268
bool rdvalue_is< std::any >(RDValue_cast_t v)
boost::uint64_t getTag() const