31 #ifndef RDKIT_RDVALUE_PTRMAGIC_H 32 #define RDKIT_RDVALUE_PTRMAGIC_H 34 #include <boost/cstdint.hpp> 36 #include <boost/any.hpp> 44 #include <boost/utility.hpp> 45 #include <boost/lexical_cast.hpp> 46 #include <boost/type_traits.hpp> 47 #include <boost/static_assert.hpp> 52 #define RDVALUE_HASBOOL 93 static const boost::uint64_t
NaN = 0xfff7FFFFFFFFFFFF;
94 static const boost::uint64_t
MaxDouble = 0xfff8000000000000;
95 static const boost::uint64_t
DoubleTag = 0xfff8000000000000;
96 static const boost::uint64_t
FloatTag = 0xfff9000000000000;
97 static const boost::uint64_t
IntTag = 0xfffa000000000000;
99 static const boost::uint64_t
BoolTag = 0xfffc000000000000;
102 static const boost::uint64_t
PtrTag = 0xffff000000000000;
103 static const boost::uint64_t
StringTag = 0xffff000000000001;
106 static const boost::uint64_t
VecIntTag = 0xffff000000000004;
109 static const boost::uint64_t
AnyTag = 0xffff000000000007;
120 template<>
inline boost::uint64_t GetTag<std::string>() {
return StringTag; }
121 template<>
inline boost::uint64_t GetTag<std::vector<double> >() {
return VecDoubleTag; }
122 template<>
inline boost::uint64_t GetTag<std::vector<float> >() {
return VecFloatTag; }
123 template<>
inline boost::uint64_t GetTag<std::vector<int> >() {
return VecIntTag; }
124 template<>
inline boost::uint64_t GetTag<std::vector<unsigned int> >() {
return VecUnsignedIntTag; }
125 template<>
inline boost::uint64_t GetTag<std::vector<std::string> >() {
return VecStringTag; }
126 template<>
inline boost::uint64_t GetTag<boost::any>() {
return AnyTag; }
132 static const boost::uint64_t TagMask = 0xFFFF000000000000;
133 static const boost::uint64_t PointerTagMask = 0xFFFF000000000007;
134 static const boost::uint64_t ApplyMask = 0x0000FFFFFFFFFFFF;
135 static const boost::uint64_t ApplyPtrMask = 0x0000FFFFFFFFFFF8;
145 if (boost::math::isnan(number)) {
149 assert(boost::math::isnan(doubleBits));
157 memcpy(((
char*)&otherBits), &number,
sizeof(
float));
175 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
180 boost::any *pointer =
new boost::any(any);
182 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
188 boost::any *pointer =
new boost::any(v);
190 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
194 std::string *pointer =
new std::string(v);
196 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::StringTag;
199 inline RDValue(
const std::vector<double> &v) {
200 std::vector<double> *pointer =
new std::vector<double>(v);
202 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecDoubleTag;
206 std::vector<float> *pointer =
new std::vector<float>(v);
208 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecFloatTag;
212 std::vector<int> *pointer =
new std::vector<int>(v);
214 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecIntTag;
217 inline RDValue(
const std::vector<unsigned int> &v) {
218 std::vector<unsigned int> *pointer =
new std::vector<unsigned int>(v);
223 inline RDValue(
const std::vector<std::string> &v) {
224 std::vector<std::string> *pointer =
new std::vector<std::string>(v);
226 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecStringTag;
235 boost::uint64_t tag = otherBits & TagMask;
237 return otherBits & PointerTagMask;
244 return reinterpret_cast<T*
>(otherBits & ~RDTypeTag::GetTag<T>());
254 delete ptrCast<std::string>();
257 delete ptrCast<std::vector<double> >();
260 delete ptrCast<std::vector<float> >();
263 delete ptrCast<std::vector<int> >();
266 delete ptrCast<std::vector<unsigned int> >();
269 delete ptrCast<std::vector<std::string> >();
272 delete ptrCast<boost::any>();
324 return v.
getTag() == RDTypeTag::GetTag<typename boost::remove_reference<T>::type>();
334 inline bool rdvalue_is<const double &>(
RDValue v) {
364 BOOST_STATIC_ASSERT( !(
365 (boost::is_pointer<T>::value && (
366 boost::is_integral<
typename boost::remove_pointer<T>::type>::value ||
367 boost::is_floating_point<
typename boost::remove_pointer<T>::type>::value)) ||
368 (boost::is_reference<T>::value && (
369 boost::is_integral<
typename boost::remove_reference<T>::type>::value ||
370 boost::is_floating_point<
typename boost::remove_reference<T>::type>::value))
373 if (rdvalue_is<boost::any>(v)) {
374 return boost::any_cast<T>(*v.
ptrCast<boost::any>());
376 throw boost::bad_any_cast();
383 throw boost::bad_any_cast();
388 if (rdvalue_is<float>(v)) {
390 memcpy(&f, ((
char*)&v.otherBits),
sizeof(
float));
393 throw boost::bad_any_cast();
400 if (rdvalue_is<int>(v))
return static_cast<int32_t>(v.otherBits &
402 throw boost::bad_any_cast();
406 if (rdvalue_is<unsigned int>(v))
return static_cast<uint32_t>(
408 throw boost::bad_any_cast();
413 if (rdvalue_is<bool>(v))
return static_cast<bool>(
415 throw boost::bad_any_cast();
bool rdvalue_is< double >(RDValue v)
RDValue(const std::vector< unsigned int > &v)
RDValue(boost::any *pointer)
boost::uint64_t GetTag< float >()
static const boost::uint64_t MaxDouble
void copy_rdvalue(RDValue &dest, const RDValue &src)
static const boost::uint64_t VecDoubleTag
boost::uint64_t GetTag< int >()
static const boost::uint64_t UnsignedIntTag
RDValue(unsigned int number)
T rdvalue_cast(RDValue v)
static const boost::uint64_t AnyTag
static const boost::uint64_t DoubleTag
RDValue(const std::vector< float > &v)
static const boost::uint64_t FloatTag
static void cleanup_rdvalue(RDValue v)
static const boost::uint64_t StringTag
bool rdvalue_is(RDValue v)
RDValue(const std::vector< std::string > &v)
static const boost::uint64_t VecIntTag
static const boost::uint64_t VecUnsignedIntTag
static const boost::uint64_t VecStringTag
static const boost::uint64_t NaN
static const boost::uint64_t IntTag
boost::uint64_t GetTag< unsigned int >()
static const boost::uint64_t BoolTag
boost::uint64_t getTag() const
static const boost::uint64_t VecFloatTag
RDValue(const std::vector< double > &v)
boost::uint64_t GetTag< double >()
RDValue(const boost::any &any)
boost::uint64_t GetTag< bool >()
static const boost::uint64_t PtrTag
RDValue(const std::vector< int > &v)
RDValue(const std::string &v)
boost::uint64_t otherBits