RDKit
Open-source cheminformatics and machine learning.
RDAny.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_RDANY_H
32 #define RDKIT_RDANY_H
33 #include <boost/any.hpp>
34 #include <boost/utility.hpp>
35 #include <boost/lexical_cast.hpp>
36 #include "LocaleSwitcher.h"
37 #include "RDValue.h"
38 #include <string>
39 #include <vector>
40 #include <iostream>
41 #include <sstream>
42 namespace RDKit {
43 
44 // RDValue does not dynamically create POD types (kind of like
45 // cdiggins::any) However, it doesn't use RTTI type info
46 // directly, it uses a companion short valued type
47 // to determine what to do.
48 // For unregistered types, it falls back to boost::any.
49 // The Size of an RDAny is (sizeof(double) + sizeof(short) == 10 bytes)
50 //
51 // For the sake of compatibility, errors throw boost::bad_any_cast
52 //
53 // Examples:
54 //
55 // RDAny v(2.);
56 // v = 1;
57 // std::vector<double> d;
58 // v == d;
59 // v.asDoubleVect().push_back(4.)
60 // rdany_cast<std::vector<double>(v).push_back(4.)
61 //
62 // Falls back to boost::any for non registered types
63 // v = boost::shared_ptr<ROMol>(new ROMol(m));
64 //
65 
66 // Safe container for RDValue -- cleans up memory and copy constructs
67 struct RDAny {
69 
70  RDAny() : m_value() {}
71  template <class T> RDAny(const T &d) : m_value(d) {}
72  /*
73  explicit RDAny(bool v) : m_value(v) {}
74  template <class T>
75  explicit RDAny(std::vector<T> *v) : m_value(v) {}
76  template <class T>
77  explicit RDAny(const boost::shared_ptr<T> &v) : m_value(v) {}
78  */
79  RDAny(const RDAny &rhs) {
80  copy_rdvalue(m_value, rhs.m_value);
81  }
82 
84 
85  // For easy of use:
86  // RDAny v;
87  // v = 2.0;
88  // v = std::string("foo...");
89 
90  RDAny &operator=(const RDAny &rhs) {
91  copy_rdvalue(m_value, rhs.m_value);
92  return *this;
93  }
94 
95  RDAny &operator=(float d) {
96  RDValue::cleanup_rdvalue(m_value);
97  m_value = RDValue(d);
98  return *this;
99  }
100 
101  RDAny &operator=(int d) {
102  RDValue::cleanup_rdvalue(m_value);
103  m_value = RDValue(d);
104  return *this;
105  }
106 
107  RDAny &operator=(unsigned int d) {
108  RDValue::cleanup_rdvalue(m_value);
109  m_value = RDValue(d);
110  return *this;
111  }
112 
113  RDAny &operator=(bool d) {
114  RDValue::cleanup_rdvalue(m_value);
115  m_value = RDValue(d);
116  return *this;
117  }
118 
119  RDAny &operator=(const std::string &d) {
120  RDValue::cleanup_rdvalue(m_value);
121  m_value = RDValue(d);
122  return *this;
123  }
124 
125  RDAny &operator=(const std::vector<double> &d) {
126  RDValue::cleanup_rdvalue(m_value);
127  m_value = RDValue(d);
128  return *this;
129  }
130 
131  RDAny &operator=(const std::vector<float> &d) {
132  RDValue::cleanup_rdvalue(m_value);
133  m_value = RDValue(d);
134  return *this;
135  }
136 
137  RDAny &operator=(const std::vector<int> &d) {
138  RDValue::cleanup_rdvalue(m_value);
139  m_value = RDValue(d);
140  return *this;
141  }
142 
143  RDAny &operator=(const std::vector<unsigned int> &d) {
144  RDValue::cleanup_rdvalue(m_value);
145  m_value = d;
146  return *this;
147  }
148 
149  RDAny &operator=(const std::vector<std::string> &d) {
150  RDValue::cleanup_rdvalue(m_value);
151  m_value = RDValue(d);
152  return *this;
153  }
154 
155  RDAny &operator=(const boost::any &d) {
156  RDValue::cleanup_rdvalue(m_value);
157  m_value = RDValue(d);//new boost::any(d);
158  return *this;
159  }
160 
161  template<class T>
162  RDAny &operator=(const T &d) {
163  RDValue::cleanup_rdvalue(m_value);
164  boost::any *v = new boost::any(d);
165  m_value = RDValue(v);
166  return *this;
167  }
168 
169 };
170 
171 ////////////////////////////////////////////////////////////////
172 // rdany_cast
173 ////////////////////////////////////////////////////////////////
174 
175 
176 // Const Access
177 template <class T>
178 const T rdany_cast(const RDAny &d) {
179  return rdvalue_cast<T>(d.m_value);
180 }
181 
182 // Direct access
183 template <class T>
185  return rdvalue_cast<T>(d.m_value);
186 }
187 
188 template <class T>
189 typename boost::enable_if<boost::is_arithmetic<T>, T>::type from_rdany(
190  const RDAny &arg) {
191  T res;
192  if (arg.m_value.getTag() == RDTypeTag::StringTag) {
194  try {
195  res = rdany_cast<T>(arg);
196  } catch (const boost::bad_any_cast &exc) {
197  try {
198  res = boost::lexical_cast<T>(rdany_cast<std::string>(arg));
199  } catch (...) {
200  throw exc;
201  }
202  }
203  } else {
204  res = rdany_cast<T>(arg);
205  }
206  return res;
207 }
208 
209 template <class T>
210 typename boost::disable_if<boost::is_arithmetic<T>, T>::type from_rdany(
211  const RDAny &arg) {
212  return rdany_cast<T>(arg);
213 }
214 
215 }
216 #endif
~RDAny()
Definition: RDAny.h:83
void copy_rdvalue(RDValue &dest, const RDValue &src)
const T rdany_cast(const RDAny &d)
Definition: RDAny.h:178
T rdvalue_cast(RDValue v)
RDValue m_value
Definition: RDAny.h:68
static void cleanup_rdvalue(RDValue v)
RDAny & operator=(const RDAny &rhs)
Definition: RDAny.h:90
static const boost::uint64_t StringTag
RDAny(const RDAny &rhs)
Definition: RDAny.h:79
RDAny & operator=(const std::vector< float > &d)
Definition: RDAny.h:131
RDAny(const T &d)
Definition: RDAny.h:71
Includes a bunch of functionality for handling Atom and Bond queries.
Definition: Atom.h:29
RDAny & operator=(const std::vector< unsigned int > &d)
Definition: RDAny.h:143
RDAny & operator=(unsigned int d)
Definition: RDAny.h:107
RDAny & operator=(const boost::any &d)
Definition: RDAny.h:155
RDAny & operator=(int d)
Definition: RDAny.h:101
RDAny & operator=(const std::string &d)
Definition: RDAny.h:119
RDAny & operator=(const T &d)
Definition: RDAny.h:162
RDAny & operator=(const std::vector< int > &d)
Definition: RDAny.h:137
RDAny & operator=(float d)
Definition: RDAny.h:95
boost::uint64_t getTag() const
RDAny & operator=(const std::vector< double > &d)
Definition: RDAny.h:125
boost::enable_if< boost::is_arithmetic< T >, T >::type from_rdany(const RDAny &arg)
Definition: RDAny.h:189
RDAny & operator=(bool d)
Definition: RDAny.h:113
RDAny & operator=(const std::vector< std::string > &d)
Definition: RDAny.h:149