319 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			319 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
//////////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// (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/intrusive/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::intrusive::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.
 | 
						|
   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>
 | 
						|
   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>
 | 
						|
   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>
 | 
						|
   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>
 | 
						|
   static T* to_raw_pointer(T* p)
 | 
						|
   {  return p; }
 | 
						|
 | 
						|
   template <class Pointer>
 | 
						|
   static typename pointer_traits<Pointer>::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<class UPtr>
 | 
						|
   static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
 | 
						|
   { return Ptr::static_cast_from(uptr); }
 | 
						|
 | 
						|
   template<class UPtr>
 | 
						|
   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>
 | 
						|
   static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
 | 
						|
   { return Ptr::const_cast_from(uptr); }
 | 
						|
 | 
						|
   template<class UPtr>
 | 
						|
   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>
 | 
						|
   static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr)
 | 
						|
   { return Ptr::dynamic_cast_from(uptr); }
 | 
						|
 | 
						|
   template<class UPtr>
 | 
						|
   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)
 |