mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-23 09:55:34 +00:00
377 lines
9.2 KiB
C++
377 lines
9.2 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// (C) Copyright Ion Gaztanaga 2006-2014
|
||
|
// (C) Copyright Microsoft Corporation 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_DETAIL_MPL_HPP
|
||
|
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
|
||
|
|
||
|
#if defined(_MSC_VER)
|
||
|
# pragma once
|
||
|
#endif
|
||
|
|
||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||
|
#include <cstddef>
|
||
|
|
||
|
namespace boost {
|
||
|
namespace intrusive {
|
||
|
namespace detail {
|
||
|
|
||
|
template <typename T, typename U>
|
||
|
struct is_same
|
||
|
{
|
||
|
static const bool value = false;
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct is_same<T, T>
|
||
|
{
|
||
|
static const bool value = true;
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct add_const
|
||
|
{ typedef const T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_const
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_const<const T>
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_cv
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_cv<const T>
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_cv<const volatile T>
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<typename T>
|
||
|
struct remove_cv<volatile T>
|
||
|
{ typedef T type; };
|
||
|
|
||
|
template<class T>
|
||
|
struct remove_reference
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct remove_reference<T&>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct remove_pointer
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct remove_pointer<T*>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct add_pointer
|
||
|
{
|
||
|
typedef T *type;
|
||
|
};
|
||
|
|
||
|
typedef char one;
|
||
|
struct two {one _[2];};
|
||
|
|
||
|
template< bool C_ >
|
||
|
struct bool_
|
||
|
{
|
||
|
static const bool value = C_;
|
||
|
};
|
||
|
|
||
|
template< class Integer, Integer Value >
|
||
|
struct integer
|
||
|
{
|
||
|
static const Integer value = Value;
|
||
|
};
|
||
|
|
||
|
typedef bool_<true> true_;
|
||
|
typedef bool_<false> false_;
|
||
|
|
||
|
typedef true_ true_type;
|
||
|
typedef false_ false_type;
|
||
|
|
||
|
typedef char yes_type;
|
||
|
struct no_type
|
||
|
{
|
||
|
char padding[8];
|
||
|
};
|
||
|
|
||
|
template <bool B, class T = void>
|
||
|
struct enable_if_c {
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
struct enable_if_c<false, T> {};
|
||
|
|
||
|
template <class Cond, class T = void>
|
||
|
struct enable_if : public enable_if_c<Cond::value, T>{};
|
||
|
|
||
|
template<class F, class Param>
|
||
|
struct apply
|
||
|
{
|
||
|
typedef typename F::template apply<Param>::type type;
|
||
|
};
|
||
|
|
||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||
|
|
||
|
template <class T, class U>
|
||
|
struct is_convertible
|
||
|
{
|
||
|
static const bool value = __is_convertible_to(T, U);
|
||
|
};
|
||
|
|
||
|
#else
|
||
|
|
||
|
template <class T, class U>
|
||
|
class is_convertible
|
||
|
{
|
||
|
typedef char true_t;
|
||
|
class false_t { char dummy[2]; };
|
||
|
//use any_conversion as first parameter since in MSVC
|
||
|
//overaligned types can't go through ellipsis
|
||
|
static false_t dispatch(...);
|
||
|
static true_t dispatch(U);
|
||
|
static typename remove_reference<T>::type &trigger();
|
||
|
public:
|
||
|
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
template<
|
||
|
bool C
|
||
|
, typename T1
|
||
|
, typename T2
|
||
|
>
|
||
|
struct if_c
|
||
|
{
|
||
|
typedef T1 type;
|
||
|
};
|
||
|
|
||
|
template<
|
||
|
typename T1
|
||
|
, typename T2
|
||
|
>
|
||
|
struct if_c<false,T1,T2>
|
||
|
{
|
||
|
typedef T2 type;
|
||
|
};
|
||
|
|
||
|
template<
|
||
|
typename C
|
||
|
, typename T1
|
||
|
, typename T2
|
||
|
>
|
||
|
struct if_
|
||
|
{
|
||
|
typedef typename if_c<0 != C::value, T1, T2>::type type;
|
||
|
};
|
||
|
|
||
|
template<
|
||
|
bool C
|
||
|
, typename F1
|
||
|
, typename F2
|
||
|
>
|
||
|
struct eval_if_c
|
||
|
: if_c<C,F1,F2>::type
|
||
|
{};
|
||
|
|
||
|
template<
|
||
|
typename C
|
||
|
, typename T1
|
||
|
, typename T2
|
||
|
>
|
||
|
struct eval_if
|
||
|
: if_<C,T1,T2>::type
|
||
|
{};
|
||
|
|
||
|
// identity is an extension: it is not part of the standard.
|
||
|
template <class T>
|
||
|
struct identity
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T, bool Add>
|
||
|
struct add_const_if_c
|
||
|
{
|
||
|
typedef typename if_c
|
||
|
< Add
|
||
|
, typename add_const<T>::type
|
||
|
, T
|
||
|
>::type type;
|
||
|
};
|
||
|
|
||
|
|
||
|
//boost::alignment_of yields to 10K lines of preprocessed code, so we
|
||
|
//need an alternative
|
||
|
template <typename T> struct alignment_of;
|
||
|
|
||
|
template <typename T>
|
||
|
struct alignment_of_hack
|
||
|
{
|
||
|
char c;
|
||
|
T t;
|
||
|
alignment_of_hack();
|
||
|
};
|
||
|
|
||
|
template <unsigned A, unsigned S>
|
||
|
struct alignment_logic
|
||
|
{
|
||
|
static const std::size_t value = A < S ? A : S;
|
||
|
};
|
||
|
|
||
|
template< typename T >
|
||
|
struct alignment_of
|
||
|
{
|
||
|
static const std::size_t value = alignment_logic
|
||
|
< sizeof(alignment_of_hack<T>) - sizeof(T)
|
||
|
, sizeof(T)
|
||
|
>::value;
|
||
|
};
|
||
|
|
||
|
template<class Class>
|
||
|
class is_empty_class
|
||
|
{
|
||
|
template <typename T>
|
||
|
struct empty_helper_t1 : public T
|
||
|
{
|
||
|
empty_helper_t1();
|
||
|
int i[256];
|
||
|
};
|
||
|
|
||
|
struct empty_helper_t2
|
||
|
{ int i[256]; };
|
||
|
|
||
|
public:
|
||
|
static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
|
||
|
};
|
||
|
|
||
|
template<std::size_t S>
|
||
|
struct ls_zeros
|
||
|
{
|
||
|
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
struct ls_zeros<0>
|
||
|
{
|
||
|
static const std::size_t value = 0;
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
struct ls_zeros<1>
|
||
|
{
|
||
|
static const std::size_t value = 0;
|
||
|
};
|
||
|
|
||
|
template <typename T> struct unvoid_ref { typedef T &type; };
|
||
|
template <> struct unvoid_ref<void> { struct type_impl { }; typedef type_impl & type; };
|
||
|
template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_impl & type; };
|
||
|
|
||
|
// Infrastructure for providing a default type for T::TNAME if absent.
|
||
|
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
|
||
|
template <typename T, typename DefaultType> \
|
||
|
struct boost_intrusive_default_type_ ## TNAME \
|
||
|
{ \
|
||
|
template <typename X> \
|
||
|
static char test(int, typename X::TNAME*); \
|
||
|
\
|
||
|
template <typename X> \
|
||
|
static int test(...); \
|
||
|
\
|
||
|
struct DefaultWrap { typedef DefaultType TNAME; }; \
|
||
|
\
|
||
|
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
||
|
\
|
||
|
typedef typename \
|
||
|
::boost::intrusive::detail::if_c \
|
||
|
<value, T, DefaultWrap>::type::TNAME type; \
|
||
|
}; \
|
||
|
\
|
||
|
template <typename T, typename DefaultType> \
|
||
|
struct boost_intrusive_eval_default_type_ ## TNAME \
|
||
|
{ \
|
||
|
template <typename X> \
|
||
|
static char test(int, typename X::TNAME*); \
|
||
|
\
|
||
|
template <typename X> \
|
||
|
static int test(...); \
|
||
|
\
|
||
|
struct DefaultWrap \
|
||
|
{ typedef typename DefaultType::type TNAME; }; \
|
||
|
\
|
||
|
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
||
|
\
|
||
|
typedef typename \
|
||
|
::boost::intrusive::detail::eval_if_c \
|
||
|
< value \
|
||
|
, ::boost::intrusive::detail::identity<T> \
|
||
|
, ::boost::intrusive::detail::identity<DefaultWrap> \
|
||
|
>::type::TNAME type; \
|
||
|
}; \
|
||
|
//
|
||
|
|
||
|
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
||
|
typename INSTANTIATION_NS_PREFIX \
|
||
|
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
|
||
|
//
|
||
|
|
||
|
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
||
|
typename INSTANTIATION_NS_PREFIX \
|
||
|
boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
|
||
|
//
|
||
|
|
||
|
#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
|
||
|
template <class T>\
|
||
|
struct TRAITS_PREFIX##_bool\
|
||
|
{\
|
||
|
template<bool Add>\
|
||
|
struct two_or_three {one _[2 + Add];};\
|
||
|
template <class U> static one test(...);\
|
||
|
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
|
||
|
static const std::size_t value = sizeof(test<T>(0));\
|
||
|
};\
|
||
|
\
|
||
|
template <class T>\
|
||
|
struct TRAITS_PREFIX##_bool_is_true\
|
||
|
{\
|
||
|
static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\
|
||
|
};\
|
||
|
//
|
||
|
|
||
|
} //namespace detail
|
||
|
} //namespace intrusive
|
||
|
} //namespace boost
|
||
|
|
||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||
|
|
||
|
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP
|