32 #ifndef RDKIT_RDVALUE_PTRMAGIC_H
33 #define RDKIT_RDVALUE_PTRMAGIC_H
37 #include <boost/any.hpp>
45 #include <boost/utility.hpp>
46 #include <boost/lexical_cast.hpp>
47 #include <boost/type_traits.hpp>
48 #include <boost/static_assert.hpp>
53 #define RDVALUE_HASBOOL
94 static const boost::uint64_t
NaN = 0xfff7FFFFFFFFFFFF;
95 static const boost::uint64_t
MaxDouble = 0xfff8000000000000;
96 static const boost::uint64_t
DoubleTag = 0xfff8000000000000;
97 static const boost::uint64_t
FloatTag = 0xfff9000000000000;
98 static const boost::uint64_t
IntTag = 0xfffa000000000000;
100 static const boost::uint64_t
BoolTag = 0xfffc000000000000;
103 static const boost::uint64_t
PtrTag = 0xffff000000000000;
104 static const boost::uint64_t
StringTag = 0xffff000000000001;
107 static const boost::uint64_t
VecIntTag = 0xffff000000000004;
110 static const boost::uint64_t
AnyTag = 0xffff000000000007;
138 inline boost::uint64_t GetTag<std::string>() {
142 inline boost::uint64_t GetTag<std::vector<double>>() {
146 inline boost::uint64_t GetTag<std::vector<float>>() {
150 inline boost::uint64_t GetTag<std::vector<int>>() {
154 inline boost::uint64_t GetTag<std::vector<unsigned int>>() {
158 inline boost::uint64_t GetTag<std::vector<std::string>>() {
162 inline boost::uint64_t GetTag<boost::any>() {
169 static const boost::uint64_t
TagMask = 0xFFFF000000000000;
171 static const boost::uint64_t
ApplyMask = 0x0000FFFFFFFFFFFF;
182 if (boost::math::isnan(number)) {
193 memcpy(((
char *)&
otherBits), &number,
sizeof(
float));
219 boost::any *pointer =
new boost::any(any);
228 boost::any *pointer =
new boost::any(v);
235 std::string *pointer =
new std::string(v);
236 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
242 inline RDValue(
const std::vector<double> &v) {
243 std::vector<double> *pointer =
new std::vector<double>(v);
244 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
251 std::vector<float> *pointer =
new std::vector<float>(v);
252 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
259 std::vector<int> *pointer =
new std::vector<int>(v);
260 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
266 inline RDValue(
const std::vector<unsigned int> &v) {
267 std::vector<unsigned int> *pointer =
new std::vector<unsigned int>(v);
268 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
270 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) |
274 inline RDValue(
const std::vector<std::string> &v) {
275 std::vector<std::string> *pointer =
new std::vector<std::string>(v);
276 assert((
reinterpret_cast<boost::uint64_t
>(pointer) &
296 return reinterpret_cast<T *
>(
otherBits & ~RDTypeTag::GetTag<T>());
306 delete ptrCast<std::string>();
309 delete ptrCast<std::vector<double>>();
312 delete ptrCast<std::vector<float>>();
315 delete ptrCast<std::vector<int>>();
318 delete ptrCast<std::vector<unsigned int>>();
321 delete ptrCast<std::vector<std::string>>();
324 delete ptrCast<boost::any>();
374 RDTypeTag::GetTag<typename boost::remove_reference<T>::type>();
375 if (v.getTag() == tag)
return true;
379 return v.value.a->type() ==
typeid(T);
422 BOOST_STATIC_ASSERT(!(
423 (boost::is_pointer<T>::value &&
424 (boost::is_integral<
typename boost::remove_pointer<T>::type>::value ||
425 boost::is_floating_point<
426 typename boost::remove_pointer<T>::type>::value)) ||
427 (boost::is_reference<T>::value &&
428 (boost::is_integral<
typename boost::remove_reference<T>::type>::value ||
429 boost::is_floating_point<
430 typename boost::remove_reference<T>::type>::value))));
432 if (rdvalue_is<boost::any>(v)) {
433 return boost::any_cast<T>(*v.
ptrCast<boost::any>());
435 throw boost::bad_any_cast();
442 throw boost::bad_any_cast();
447 if (rdvalue_is<float>(v)) {
449 memcpy(&f, ((
char *)&v.
otherBits),
sizeof(
float));
452 throw boost::bad_any_cast();
459 if (rdvalue_is<int>(v))
461 throw boost::bad_any_cast();
465 if (rdvalue_is<unsigned int>(v))
467 throw boost::bad_any_cast();
472 if (rdvalue_is<bool>(v))
474 throw boost::bad_any_cast();