mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Added type_traits header
This commit is contained in:
parent
cb40851388
commit
3d335fbe41
309
type_traits.h
Normal file
309
type_traits.h
Normal file
@ -0,0 +1,309 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __etl_type_traits__
|
||||
#define __etl_type_traits__
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
///\defgroup type_traits type_traits
|
||||
/// A set of type traits definitions for compilers that do not support the standard header.
|
||||
/// \ingroup utilities
|
||||
|
||||
namespace etl
|
||||
{
|
||||
/// integral_constant
|
||||
///\ingroup type_traits
|
||||
template <typename T, const T VALUE>
|
||||
struct integral_constant
|
||||
{
|
||||
static const T value = VALUE;
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
operator value_type() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
/// integral_constant specialisations
|
||||
///\ingroup type_traits
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
|
||||
/// remove_reference
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_reference { typedef T type; };
|
||||
template <typename T> struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
/// add_reference
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct add_reference { typedef T& type; };
|
||||
template <typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
/// remove_pointer
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_pointer { typedef T type; };
|
||||
template <typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
/// add_pointer
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct add_pointer { typedef typename remove_reference<T>::type* type; };
|
||||
|
||||
/// is_const
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_const : false_type { };
|
||||
template <typename T> struct is_const<const T> : true_type { };
|
||||
template <typename T> struct is_const<const volatile T> : true_type { };
|
||||
|
||||
/// remove_const
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_const { typedef T type; };
|
||||
template <typename T> struct remove_const<const T> { typedef T type; };
|
||||
|
||||
/// add_const
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct add_const { typedef const T type; };
|
||||
template <typename T> struct add_const<const T> { typedef const T type; };
|
||||
|
||||
/// is_volatile
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_volatile : false_type { };
|
||||
template <typename T> struct is_volatile<volatile T> : true_type { };
|
||||
template <typename T> struct is_volatile<const volatile T> : true_type { };
|
||||
|
||||
/// remove_volatile
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_volatile { typedef T type; };
|
||||
template <typename T> struct remove_volatile<volatile T> { typedef T type; };
|
||||
|
||||
/// add_volatile
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct add_volatile { typedef volatile T type; };
|
||||
template <typename T> struct add_volatile<volatile T> { typedef volatile T type; };
|
||||
|
||||
/// remove_cv
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_cv
|
||||
{
|
||||
typedef typename remove_volatile<typename remove_const<T>::type>::type type;
|
||||
};
|
||||
|
||||
/// add_cv
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct add_cv
|
||||
{
|
||||
typedef typename add_volatile<typename add_const<T>::type>::type type;
|
||||
};
|
||||
|
||||
/// is_integral
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_integral : false_type { };
|
||||
template <> struct is_integral<bool> : true_type { };
|
||||
template <> struct is_integral<char> : true_type { };
|
||||
template <> struct is_integral<unsigned char> : true_type { };
|
||||
template <> struct is_integral<signed char> : true_type { };
|
||||
template <> struct is_integral<wchar_t> : true_type { };
|
||||
template <> struct is_integral<short> : true_type { };
|
||||
template <> struct is_integral<unsigned short> : true_type { };
|
||||
template <> struct is_integral<int> : true_type { };
|
||||
template <> struct is_integral<unsigned int> : true_type { };
|
||||
template <> struct is_integral<long> : true_type { };
|
||||
template <> struct is_integral<unsigned long> : true_type { };
|
||||
template <> struct is_integral<long long> : true_type { };
|
||||
template <> struct is_integral<unsigned long long> : true_type { };
|
||||
template <typename T> struct is_integral<const T> : is_integral<T> { };
|
||||
template <typename T> struct is_integral<volatile T> : is_integral<T> { };
|
||||
template <typename T> struct is_integral<const volatile T> : is_integral<T> { };
|
||||
|
||||
/// is_signed
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_signed : false_type { };
|
||||
template <> struct is_signed<char> : true_type { };
|
||||
template <> struct is_signed<signed char> : true_type { };
|
||||
template <> struct is_signed<short> : true_type { };
|
||||
template <> struct is_signed<int> : true_type { };
|
||||
template <> struct is_signed<long> : true_type { };
|
||||
template <> struct is_signed<long long> : true_type { };
|
||||
template <> struct is_signed<float> : true_type{};
|
||||
template <> struct is_signed<double> : true_type{};
|
||||
template <> struct is_signed<long double> : true_type{};
|
||||
template <typename T> struct is_signed<const T> : is_signed<T> { };
|
||||
template <typename T> struct is_signed<volatile T> : is_signed<T> { };
|
||||
template <typename T> struct is_signed<const volatile T> : is_signed<T> { };
|
||||
|
||||
/// is_unsigned
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_unsigned : false_type { };
|
||||
template <> struct is_unsigned<bool> : true_type { };
|
||||
template <> struct is_unsigned<unsigned char> : true_type { };
|
||||
template <> struct is_unsigned<wchar_t> : true_type { };
|
||||
template <> struct is_unsigned<unsigned short> : true_type { };
|
||||
template <> struct is_unsigned<unsigned int> : true_type { };
|
||||
template <> struct is_unsigned<unsigned long> : true_type { };
|
||||
template <> struct is_unsigned<unsigned long long> : true_type { };
|
||||
template <typename T> struct is_unsigned<const T> : is_unsigned<T> { };
|
||||
template <typename T> struct is_unsigned<volatile T> : is_unsigned<T> { };
|
||||
template <typename T> struct is_unsigned<const volatile T> : is_unsigned<T> { };
|
||||
|
||||
/// is_floating_point
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_floating_point : false_type { };
|
||||
template <> struct is_floating_point<float> : true_type { };
|
||||
template <> struct is_floating_point<double> : true_type { };
|
||||
template <> struct is_floating_point<long double> : true_type { };
|
||||
template <typename T> struct is_floating_point<const T> : is_floating_point<T> { };
|
||||
template <typename T> struct is_floating_point<volatile T> : is_floating_point<T> { };
|
||||
template <typename T> struct is_floating_point<const volatile T> : is_floating_point<T> { };
|
||||
|
||||
/// is_same
|
||||
///\ingroup type_traits
|
||||
template <typename T1, typename T2> struct is_same : public false_type { };
|
||||
template <typename T> struct is_same<T, T> : public true_type { };
|
||||
|
||||
/// is_void
|
||||
///\ingroup type_traits
|
||||
template<typename T> struct is_void : false_type { };
|
||||
template<> struct is_void<void> : true_type { };
|
||||
|
||||
/// is_arithmetic
|
||||
///\ingroup type_traits
|
||||
template<typename T> struct is_arithmetic : integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value> {};
|
||||
|
||||
/// is_fundamental
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_fundamental : integral_constant<bool, is_arithmetic<T>::value ||
|
||||
is_void<T>::value ||
|
||||
is_same<nullptr_t,
|
||||
typename remove_cv<T>::type>::value> {};
|
||||
|
||||
/// is_array
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_array : false_type {};
|
||||
template <typename T> struct is_array<T[]> : true_type {};
|
||||
template <typename T, std::size_t N> struct is_array<T[N]> : true_type {};
|
||||
|
||||
/// is_pointer
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_pointer : false_type { };
|
||||
template <typename T> struct is_pointer<T*> : true_type { };
|
||||
|
||||
/// is_reference
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct is_reference : false_type {};
|
||||
template <typename T> struct is_reference<T&> : true_type {};
|
||||
|
||||
/// make_signed
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct make_signed { typedef T type; };
|
||||
template <> struct make_signed<char> { typedef signed char type; };
|
||||
template <> struct make_signed<unsigned char> { typedef signed char type; };
|
||||
template <> struct make_signed<wchar_t> { typedef short type; };
|
||||
template <> struct make_signed<unsigned short> { typedef short type; };
|
||||
template <> struct make_signed<unsigned int> { typedef int type; };
|
||||
template <> struct make_signed<unsigned long> { typedef long type; };
|
||||
template <> struct make_signed<unsigned long long> { typedef long long type; };
|
||||
template <typename T> struct make_signed<const T> : add_const<typename make_signed<T>::type> { };
|
||||
template <typename T> struct make_signed<volatile T> : add_volatile<typename make_signed<T>::type> { };
|
||||
template <typename T> struct make_signed<const volatile T> : add_const<typename add_volatile<typename make_signed<T>::type>::type> { };
|
||||
|
||||
/// make_unsigned
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct make_unsigned { typedef T type; };
|
||||
template <> struct make_unsigned<char> { typedef unsigned char type; };
|
||||
template <> struct make_unsigned<signed char> { typedef unsigned char type; };
|
||||
template <> struct make_unsigned<wchar_t> { typedef unsigned short type; };
|
||||
template <> struct make_unsigned<short> { typedef unsigned short type; };
|
||||
template <> struct make_unsigned<int> { typedef unsigned int type; };
|
||||
template <> struct make_unsigned<long> { typedef unsigned long type; };
|
||||
template <> struct make_unsigned<long long> { typedef unsigned long long type; };
|
||||
template <typename T> struct make_unsigned<const T> : add_const<typename make_unsigned<T>::type> { };
|
||||
template <typename T> struct make_unsigned<volatile T> : add_volatile<typename make_unsigned<T>::type> { };
|
||||
template <typename T> struct make_unsigned<const volatile T> : add_const<typename add_volatile<typename make_unsigned<T>::type>::type> { };
|
||||
|
||||
/// enable_if
|
||||
///\ingroup type_traits
|
||||
template <bool B, typename T = void> struct enable_if { };
|
||||
template <typename T> struct enable_if<true, T> { typedef T type; };
|
||||
|
||||
/// conditional
|
||||
///\ingroup type_traits
|
||||
template <bool B, typename T, typename F> struct conditional { typedef T type; };
|
||||
template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
|
||||
|
||||
/// extent
|
||||
///\ingroup type_traits
|
||||
template <typename T, size_t N = 0>
|
||||
struct extent : std::integral_constant<std::size_t, 0> {};
|
||||
|
||||
template <typename T>
|
||||
struct extent<T[], 0> : std::integral_constant<std::size_t, 0> {};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct extent<T[], N> : std::integral_constant<std::size_t, std::extent<T, N - 1>::value> {};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct extent<T[N], 0> : std::integral_constant<std::size_t, N> {};
|
||||
|
||||
template <typename T, std::size_t I, size_t N>
|
||||
struct extent<T[I], N> : std::integral_constant<std::size_t, std::extent<T, N - 1>::value> {};
|
||||
|
||||
/// remove_extent
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_extent { typedef T type; };
|
||||
template <typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template <typename T, std::size_t N> struct remove_extent<T[N]> { typedef T type;};
|
||||
|
||||
/// remove_all_extents
|
||||
///\ingroup type_traits
|
||||
template <typename T> struct remove_all_extents { typedef T type;};
|
||||
template <typename T> struct remove_all_extents<T[]> { typedef typename remove_all_extents<T>::type type; };
|
||||
template <typename T, std::size_t N> struct remove_all_extents<T[N]> { typedef typename remove_all_extents<T>::type type; };
|
||||
|
||||
/// rank
|
||||
///\ingroup type_traits
|
||||
template <typename T>struct rank : integral_constant<std::size_t, 0> {};
|
||||
template <typename T> struct rank<T[]> : public integral_constant<std::size_t, rank<T>::value + 1> {};
|
||||
template <typename T, size_t N> struct rank<T[N]> : public integral_constant<std::size_t, rank<T>::value + 1> {};
|
||||
|
||||
/// Alignment templates.
|
||||
/// These require compiler specific intrinsics.
|
||||
///\ingroup type_traits
|
||||
#ifdef _MSC_VER
|
||||
// alignment_of
|
||||
template <typename T> struct alignment_of : integral_constant <size_t, __alignof(T)> {};
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
// alignment_of
|
||||
template <typename T> struct alignment_of : integral_constant <size_t, __alignof__(T)> {};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user