mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-23 09:55:34 +00:00
592 lines
13 KiB
C++
592 lines
13 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (C) Copyright Ion Gaztanaga 2012-2012.
|
|
// 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/move for documentation.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//! \file
|
|
|
|
#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
|
#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
|
|
|
#ifndef BOOST_CONFIG_HPP
|
|
# include <boost/config.hpp>
|
|
#endif
|
|
#
|
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif
|
|
|
|
#include <cstddef> //for std::size_t
|
|
|
|
//Small meta-typetraits to support move
|
|
|
|
namespace boost {
|
|
|
|
namespace movelib {
|
|
|
|
template <class T>
|
|
struct default_delete;
|
|
|
|
} //namespace movelib {
|
|
|
|
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
|
//Forward declare boost::rv
|
|
template <class T> class rv;
|
|
#endif
|
|
|
|
namespace move_upmu {
|
|
|
|
//////////////////////////////////////
|
|
// nat
|
|
//////////////////////////////////////
|
|
struct nat{};
|
|
|
|
//////////////////////////////////////
|
|
// natify
|
|
//////////////////////////////////////
|
|
template <class T> struct natify{};
|
|
|
|
//////////////////////////////////////
|
|
// if_c
|
|
//////////////////////////////////////
|
|
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;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// if_
|
|
//////////////////////////////////////
|
|
template<typename T1, typename T2, typename T3>
|
|
struct if_ : if_c<0 != T1::value, T2, T3>
|
|
{};
|
|
|
|
//enable_if_
|
|
template <bool B, class T = nat>
|
|
struct enable_if_c
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// enable_if_c
|
|
//////////////////////////////////////
|
|
template <class T>
|
|
struct enable_if_c<false, T> {};
|
|
|
|
//////////////////////////////////////
|
|
// enable_if
|
|
//////////////////////////////////////
|
|
template <class Cond, class T = nat>
|
|
struct enable_if : public enable_if_c<Cond::value, T> {};
|
|
|
|
//////////////////////////////////////
|
|
// remove_reference
|
|
//////////////////////////////////////
|
|
template<class T>
|
|
struct remove_reference
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template<class T>
|
|
struct remove_reference<T&>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
|
|
|
template<class T>
|
|
struct remove_reference<T&&>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
#else
|
|
|
|
template<class T>
|
|
struct remove_reference< rv<T> >
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template<class T>
|
|
struct remove_reference< rv<T> &>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template<class T>
|
|
struct remove_reference< const rv<T> &>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
//////////////////////////////////////
|
|
// remove_const
|
|
//////////////////////////////////////
|
|
template< class T >
|
|
struct remove_const
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template< class T >
|
|
struct remove_const<const T>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// remove_volatile
|
|
//////////////////////////////////////
|
|
template< class T >
|
|
struct remove_volatile
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template< class T >
|
|
struct remove_volatile<volatile T>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// remove_cv
|
|
//////////////////////////////////////
|
|
template< class T >
|
|
struct remove_cv
|
|
{
|
|
typedef typename remove_volatile
|
|
<typename remove_const<T>::type>::type type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// remove_extent
|
|
//////////////////////////////////////
|
|
template<class T>
|
|
struct remove_extent
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template<class T>
|
|
struct remove_extent<T[]>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
template<class T, std::size_t N>
|
|
struct remove_extent<T[N]>
|
|
{
|
|
typedef T type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// extent
|
|
//////////////////////////////////////
|
|
|
|
template<class T, unsigned N = 0>
|
|
struct extent
|
|
{
|
|
static const std::size_t value = 0;
|
|
};
|
|
|
|
template<class T>
|
|
struct extent<T[], 0>
|
|
{
|
|
static const std::size_t value = 0;
|
|
};
|
|
|
|
template<class T, unsigned N>
|
|
struct extent<T[], N>
|
|
{
|
|
static const std::size_t value = extent<T, N-1>::value;
|
|
};
|
|
|
|
template<class T, std::size_t N>
|
|
struct extent<T[N], 0>
|
|
{
|
|
static const std::size_t value = N;
|
|
};
|
|
|
|
template<class T, std::size_t I, unsigned N>
|
|
struct extent<T[I], N>
|
|
{
|
|
static const std::size_t value = extent<T, N-1>::value;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// add_lvalue_reference
|
|
//////////////////////////////////////
|
|
template<class T>
|
|
struct add_lvalue_reference
|
|
{
|
|
typedef T& type;
|
|
};
|
|
|
|
template<class T>
|
|
struct add_lvalue_reference<T&>
|
|
{
|
|
typedef T& type;
|
|
};
|
|
|
|
template<>
|
|
struct add_lvalue_reference<void>
|
|
{
|
|
typedef void type;
|
|
};
|
|
|
|
template<>
|
|
struct add_lvalue_reference<const void>
|
|
{
|
|
typedef const void type;
|
|
};
|
|
|
|
template<>
|
|
struct add_lvalue_reference<volatile void>
|
|
{
|
|
typedef volatile void type;
|
|
};
|
|
|
|
template<>
|
|
struct add_lvalue_reference<const volatile void>
|
|
{
|
|
typedef const volatile void type;
|
|
};
|
|
|
|
template<class T>
|
|
struct add_const_lvalue_reference
|
|
{
|
|
typedef typename remove_reference<T>::type t_unreferenced;
|
|
typedef const t_unreferenced t_unreferenced_const;
|
|
typedef typename add_lvalue_reference
|
|
<t_unreferenced_const>::type type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// is_same
|
|
//////////////////////////////////////
|
|
template<class T, class U>
|
|
struct is_same
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
template<class T>
|
|
struct is_same<T, T>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// is_pointer
|
|
//////////////////////////////////////
|
|
template< class T >
|
|
struct is_pointer
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
template< class T >
|
|
struct is_pointer<T*>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// is_reference
|
|
//////////////////////////////////////
|
|
template< class T >
|
|
struct is_reference
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
template< class T >
|
|
struct is_reference<T&>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
|
|
|
template< class T >
|
|
struct is_reference<T&&>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
#endif
|
|
|
|
//////////////////////////////////////
|
|
// is_lvalue_reference
|
|
//////////////////////////////////////
|
|
template<class T>
|
|
struct is_lvalue_reference
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
template<class T>
|
|
struct is_lvalue_reference<T&>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// is_array
|
|
//////////////////////////////////////
|
|
template<class T>
|
|
struct is_array
|
|
{
|
|
static const bool value = false;
|
|
};
|
|
|
|
template<class T>
|
|
struct is_array<T[]>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
template<class T, std::size_t N>
|
|
struct is_array<T[N]>
|
|
{
|
|
static const bool value = true;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// has_pointer_type
|
|
//////////////////////////////////////
|
|
template <class T>
|
|
struct has_pointer_type
|
|
{
|
|
struct two { char c[2]; };
|
|
template <class U> static two test(...);
|
|
template <class U> static char test(typename U::pointer* = 0);
|
|
static const bool value = sizeof(test<T>(0)) == 1;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// pointer_type
|
|
//////////////////////////////////////
|
|
template <class T, class D, bool = has_pointer_type<D>::value>
|
|
struct pointer_type_imp
|
|
{
|
|
typedef typename D::pointer type;
|
|
};
|
|
|
|
template <class T, class D>
|
|
struct pointer_type_imp<T, D, false>
|
|
{
|
|
typedef typename remove_extent<T>::type* type;
|
|
};
|
|
|
|
template <class T, class D>
|
|
struct pointer_type
|
|
{
|
|
typedef typename pointer_type_imp
|
|
<typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
|
|
};
|
|
|
|
//////////////////////////////////////
|
|
// is_convertible
|
|
//////////////////////////////////////
|
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
|
|
|
//use intrinsic since in MSVC
|
|
//overaligned types can't go through ellipsis
|
|
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 typename add_lvalue_reference<T>::type t_reference;
|
|
typedef char true_t;
|
|
class false_t { char dummy[2]; };
|
|
static false_t dispatch(...);
|
|
static true_t dispatch(U);
|
|
static t_reference trigger();
|
|
public:
|
|
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
|
};
|
|
|
|
#endif
|
|
|
|
//////////////////////////////////////
|
|
// is_unary_function
|
|
//////////////////////////////////////
|
|
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
|
|
#define BOOST_MOVE_TT_DECL __cdecl
|
|
#else
|
|
#define BOOST_MOVE_TT_DECL
|
|
#endif
|
|
|
|
#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE)
|
|
#define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
|
#endif
|
|
|
|
template <typename T>
|
|
struct is_unary_function_impl
|
|
{ static const bool value = false; };
|
|
|
|
// avoid duplicate definitions of is_unary_function_impl
|
|
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (*)()>
|
|
{ static const bool value = true; };
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (*)(...)>
|
|
{ static const bool value = true; };
|
|
|
|
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (__stdcall*)()>
|
|
{ static const bool value = true; };
|
|
|
|
#ifndef _MANAGED
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (__fastcall*)()>
|
|
{ static const bool value = true; };
|
|
|
|
#endif
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (__cdecl*)()>
|
|
{ static const bool value = true; };
|
|
|
|
template <typename R>
|
|
struct is_unary_function_impl<R (__cdecl*)(...)>
|
|
{ static const bool value = true; };
|
|
|
|
#endif
|
|
|
|
// avoid duplicate definitions of is_unary_function_impl
|
|
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (*)(T0)>
|
|
{ static const bool value = true; };
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (*)(T0...)>
|
|
{ static const bool value = true; };
|
|
|
|
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (__stdcall*)(T0)>
|
|
{ static const bool value = true; };
|
|
|
|
#ifndef _MANAGED
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (__fastcall*)(T0)>
|
|
{ static const bool value = true; };
|
|
|
|
#endif
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (__cdecl*)(T0)>
|
|
{ static const bool value = true; };
|
|
|
|
template <typename R, class T0>
|
|
struct is_unary_function_impl<R (__cdecl*)(T0...)>
|
|
{ static const bool value = true; };
|
|
|
|
#endif
|
|
|
|
template <typename T>
|
|
struct is_unary_function_impl<T&>
|
|
{ static const bool value = false; };
|
|
|
|
template<typename T>
|
|
struct is_unary_function
|
|
{ static const bool value = is_unary_function_impl<T>::value; };
|
|
|
|
//////////////////////////////////////
|
|
// has_virtual_destructor
|
|
//////////////////////////////////////
|
|
#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
|
|
|| (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
|
|
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
|
#elif defined(BOOST_CLANG) && defined(__has_feature)
|
|
# if __has_feature(has_virtual_destructor)
|
|
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
|
# endif
|
|
#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
|
|
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
|
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
|
|
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
|
#elif defined(__CODEGEARC__)
|
|
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
|
#endif
|
|
|
|
#ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
|
|
template<class T>
|
|
struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); };
|
|
#else
|
|
//If no intrinsic is available you trust the programmer knows what is doing
|
|
template<class T>
|
|
struct has_virtual_destructor{ static const bool value = true; };
|
|
#endif
|
|
|
|
//////////////////////////////////////
|
|
// missing_virtual_destructor
|
|
//////////////////////////////////////
|
|
|
|
template< class T, class U
|
|
, bool enable = is_convertible< U*, T*>::value &&
|
|
!is_array<T>::value &&
|
|
!is_same<typename remove_cv<T>::type, void>::value &&
|
|
!is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
|
|
>
|
|
struct missing_virtual_destructor_default_delete
|
|
{ static const bool value = !has_virtual_destructor<T>::value; };
|
|
|
|
template<class T, class U>
|
|
struct missing_virtual_destructor_default_delete<T, U, false>
|
|
{ static const bool value = false; };
|
|
|
|
template<class Deleter, class U>
|
|
struct missing_virtual_destructor
|
|
{ static const bool value = false; };
|
|
|
|
template<class T, class U>
|
|
struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
|
|
: missing_virtual_destructor_default_delete<T, U>
|
|
{};
|
|
|
|
} //namespace move_upmu {
|
|
} //namespace boost {
|
|
|
|
#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|