32 #ifndef RDKIT_RDVALUE_PTRMAGIC_H 33 #define RDKIT_RDVALUE_PTRMAGIC_H 35 #include <boost/cstdint.hpp> 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;
121 template<>
inline boost::uint64_t GetTag<std::string>() {
return StringTag; }
122 template<>
inline boost::uint64_t GetTag<std::vector<double> >() {
return VecDoubleTag; }
123 template<>
inline boost::uint64_t GetTag<std::vector<float> >() {
return VecFloatTag; }
124 template<>
inline boost::uint64_t GetTag<std::vector<int> >() {
return VecIntTag; }
125 template<>
inline boost::uint64_t GetTag<std::vector<unsigned int> >() {
return VecUnsignedIntTag; }
126 template<>
inline boost::uint64_t GetTag<std::vector<std::string> >() {
return VecStringTag; }
127 template<>
inline boost::uint64_t GetTag<boost::any>() {
return AnyTag; }
133 static const boost::uint64_t TagMask = 0xFFFF000000000000;
134 static const boost::uint64_t PointerTagMask = 0xFFFF000000000007;
135 static const boost::uint64_t ApplyMask = 0x0000FFFFFFFFFFFF;
136 static const boost::uint64_t ApplyPtrMask = 0x0000FFFFFFFFFFF8;
146 if (boost::math::isnan(number)) {
150 assert(boost::math::isnan(doubleBits));
158 memcpy(((
char*)&otherBits), &number,
sizeof(
float));
176 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
181 boost::any *pointer =
new boost::any(any);
183 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
189 boost::any *pointer =
new boost::any(v);
191 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
195 std::string *pointer =
new std::string(v);
197 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::StringTag;
200 inline RDValue(
const std::vector<double> &v) {
201 std::vector<double> *pointer =
new std::vector<double>(v);
203 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecDoubleTag;
207 std::vector<float> *pointer =
new std::vector<float>(v);
209 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecFloatTag;
213 std::vector<int> *pointer =
new std::vector<int>(v);
215 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecIntTag;
218 inline RDValue(
const std::vector<unsigned int> &v) {
219 std::vector<unsigned int> *pointer =
new std::vector<unsigned int>(v);
224 inline RDValue(
const std::vector<std::string> &v) {
225 std::vector<std::string> *pointer =
new std::vector<std::string>(v);
227 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecStringTag;
236 boost::uint64_t tag = otherBits & TagMask;
238 return otherBits & PointerTagMask;
245 return reinterpret_cast<T*
>(otherBits & ~RDTypeTag::GetTag<T>());
255 delete ptrCast<std::string>();
258 delete ptrCast<std::vector<double> >();
261 delete ptrCast<std::vector<float> >();
264 delete ptrCast<std::vector<int> >();
267 delete ptrCast<std::vector<unsigned int> >();
270 delete ptrCast<std::vector<std::string> >();
273 delete ptrCast<boost::any>();
325 return v.
getTag() == RDTypeTag::GetTag<typename boost::remove_reference<T>::type>();
335 inline bool rdvalue_is<const double &>(
RDValue v) {
365 BOOST_STATIC_ASSERT( !(
366 (boost::is_pointer<T>::value && (
367 boost::is_integral<
typename boost::remove_pointer<T>::type>::value ||
368 boost::is_floating_point<
typename boost::remove_pointer<T>::type>::value)) ||
369 (boost::is_reference<T>::value && (
370 boost::is_integral<
typename boost::remove_reference<T>::type>::value ||
371 boost::is_floating_point<
typename boost::remove_reference<T>::type>::value))
374 if (rdvalue_is<boost::any>(v)) {
375 return boost::any_cast<T>(*v.
ptrCast<boost::any>());
377 throw boost::bad_any_cast();
384 throw boost::bad_any_cast();
389 if (rdvalue_is<float>(v)) {
391 memcpy(&f, ((
char*)&v.otherBits),
sizeof(
float));
394 throw boost::bad_any_cast();
401 if (rdvalue_is<int>(v))
return static_cast<int32_t>(v.otherBits &
403 throw boost::bad_any_cast();
407 if (rdvalue_is<unsigned int>(v))
return static_cast<uint32_t>(
409 throw boost::bad_any_cast();
414 if (rdvalue_is<bool>(v))
return static_cast<bool>(
416 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