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