////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Pablo Halpern 2009. 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) // ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2014. 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. // ////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP #define BOOST_INTRUSIVE_POINTER_TRAITS_HPP #include #include #include #include #include #include #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif namespace boost { namespace intrusive { namespace detail { #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1310) BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to) BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from) BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from) BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from) #else BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to) BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from) BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from) BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from) #endif BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(element_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr) } //namespace detail { //! pointer_traits is the implementation of C++11 std::pointer_traits class with some //! extensions like castings. //! //! pointer_traits supplies a uniform interface to certain attributes of pointer-like types. //! //! Note: When defining a custom family of pointers or references to be used with BI //! library, make sure the public static conversion functions accessed through //! the `pointer_traits` interface (`*_cast_from` and `pointer_to`) can //! properly convert between const and nonconst referred member types //! without the use of implicit constructor calls. It is suggested these //! conversions be implemented as function templates, where the template //! argument is the type of the object being converted from. template struct pointer_traits { #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //!The pointer type //!queried by this pointer_traits instantiation typedef Ptr pointer; //!Ptr::element_type if such a type exists; otherwise, T if Ptr is a class //!template instantiation of the form SomePointer, where Args is zero or //!more type arguments ; otherwise , the specialization is ill-formed. typedef unspecified_type element_type; //!Ptr::difference_type if such a type exists; otherwise, //!std::ptrdiff_t. typedef unspecified_type difference_type; //!Ptr::rebind if such a type exists; otherwise, SomePointer if Ptr is //!a class template instantiation of the form SomePointer, where Args is zero or //!more type arguments ; otherwise, the instantiation of rebind is ill-formed. //! //!For portable code for C++03 and C++11,
typename rebind_pointer::type
//!shall be used instead of rebind to obtain a pointer to U. template using rebind = unspecified; //!Ptr::reference if such a type exists (non-standard extension); otherwise, element_type & //! typedef unspecified_type reference; #else typedef Ptr pointer; // typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT ( boost::intrusive::detail::, Ptr, element_type , boost::intrusive::detail::first_param) element_type; // typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type; typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT (boost::intrusive::detail::, Ptr, reference, typename boost::intrusive::detail::unvoid_ref::type) reference; // template struct rebind_pointer { typedef typename boost::intrusive::pointer_rebind::type type; }; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = typename boost::intrusive::pointer_rebind::type; #endif #endif //#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) //! Remark: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise, //! it is element_type &. //! //! Returns: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(reference). //! Non-standard extension: If such function does not exist, returns pointer(addressof(r)); //! //! Note: For non-conforming compilers only the existence of a member function called //! pointer_to is checked. static pointer pointer_to(reference r) { //Non-standard extension, it does not require Ptr::pointer_to. If not present //tries to converts &r to pointer. const bool value = boost::intrusive::detail:: has_member_function_callable_with_pointer_to ::value; boost::intrusive::detail::bool_ flag; return pointer_traits::priv_pointer_to(flag, r); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling the static template function //! Ptr::static_cast_from(UPpr/const UPpr &). //! If such function does not exist, returns pointer_to(static_cast(*uptr)) //! //! Note: For non-conforming compilers only the existence of a member function called //! static_cast_from is checked. template static pointer static_cast_from(const UPtr &uptr) { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: has_member_function_callable_with_static_cast_from ::value || boost::intrusive::detail:: has_member_function_callable_with_static_cast_from ::value; return pointer_traits::priv_static_cast_from(boost::intrusive::detail::bool_(), uptr); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling the static template function //! Ptr::const_cast_from(UPpr/const UPpr &). //! If such function does not exist, returns pointer_to(const_cast(*uptr)) //! //! Note: For non-conforming compilers only the existence of a member function called //! const_cast_from is checked. template static pointer const_cast_from(const UPtr &uptr) { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: has_member_function_callable_with_const_cast_from ::value || boost::intrusive::detail:: has_member_function_callable_with_const_cast_from ::value; return pointer_traits::priv_const_cast_from(boost::intrusive::detail::bool_(), uptr); } //! Remark: Non-standard extension. //! //! Returns: A dereferenceable pointer to r obtained by calling the static template function //! Ptr::dynamic_cast_from(UPpr/const UPpr &). //! If such function does not exist, returns pointer_to(*dynamic_cast(&*uptr)) //! //! Note: For non-conforming compilers only the existence of a member function called //! dynamic_cast_from is checked. template static pointer dynamic_cast_from(const UPtr &uptr) { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: has_member_function_callable_with_dynamic_cast_from ::value || boost::intrusive::detail:: has_member_function_callable_with_dynamic_cast_from ::value; return pointer_traits::priv_dynamic_cast_from(boost::intrusive::detail::bool_(), uptr); } ///@cond private: //priv_to_raw_pointer template static T* to_raw_pointer(T* p) { return p; } template static typename pointer_traits::element_type* to_raw_pointer(const Pointer &p) { return pointer_traits::to_raw_pointer(p.operator->()); } //priv_pointer_to static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) { return Ptr::pointer_to(r); } static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) { return pointer(boost::intrusive::detail::addressof(r)); } //priv_static_cast_from template static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) { return Ptr::static_cast_from(uptr); } template static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) { return pointer_to(*static_cast(to_raw_pointer(uptr))); } //priv_const_cast_from template static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) { return Ptr::const_cast_from(uptr); } template static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) { return pointer_to(const_cast(*uptr)); } //priv_dynamic_cast_from template static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) { return Ptr::dynamic_cast_from(uptr); } template static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) { element_type *p = dynamic_cast(&*uptr); if(!p){ return pointer(); } else{ return pointer_to(*p); } } ///@endcond }; ///@cond // Remove cv qualification from Ptr parameter to pointer_traits: template struct pointer_traits : pointer_traits {}; template struct pointer_traits : pointer_traits { }; template struct pointer_traits : pointer_traits { }; // Remove reference from Ptr parameter to pointer_traits: template struct pointer_traits : pointer_traits { }; ///@endcond //! Specialization of pointer_traits for raw pointers //! template struct pointer_traits { typedef T element_type; typedef T* pointer; typedef std::ptrdiff_t difference_type; #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED typedef T & reference; //!typedef for
U *
//! //!For portable code for C++03 and C++11,
typename rebind_pointer::type
//!shall be used instead of rebind to obtain a pointer to U. template using rebind = U*; #else typedef typename boost::intrusive::detail::unvoid_ref::type reference; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = U*; #endif #endif template struct rebind_pointer { typedef U* type; }; //! Returns: addressof(r) //! static pointer pointer_to(reference r) { return boost::intrusive::detail::addressof(r); } //! Returns: static_cast(uptr) //! template static pointer static_cast_from(U *uptr) { return static_cast(uptr); } //! Returns: const_cast(uptr) //! template static pointer const_cast_from(U *uptr) { return const_cast(uptr); } //! Returns: dynamic_cast(uptr) //! template static pointer dynamic_cast_from(U *uptr) { return dynamic_cast(uptr); } }; } //namespace container { } //namespace boost { #include #endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)