123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (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 <boost/intrusive/detail/config_begin.hpp>
- #include <boost/intrusive/detail/workaround.hpp>
- #include <boost/intrusive/pointer_rebind.hpp>
- #include <boost/move/detail/pointer_element.hpp>
- #include <boost/intrusive/detail/mpl.hpp>
- #include <cstddef>
- #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.
- //!
- //! <b>Note</b>: 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
- //! <b>without the use of implicit constructor calls</b>. It is suggested these
- //! conversions be implemented as function templates, where the template
- //! argument is the type of the object being converted from.
- template <typename Ptr>
- 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<T, Args>, 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<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
- //!a class template instantiation of the form SomePointer<T, Args>, 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, <pre>typename rebind_pointer<U>::type</pre>
- //!shall be used instead of rebind<U> to obtain a pointer to U.
- template <class U> 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::movelib::detail::first_param<Ptr>) 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<element_type>::type) reference;
- //
- template <class U> struct rebind_pointer
- {
- typedef typename boost::intrusive::pointer_rebind<Ptr, U>::type type;
- };
- #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
- template <class U> using rebind = typename boost::intrusive::pointer_rebind<Ptr, U>::type;
- #endif
- #endif //#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
- //! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
- //! it is element_type &.
- //!
- //! <b>Returns</b>: 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));
- //!
- //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
- //! <code>pointer_to</code> is checked.
- BOOST_INTRUSIVE_FORCEINLINE 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
- <Ptr, Ptr (*)(reference)>::value;
- boost::intrusive::detail::bool_<value> flag;
- return pointer_traits::priv_pointer_to(flag, r);
- }
- //! <b>Remark</b>: Non-standard extension.
- //!
- //! <b>Returns</b>: 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<element_type&>(*uptr))
- //!
- //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
- //! <code>static_cast_from</code> is checked.
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE 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
- <pointer, pointer(*)(RefArg)>::value
- || boost::intrusive::detail::
- has_member_function_callable_with_static_cast_from
- <pointer, pointer(*)(UPtr)>::value;
- return pointer_traits::priv_static_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
- }
- //! <b>Remark</b>: Non-standard extension.
- //!
- //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
- //! Ptr::const_cast_from<UPtr>(UPpr/const UPpr &).
- //! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
- //!
- //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
- //! <code>const_cast_from</code> is checked.
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE 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
- <pointer, pointer(*)(RefArg)>::value
- || boost::intrusive::detail::
- has_member_function_callable_with_const_cast_from
- <pointer, pointer(*)(UPtr)>::value;
- return pointer_traits::priv_const_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
- }
- //! <b>Remark</b>: Non-standard extension.
- //!
- //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
- //! Ptr::dynamic_cast_from<UPtr>(UPpr/const UPpr &).
- //! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
- //!
- //! <b>Note</b>: For non-conforming compilers only the existence of a member function called
- //! <code>dynamic_cast_from</code> is checked.
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE 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
- <pointer, pointer(*)(RefArg)>::value
- || boost::intrusive::detail::
- has_member_function_callable_with_dynamic_cast_from
- <pointer, pointer(*)(UPtr)>::value;
- return pointer_traits::priv_dynamic_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
- }
- ///@cond
- private:
- //priv_to_raw_pointer
- template <class T>
- BOOST_INTRUSIVE_FORCEINLINE static T* to_raw_pointer(T* p)
- { return p; }
- template <class Pointer>
- BOOST_INTRUSIVE_FORCEINLINE static typename pointer_traits<Pointer>::element_type*
- to_raw_pointer(const Pointer &p)
- { return pointer_traits::to_raw_pointer(p.operator->()); }
- //priv_pointer_to
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r)
- { return Ptr::pointer_to(r); }
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r)
- { return pointer(boost::intrusive::detail::addressof(r)); }
- //priv_static_cast_from
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
- { return Ptr::static_cast_from(uptr); }
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
- { return uptr ? pointer_to(*static_cast<element_type*>(to_raw_pointer(uptr))) : pointer(); }
- //priv_const_cast_from
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
- { return Ptr::const_cast_from(uptr); }
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
- { return uptr ? pointer_to(const_cast<element_type&>(*uptr)) : pointer(); }
- //priv_dynamic_cast_from
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
- { return Ptr::dynamic_cast_from(uptr); }
- template<class UPtr>
- BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr)
- { return uptr ? pointer_to(dynamic_cast<element_type&>(*uptr)) : pointer(); }
- ///@endcond
- };
- ///@cond
- // Remove cv qualification from Ptr parameter to pointer_traits:
- template <typename Ptr>
- struct pointer_traits<const Ptr> : pointer_traits<Ptr> {};
- template <typename Ptr>
- struct pointer_traits<volatile Ptr> : pointer_traits<Ptr> { };
- template <typename Ptr>
- struct pointer_traits<const volatile Ptr> : pointer_traits<Ptr> { };
- // Remove reference from Ptr parameter to pointer_traits:
- template <typename Ptr>
- struct pointer_traits<Ptr&> : pointer_traits<Ptr> { };
- ///@endcond
- //! Specialization of pointer_traits for raw pointers
- //!
- template <typename T>
- struct pointer_traits<T*>
- {
- typedef T element_type;
- typedef T* pointer;
- typedef std::ptrdiff_t difference_type;
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- typedef T & reference;
- //!typedef for <pre>U *</pre>
- //!
- //!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
- //!shall be used instead of rebind<U> to obtain a pointer to U.
- template <class U> using rebind = U*;
- #else
- typedef typename boost::intrusive::detail::unvoid_ref<element_type>::type reference;
- #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
- template <class U> using rebind = U*;
- #endif
- #endif
- template <class U> struct rebind_pointer
- { typedef U* type; };
- //! <b>Returns</b>: addressof(r)
- //!
- BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r)
- { return boost::intrusive::detail::addressof(r); }
- //! <b>Returns</b>: static_cast<pointer>(uptr)
- //!
- template<class U>
- BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr)
- { return static_cast<pointer>(uptr); }
- //! <b>Returns</b>: const_cast<pointer>(uptr)
- //!
- template<class U>
- BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr)
- { return const_cast<pointer>(uptr); }
- //! <b>Returns</b>: dynamic_cast<pointer>(uptr)
- //!
- template<class U>
- BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr)
- { return dynamic_cast<pointer>(uptr); }
- };
- } //namespace container {
- } //namespace boost {
- #include <boost/intrusive/detail/config_end.hpp>
- #endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)
|