DYT/Tool/3rdParty_x64/include/dcmtk/ofstd/oftraits.h
2024-11-22 23:19:31 +08:00

498 lines
15 KiB
C++

/*
*
* Copyright (C) 2014, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: ofstd
*
* Author: Jan Schlamelcher
*
* Purpose:
* Implementing a subset of C++11's type_traits for old compilers.
*
*/
#ifndef OFTRAITS_H
#define OFTRAITS_H
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/ofstd/oftypes.h"
// use native classes if C++11 is supported
#ifdef DCMTK_USE_CXX11_STL
#include <type_traits>
template<bool B,typename... ARGS>
using OFenable_if = std::enable_if<B,ARGS...>;
template<bool B,typename... ARGS>
using OFconditional = std::conditional<B,ARGS...>;
template<typename T,T Value>
using OFintegral_constant = std::integral_constant<T,Value>;
template<typename... ARGS>
using OFis_signed = std::is_signed<ARGS...>;
template<typename... ARGS>
using OFis_unsigned = std::is_unsigned<ARGS...>;
template<typename... ARGS>
using OFis_same = std::is_same<ARGS...>;
template<typename... ARGS>
using OFis_array = std::is_array<ARGS...>;
template<typename... ARGS>
using OFis_function = std::is_function<ARGS...>;
template<typename... ARGS>
using OFis_integral = std::is_integral<ARGS...>;
template<typename... ARGS>
using OFremove_pointer = std::remove_pointer<ARGS...>;
template<typename... ARGS>
using OFremove_reference = std::remove_reference<ARGS...>;
template<typename... ARGS>
using OFremove_cv = std::remove_cv<ARGS...>;
template<typename... ARGS>
using OFremove_const = std::remove_const<ARGS...>;
template<typename... ARGS>
using OFremove_volatile = std::remove_volatile<ARGS...>;
template<typename... ARGS>
using OFremove_extent = std::remove_extent<ARGS...>;
template<typename... ARGS>
using OFadd_pointer = std::add_pointer<ARGS...>;
template<typename... ARGS>
using OFdecay = std::decay<ARGS...>;
using OFtrue_type = std::true_type;
using OFfalse_type = std::false_type;
#elif !defined(DOXYGEN) // fallback implementations
template<OFBool B,typename T=void>
struct OFenable_if {};
template<typename T>
struct OFenable_if<OFTrue,T> { typedef T type; };
template<OFBool B,typename T,typename F>
struct OFconditional { typedef T type; };
template<typename T,typename F>
struct OFconditional<OFFalse,T,F> { typedef F type; };
template<typename T,T Value>
struct OFintegral_constant { static const T value = Value; };
template<typename T,T Value>
const T OFintegral_constant<T,Value>::value;
typedef OFintegral_constant<OFBool,OFTrue> OFtrue_type;
typedef OFintegral_constant<OFBool,OFFalse> OFfalse_type;
template<typename T>
struct OFis_signed : OFfalse_type {};
template<typename T>
struct OFis_unsigned : OFfalse_type {};
template<typename T0,typename T1>
struct OFis_same : OFfalse_type {};
template<typename T>
struct OFis_array : OFfalse_type {};
template<typename T>
struct OFis_function : OFfalse_type {};
template<typename T>
struct OFis_integral : OFfalse_type {};
template<typename T>
struct OFremove_reference { typedef T type; };
template<typename T>
struct OFremove_const { typedef T type; };
template<typename T>
struct OFremove_volatile { typedef T type; };
template<typename T>
struct OFremove_extent { typedef T type; };
#ifdef HAVE_CXX_BOOL
template<>
struct OFis_unsigned<bool> : OFtrue_type {};
#endif
#ifndef C_CHAR_UNSIGNED
template<>
struct OFis_signed<char> : OFtrue_type {};
#else
template<>
struct OFis_unsigned<char> : OFtrue_type {};
#endif
template<>
struct OFis_signed<signed char> : OFtrue_type {};
template<>
struct OFis_unsigned<unsigned char> : OFtrue_type {};
template<>
struct OFis_signed<signed short> : OFtrue_type {};
template<>
struct OFis_unsigned<unsigned short> : OFtrue_type {};
template<>
struct OFis_signed<signed int> : OFtrue_type {};
template<>
struct OFis_unsigned<unsigned int> : OFtrue_type {};
template<>
struct OFis_signed<signed long> : OFtrue_type {};
template<>
struct OFis_unsigned<unsigned long> : OFtrue_type {};
#ifdef OFlonglong
template<>
struct OFis_signed<OFlonglong> : OFtrue_type {};
#endif
#ifdef OFulonglong
template<>
struct OFis_unsigned<OFulonglong> : OFtrue_type {};
#endif
template<>
struct OFis_signed<float> : OFtrue_type {};
template<>
struct OFis_signed<double> : OFtrue_type {};
template<typename T>
struct OFis_same<T,T> : OFtrue_type {};
template<typename T>
struct OFis_array<T[]> : OFtrue_type {};
template<typename T,size_t N>
struct OFis_array<T[N]> : OFtrue_type {};
template<typename R>
struct OFis_function<R()> : OFtrue_type {};
template<typename R>
struct OFis_function<R(...)> : OFtrue_type {};
template<typename R,typename T0>
struct OFis_function<R(T0)> : OFtrue_type {};
template<typename R,typename T0>
struct OFis_function<R(T0,...)> : OFtrue_type {};
template<typename R,typename T0,typename T1>
struct OFis_function<R(T0,T1)> : OFtrue_type {};
template<typename R,typename T0,typename T1>
struct OFis_function<R(T0,T1,...)> : OFtrue_type {};
template<typename R,typename T0,typename T1,typename T2>
struct OFis_function<R(T0,T1,T2)> : OFtrue_type {};
template<typename R,typename T0,typename T1,typename T2>
struct OFis_function<R(T0,T1,T2,...)> : OFtrue_type {};
/* TODO: handle functions with more than three arguments */
template<>
struct OFis_integral<char> : OFtrue_type {};
template<>
struct OFis_integral<signed char> : OFtrue_type {};
template<>
struct OFis_integral<unsigned char> : OFtrue_type {};
template<>
struct OFis_integral<signed short> : OFtrue_type {};
template<>
struct OFis_integral<unsigned short> : OFtrue_type {};
template<>
struct OFis_integral<signed int> : OFtrue_type {};
template<>
struct OFis_integral<unsigned int> : OFtrue_type {};
template<>
struct OFis_integral<signed long> : OFtrue_type {};
template<>
struct OFis_integral<unsigned long> : OFtrue_type {};
#ifdef OFlonglong
template<>
struct OFis_integral<OFlonglong> : OFtrue_type {};
#endif
#ifdef OFulonglong
template<>
struct OFis_integral<OFulonglong> : OFtrue_type {};
#endif
template<typename T>
struct OFremove_reference<T&> { typedef T type; };
template<typename T>
struct OFremove_const<const T> { typedef T type; };
template<typename T>
struct OFremove_volatile<volatile T> { typedef T type; };
template<typename T>
struct OFremove_extent<T[]> { typedef T type; };
template<typename T,size_t N>
struct OFremove_extent<T[N]> { typedef T type;};
template<typename T>
struct OFremove_cv
{
typedef typename OFremove_volatile<typename OFremove_const<T>::type>::type type;
};
template< class T > struct OFremove_pointer {
typedef T type;
};
template< class T > struct OFremove_pointer<T*> {
typedef T type;
};
template< class T > struct OFremove_pointer<T* const> {
typedef T type;
};
template< class T > struct OFremove_pointer<T* volatile> {
typedef T type;
};
template< class T > struct OFremove_pointer<T* const volatile> {
typedef T type;
};
template<typename T>
struct OFadd_pointer
{
typedef typename OFremove_reference<T>::type* type;
};
template<typename T>
struct OFdecay
{
typedef typename OFconditional
<
OFis_array<typename OFremove_reference<T>::type>::value,
typename OFremove_extent<typename OFremove_reference<T>::type>::type*,
typename OFconditional
<
OFis_function<typename OFremove_reference<T>::type>::value,
typename OFadd_pointer<typename OFremove_reference<T>::type>::type,
typename OFremove_cv<typename OFremove_reference<T>::type>::type
>::type
>::type type;
};
#else // for doxygen
/** Metafunction to conditionally remove functions and classes from overload
* resolution.
* This metafunction is a convenient way to leverage SFINAE to conditionally
* remove functions and classes from overload resolution based on type traits
* and to provide separate function overloads and specializations for different
* type traits. OFenable_if can be used as an additional function argument
* (not applicable to operator overloads), as a return type (not applicable to
* constructors and destructors), or as a class template or function template
* parameter.
* @see http://en.cppreference.com/w/cpp/types/enable_if for details.
* @tparam B If B is OFTrue, OFenable_if has a public member typedef type, equal
* to T; otherwise, there is no member typedef.
* @tparam T The type to use for "type" if B equals OFTrue. Defaults to void.
*/
template<OFBool B,typename T=void>
struct OFenable_if {};
/** Metafunction to select one of two types depending on a template parameter.
* @see http://en.cppreference.com/w/cpp/types/conditional for details.
* @tparam B If B is OFtrue, OFconditional has a public member typedef type, equal
* to T; otherwise, type equals F.
* @tparam T The type to use for "type" if B equals OFTrue.
* @tparam F The type to use for "type" if B equals OFFalse.
*/
template<OFBool B,typename T,typename F>
struct OFconditional {};
/** OFintegral_constant wraps a static constant of specified type.
* OFintegral_constant allows to manage compile-time constants as types,
* which allows to use them as template parameters. The value of an integral
* constant C can be accessed as C::value.
* @see http://en.cppreference.com/w/cpp/types/integral_constant for details.
* @tparam T The integral type to use as base type for the constant, e.g. "int".
* @tparam Value The value of the constant, e.g. 42.
*/
template<typename T,T Value>
struct OFintegral_constant {};
/** Metafunction to determine if a type is signed.
* OFis_signed is based on OFintegral_constant and evaluates to OFTrue if
* a signed type is probed, otherwise OFis_signed<...>::value equals OFFalse.
* @see http://en.cppreference.com/w/cpp/types/is_signed for details.
* @tparam T The type to inspect, e.g. "int" or "float".
*/
template<typename T>
struct OFis_signed {};
/** Metafunction to determine if a type is unsigned.
* OFis_unsigned is based on OFintegral_constant and evaluates to OFTrue if
* an unsigned type is probed, otherwise OFis_unsigned<...>::value equals OFFalse.
* @see http://en.cppreference.com/w/cpp/types/is_unsigned for details.
* @tparam T The type to inspect, e.g. "unsigned int".
*/
template<typename T>
struct OFis_unsigned {};
/** Metafunction to determine if two types are identical.
* OFis_same is based on OFintegral_constant and evaluates to OFTrue if
* two identical types are given, otherwise OFis_same<...>::value equals OFFalse.
* @see http://en.cppreference.com/w/cpp/types/is_same for details.
* @tparam T0 The first type to compare.
* @tparam T1 The second type to compare.
*/
template<typename T0,typename T1>
struct OFis_same {};
/** Metafunction to determine if a type is an array.
* OFis_array is based on OFintegral_constant and evaluates to OFTrue if
* an array type is probed, otherwise OFis_array<...>::value equals OFFalse.
* @see http://en.cppreference.com/w/cpp/types/is_array for details.
* @tparam T The type to inspect, e.g. "int[]".
*/
template<typename T>
struct OFis_array {};
/** Metafunction to determine if a type refers to function.
* OFis_function is based on OFintegral_constant and evaluates to OFTrue if
* a function type is probed, otherwise OFis_function<...>::value equals OFFalse.
* @note The current implementation only supports detecting functions taking up
* to three arguments.
* @see http://en.cppreference.com/w/cpp/types/is_function for details.
* @tparam T The type to inspect, e.g. "int(OFBool,const OFString&)".
*/
template<typename T>
struct OFis_function {};
/** Metafunction to determine if a type is an integer.
* OFis_integral is based on OFintegral_constant and evaluates to OFTrue if
* an integral type is probed, otherwise OFis_integral<...>::value equals OFFalse.
* @see http://en.cppreference.com/w/cpp/types/is_integral for details.
* @tparam T The type to inspect, e.g. "int" or "long".
*/
template<typename T>
struct OFis_integral {};
/** Metafunction to remove the reference from a type.
* OFremove_reference provides a public member typedef "type" for the type
* referred by the given parameter.
* @see http://en.cppreference.com/w/cpp/types/remove_reference for details.
* @tparam T The type its reference should be removed.
*/
template<typename T>
struct OFremove_reference {};
/** Metafunction to remove the const modifier from a type.
* OFremove_const provides a public member typedef "type" that is equal
* to the given parameter except existing const modifiers are removed.
* @see http://en.cppreference.com/w/cpp/types/remove_const for details.
* @tparam T The type its const modifiers should be removed.
*/
template<typename T>
struct OFremove_const {};
/** Metafunction to remove the volatile modifier from a type.
* OFremove_volatile provides a public member typedef "type" that is equal
* to the given parameter except existing volatile modifiers are removed.
* @see http://en.cppreference.com/w/cpp/types/remove_volatile for details.
* @tparam T The type its volatile modifiers should be removed.
*/
template<typename T>
struct OFremove_volatile {};
/** Metafunction to remove the extent from an array type.
* OFremove_extent provides a public member typedef "type" that is equal
* to the given parameter except existing extents are removed.
* @note If the parameter is a multidimensional array, only the first
* dimension is removed.
* @see http://en.cppreference.com/w/cpp/types/remove_extent for details.
* @tparam T The type its extents should be removed.
*/
template<typename T>
struct OFremove_extent {};
/** Metafunction to remove both the const and the volatile modifier from a type.
* OFremove_cv provides a public member typedef "type" that is equal
* to the given parameter except existing const and volatile modifiers are removed.
* @see http://en.cppreference.com/w/cpp/types/remove_cv for details.
* @tparam T The type its const and volatile modifiers should be removed.
*/
template<typename T>
struct OFremove_cv {};
/** Metafunction to add another pointer-level to a type.
* OFadd_pointer provides a public member typedef "type" that is equal
* to the given parameter except existing references are removed and instead
* another pointer-level is added.
* @see http://en.cppreference.com/w/cpp/types/add_pointer for details.
* @tparam T The type to add a pointer-level to.
*/
template<typename T>
struct OFadd_pointer {};
/** Metafunction to remove several modifiers from a type, for example to realize by-value
* parameter passing.
* OFdecay applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit
* conversions to the parameter type, removes cv-qualifiers, and defines the resulting type
* as the public member typedef "type".
* @see http://en.cppreference.com/w/cpp/types/decay for details.
* @tparam T The type to decay.
*/
template<typename T>
struct OFdecay {};
/// An integral constant evaluating to OFTrue (OFtrue_type::value == OFTrue).
typedef unspecified OFtrue_type;
/// An integral constant evaluating to OFFalse (OFtrue_type::value == OFFalse).
typedef unspecified OFfalse_type;
#endif // C++11
#endif // OFTRAITS_H