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