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