189 lines
6.3 KiB
C++
189 lines
6.3 KiB
C++
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// (C) Copyright Ion Gaztanaga 2014-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_REBIND_HPP
|
||
|
#define BOOST_INTRUSIVE_POINTER_REBIND_HPP
|
||
|
|
||
|
#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
|
||
|
#include <boost/intrusive/detail/workaround.hpp>
|
||
|
#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
|
||
|
|
||
|
#ifndef BOOST_CONFIG_HPP
|
||
|
# include <boost/config.hpp>
|
||
|
#endif
|
||
|
|
||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||
|
# pragma once
|
||
|
#endif
|
||
|
|
||
|
namespace boost {
|
||
|
namespace intrusive {
|
||
|
|
||
|
///////////////////////////
|
||
|
//struct pointer_rebind_mode
|
||
|
///////////////////////////
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_has_rebind
|
||
|
{
|
||
|
template <typename V> struct any
|
||
|
{ any(const V&) { } };
|
||
|
|
||
|
template <typename X>
|
||
|
static char test(int, typename X::template rebind<U>*);
|
||
|
|
||
|
template <typename X>
|
||
|
static int test(any<int>, void*);
|
||
|
|
||
|
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
|
||
|
};
|
||
|
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_has_rebind_other
|
||
|
{
|
||
|
template <typename V> struct any
|
||
|
{ any(const V&) { } };
|
||
|
|
||
|
template <typename X>
|
||
|
static char test(int, typename X::template rebind<U>::other*);
|
||
|
|
||
|
template <typename X>
|
||
|
static int test(any<int>, void*);
|
||
|
|
||
|
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
|
||
|
};
|
||
|
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_rebind_mode
|
||
|
{
|
||
|
static const unsigned int rebind = (unsigned int)pointer_has_rebind<Ptr, U>::value;
|
||
|
static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other<Ptr, U>::value;
|
||
|
static const unsigned int mode = rebind + rebind*rebind_other;
|
||
|
};
|
||
|
|
||
|
////////////////////////
|
||
|
//struct pointer_rebinder
|
||
|
////////////////////////
|
||
|
template <typename Ptr, typename U, unsigned int RebindMode>
|
||
|
struct pointer_rebinder;
|
||
|
|
||
|
// Implementation of pointer_rebinder<U>::type if Ptr has
|
||
|
// its own rebind<U>::other type (C++03)
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_rebinder< Ptr, U, 2u >
|
||
|
{
|
||
|
typedef typename Ptr::template rebind<U>::other type;
|
||
|
};
|
||
|
|
||
|
// Implementation of pointer_rebinder<U>::type if Ptr has
|
||
|
// its own rebind template.
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_rebinder< Ptr, U, 1u >
|
||
|
{
|
||
|
typedef typename Ptr::template rebind<U> type;
|
||
|
};
|
||
|
|
||
|
// Specialization of pointer_rebinder if Ptr does not
|
||
|
// have its own rebind template but has a the form Ptr<A, An...>,
|
||
|
// where An... comprises zero or more type parameters.
|
||
|
// Many types fit this form, hence many pointers will get a
|
||
|
// reasonable default for rebind.
|
||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||
|
|
||
|
template <template <class, class...> class Ptr, typename A, class... An, class U>
|
||
|
struct pointer_rebinder<Ptr<A, An...>, U, 0u >
|
||
|
{
|
||
|
typedef Ptr<U, An...> type;
|
||
|
};
|
||
|
|
||
|
//Needed for non-conforming compilers like GCC 4.3
|
||
|
template <template <class> class Ptr, typename A, class U>
|
||
|
struct pointer_rebinder<Ptr<A>, U, 0u >
|
||
|
{
|
||
|
typedef Ptr<U> type;
|
||
|
};
|
||
|
|
||
|
#else //C++03 compilers
|
||
|
|
||
|
template <template <class> class Ptr //0arg
|
||
|
, typename A
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A>, U, 0u>
|
||
|
{ typedef Ptr<U> type; };
|
||
|
|
||
|
template <template <class, class> class Ptr //1arg
|
||
|
, typename A, class P0
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0>, U, 0u>
|
||
|
{ typedef Ptr<U, P0> type; };
|
||
|
|
||
|
template <template <class, class, class> class Ptr //2arg
|
||
|
, typename A, class P0, class P1
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1> type; };
|
||
|
|
||
|
template <template <class, class, class, class> class Ptr //3arg
|
||
|
, typename A, class P0, class P1, class P2
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class> class Ptr //4arg
|
||
|
, typename A, class P0, class P1, class P2, class P3
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class, class> class Ptr //5arg
|
||
|
, typename A, class P0, class P1, class P2, class P3, class P4
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3, P4> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class, class, class> class Ptr //6arg
|
||
|
, typename A, class P0, class P1, class P2, class P3, class P4, class P5
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class, class, class, class> class Ptr //7arg
|
||
|
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class, class, class, class, class> class Ptr //8arg
|
||
|
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7> type; };
|
||
|
|
||
|
template <template <class, class, class, class, class, class, class, class, class, class> class Ptr //9arg
|
||
|
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
|
||
|
, class U>
|
||
|
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U, 0u>
|
||
|
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; };
|
||
|
|
||
|
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||
|
|
||
|
template <typename Ptr, typename U>
|
||
|
struct pointer_rebind
|
||
|
: public pointer_rebinder<Ptr, U, pointer_rebind_mode<Ptr, U>::mode>
|
||
|
{};
|
||
|
|
||
|
template <typename T, typename U>
|
||
|
struct pointer_rebind<T*, U>
|
||
|
{ typedef U* type; };
|
||
|
|
||
|
} //namespace container {
|
||
|
} //namespace boost {
|
||
|
|
||
|
#endif // defined(BOOST_INTRUSIVE_POINTER_REBIND_HPP)
|