////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/intrusive for documentation. // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include struct CompleteSmartPtrStats { static unsigned static_cast_called; static unsigned dynamic_cast_called; static unsigned const_cast_called; static unsigned pointer_to_called; static void reset_stats() { static_cast_called = 0; dynamic_cast_called = 0; const_cast_called = 0; pointer_to_called = 0; } }; unsigned CompleteSmartPtrStats::static_cast_called= 0; unsigned CompleteSmartPtrStats::dynamic_cast_called = 0; unsigned CompleteSmartPtrStats::const_cast_called = 0; unsigned CompleteSmartPtrStats::pointer_to_called = 0; template class CompleteSmartPtr { template friend class CompleteSmartPtr; void unspecified_bool_type_func() const {} typedef void (CompleteSmartPtr::*unspecified_bool_type)() const; public: #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = CompleteSmartPtr; #else template struct rebind { typedef CompleteSmartPtr other; }; #endif typedef char difference_type; typedef T element_type; CompleteSmartPtr() : ptr_(0) {} explicit CompleteSmartPtr(T &p) : ptr_(&p) {} CompleteSmartPtr(const CompleteSmartPtr &c) { this->ptr_ = c.ptr_; } CompleteSmartPtr & operator=(const CompleteSmartPtr &c) { this->ptr_ = c.ptr_; } static CompleteSmartPtr pointer_to(T &r) { ++CompleteSmartPtrStats::pointer_to_called; return CompleteSmartPtr(r); } T * operator->() const { return ptr_; } T & operator *() const { return *ptr_; } operator unspecified_bool_type() const { return ptr_? &CompleteSmartPtr::unspecified_bool_type_func : 0; } template static CompleteSmartPtr static_cast_from(const CompleteSmartPtr &uptr) { ++CompleteSmartPtrStats::static_cast_called; element_type* const p = static_cast(uptr.ptr_); return p ? CompleteSmartPtr(*p) : CompleteSmartPtr(); } template static CompleteSmartPtr const_cast_from(const CompleteSmartPtr &uptr) { ++CompleteSmartPtrStats::const_cast_called; element_type* const p = const_cast(uptr.ptr_); return p ? CompleteSmartPtr(*p) : CompleteSmartPtr(); } template static CompleteSmartPtr dynamic_cast_from(const CompleteSmartPtr &uptr) { ++CompleteSmartPtrStats::dynamic_cast_called; element_type* const p = dynamic_cast(uptr.ptr_); return p ? CompleteSmartPtr(*p) : CompleteSmartPtr(); } friend bool operator ==(const CompleteSmartPtr &l, const CompleteSmartPtr &r) { return l.ptr_ == r.ptr_; } friend bool operator !=(const CompleteSmartPtr &l, const CompleteSmartPtr &r) { return l.ptr_ != r.ptr_; } private: T *ptr_; }; template class SimpleSmartPtr { void unspecified_bool_type_func() const {} typedef void (SimpleSmartPtr::*unspecified_bool_type)() const; public: SimpleSmartPtr() : ptr_(0) {} explicit SimpleSmartPtr(T *p) : ptr_(p) {} SimpleSmartPtr(const SimpleSmartPtr &c) { this->ptr_ = c.ptr_; } SimpleSmartPtr & operator=(const SimpleSmartPtr &c) { this->ptr_ = c.ptr_; } friend bool operator ==(const SimpleSmartPtr &l, const SimpleSmartPtr &r) { return l.ptr_ == r.ptr_; } friend bool operator !=(const SimpleSmartPtr &l, const SimpleSmartPtr &r) { return l.ptr_ != r.ptr_; } T* operator->() const { return ptr_; } T & operator *() const { return *ptr_; } operator unspecified_bool_type() const { return ptr_? &SimpleSmartPtr::unspecified_bool_type_func : 0; } private: T *ptr_; }; class B{ public: virtual ~B(){} }; class D : public B {}; class DD : public virtual B {}; int main() { int dummy; //Raw pointer BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same::element_type, int>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same::pointer, int*>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same::difference_type, std::ptrdiff_t>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same::rebind_pointer::type , double*>::value )); BOOST_TEST(boost::intrusive::pointer_traits::pointer_to(dummy) == &dummy); BOOST_TEST(boost::intrusive::pointer_traits:: static_cast_from((B*)0) == 0); BOOST_TEST(boost::intrusive::pointer_traits:: const_cast_from((const D*)0) == 0); BOOST_TEST(boost::intrusive::pointer_traits:: dynamic_cast_from((B*)0) == 0); //Complete smart pointer BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::element_type, int>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::pointer, CompleteSmartPtr >::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::difference_type, char>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::rebind_pointer::type , CompleteSmartPtr >::value )); //pointer_to CompleteSmartPtrStats::reset_stats(); BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr >::pointer_to(dummy) == CompleteSmartPtr(dummy)); BOOST_TEST(CompleteSmartPtrStats::pointer_to_called == 1); //static_cast_from CompleteSmartPtrStats::reset_stats(); BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr >::static_cast_from(CompleteSmartPtr()) == CompleteSmartPtr()); BOOST_TEST(CompleteSmartPtrStats::static_cast_called == 1); //const_cast_from CompleteSmartPtrStats::reset_stats(); BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr >::const_cast_from(CompleteSmartPtr()) == CompleteSmartPtr()); BOOST_TEST(CompleteSmartPtrStats::const_cast_called == 1); //dynamic_cast_from CompleteSmartPtrStats::reset_stats(); BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr
>::dynamic_cast_from(CompleteSmartPtr()) == CompleteSmartPtr
()); BOOST_TEST(CompleteSmartPtrStats::dynamic_cast_called == 1); //Simple smart pointer BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::element_type, int>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::pointer, SimpleSmartPtr >::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::difference_type, std::ptrdiff_t>::value )); BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same >::rebind_pointer::type , SimpleSmartPtr >::value )); BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr >::pointer_to(dummy) == SimpleSmartPtr(&dummy)); BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr > ::static_cast_from(SimpleSmartPtr()) == SimpleSmartPtr()); BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr > ::const_cast_from(SimpleSmartPtr()) == SimpleSmartPtr()); BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr
>::dynamic_cast_from(SimpleSmartPtr()) == SimpleSmartPtr
()); return boost::report_errors(); }