You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.2 KiB
188 lines
6.2 KiB
////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// (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)
|
|
|