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