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 std::copy(tv.begin(), tv.end(), std::ostream_iterator<T>(sstr, ","));
183 sstr << "]";
184 return sstr.str();
185}
186
187inline bool rdvalue_tostring(RDValue_cast_t val, std::string &res) {
188 switch (val.getTag()) {
191 break;
193 res = boost::lexical_cast<std::string>(rdvalue_cast<int>(val));
194 break;
196 Utils::LocaleSwitcher ls; // for lexical cast...
197 res = boost::lexical_cast<std::string>(rdvalue_cast<double>(val));
198 break;
199 }
201 res = boost::lexical_cast<std::string>(rdvalue_cast<unsigned int>(val));
202 break;
203#ifdef RDVALUE_HASBOOL
205 res = boost::lexical_cast<std::string>(rdvalue_cast<bool>(val));
206 break;
207#endif
208 case RDTypeTag::FloatTag: {
209 Utils::LocaleSwitcher ls; // for lexical cast...
210 res = boost::lexical_cast<std::string>(rdvalue_cast<float>(val));
211 break;
212 }
214 // vectToString uses std::imbue for locale
216 break;
217 }
219 // vectToString uses std::imbue for locale
221 break;
222 }
224 res = vectToString<int>(val);
225 break;
228 break;
231 break;
232 case RDTypeTag::AnyTag: {
233 Utils::LocaleSwitcher ls; // for lexical cast...
234 try {
235 res = std::any_cast<std::string>(rdvalue_cast<std::any &>(val));
236 } catch (const std::bad_any_cast &) {
237 auto &rdtype = rdvalue_cast<std::any &>(val).type();
238 if (rdtype == typeid(long)) {
239 res = boost::lexical_cast<std::string>(
240 std::any_cast<long>(rdvalue_cast<std::any &>(val)));
241 } else if (rdtype == typeid(int64_t)) {
242 res = boost::lexical_cast<std::string>(
243 std::any_cast<int64_t>(rdvalue_cast<std::any &>(val)));
244 } else if (rdtype == typeid(uint64_t)) {
245 res = boost::lexical_cast<std::string>(
246 std::any_cast<uint64_t>(rdvalue_cast<std::any &>(val)));
247 } else if (rdtype == typeid(unsigned long)) {
248 res = boost::lexical_cast<std::string>(
249 std::any_cast<unsigned long>(rdvalue_cast<std::any &>(val)));
250 } else {
251 throw;
252 return false;
253 }
254 }
255 break;
256 }
257 default:
258 res = "";
259 }
260 return true;
261}
262
263// from_rdvalue -> converts string values to appropriate types
264template <class T>
265typename boost::enable_if<boost::is_arithmetic<T>, T>::type from_rdvalue(
267 T res;
268 if (arg.getTag() == RDTypeTag::StringTag) {
270 try {
272 } catch (const std::bad_any_cast &exc) {
273 try {
274 res = boost::lexical_cast<T>(rdvalue_cast<std::string>(arg));
275 } catch (...) {
276 throw exc;
277 }
278 }
279 } else {
281 }
282 return res;
283}
284
285template <class T>
286typename boost::disable_if<boost::is_arithmetic<T>, T>::type from_rdvalue(
288 return rdvalue_cast<T>(arg);
289}
290} // namespace RDKit
291#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:187
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:265
bool rdvalue_is< std::any >(RDValue_cast_t v)
boost::uint64_t getTag() const