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;
170 static const boost::uint64_t PointerTagMask = 0xFFFF000000000007;
171 static const boost::uint64_t ApplyMask = 0x0000FFFFFFFFFFFF;
172 static const boost::uint64_t ApplyPtrMask = 0x0000FFFFFFFFFFF8;
182 if (boost::math::isnan(number)) {
186 assert(boost::math::isnan(doubleBits));
193 memcpy(((
char *)&otherBits), &number,
sizeof(
float));
214 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
219 boost::any *pointer =
new boost::any(any);
222 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
228 boost::any *pointer =
new boost::any(v);
231 otherBits =
reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::AnyTag;
235 std::string *pointer =
new std::string(v);
236 assert((reinterpret_cast<boost::uint64_t>(pointer) &
239 reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::StringTag;
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) &
247 reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecDoubleTag;
251 std::vector<float> *pointer =
new std::vector<float>(v);
252 assert((reinterpret_cast<boost::uint64_t>(pointer) &
255 reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecFloatTag;
259 std::vector<int> *pointer =
new std::vector<int>(v);
260 assert((reinterpret_cast<boost::uint64_t>(pointer) &
263 reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecIntTag;
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) &
279 reinterpret_cast<boost::uint64_t
>(pointer) | RDTypeTag::VecStringTag;
288 boost::uint64_t tag = otherBits & TagMask;
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();
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)
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
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
bool rdvalue_is(const RDValue_cast_t)
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
T rdvalue_cast(RDValue_cast_t v)
RDValue(const std::vector< double > &v)
boost::uint64_t GetTag< double >()
RDValue(const boost::any &any)
boost::uint64_t GetTag< bool >()
bool rdvalue_is< double >(const RDValue_cast_t)
static const boost::uint64_t PtrTag
RDValue(const std::vector< int > &v)
RDValue(const std::string &v)
boost::uint64_t otherBits