diff --git a/type_traits.h b/type_traits.h new file mode 100644 index 00000000..f02564a9 --- /dev/null +++ b/type_traits.h @@ -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 + +///\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 + 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 false_type; + typedef integral_constant true_type; + + /// remove_reference + ///\ingroup type_traits + template struct remove_reference { typedef T type; }; + template struct remove_reference { typedef T type; }; + + /// add_reference + ///\ingroup type_traits + template struct add_reference { typedef T& type; }; + template struct add_reference { typedef T& type; }; + + /// remove_pointer + ///\ingroup type_traits + template struct remove_pointer { typedef T type; }; + template struct remove_pointer { typedef T type; }; + + /// add_pointer + ///\ingroup type_traits + template struct add_pointer { typedef typename remove_reference::type* type; }; + + /// is_const + ///\ingroup type_traits + template struct is_const : false_type { }; + template struct is_const : true_type { }; + template struct is_const : true_type { }; + + /// remove_const + ///\ingroup type_traits + template struct remove_const { typedef T type; }; + template struct remove_const { typedef T type; }; + + /// add_const + ///\ingroup type_traits + template struct add_const { typedef const T type; }; + template struct add_const { typedef const T type; }; + + /// is_volatile + ///\ingroup type_traits + template struct is_volatile : false_type { }; + template struct is_volatile : true_type { }; + template struct is_volatile : true_type { }; + + /// remove_volatile + ///\ingroup type_traits + template struct remove_volatile { typedef T type; }; + template struct remove_volatile { typedef T type; }; + + /// add_volatile + ///\ingroup type_traits + template struct add_volatile { typedef volatile T type; }; + template struct add_volatile { typedef volatile T type; }; + + /// remove_cv + ///\ingroup type_traits + template struct remove_cv + { + typedef typename remove_volatile::type>::type type; + }; + + /// add_cv + ///\ingroup type_traits + template struct add_cv + { + typedef typename add_volatile::type>::type type; + }; + + /// is_integral + ///\ingroup type_traits + template struct is_integral : false_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template <> struct is_integral : true_type { }; + template struct is_integral : is_integral { }; + template struct is_integral : is_integral { }; + template struct is_integral : is_integral { }; + + /// is_signed + ///\ingroup type_traits + template struct is_signed : false_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type { }; + template <> struct is_signed : true_type{}; + template <> struct is_signed : true_type{}; + template <> struct is_signed : true_type{}; + template struct is_signed : is_signed { }; + template struct is_signed : is_signed { }; + template struct is_signed : is_signed { }; + + /// is_unsigned + ///\ingroup type_traits + template struct is_unsigned : false_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template <> struct is_unsigned : true_type { }; + template struct is_unsigned : is_unsigned { }; + template struct is_unsigned : is_unsigned { }; + template struct is_unsigned : is_unsigned { }; + + /// is_floating_point + ///\ingroup type_traits + template struct is_floating_point : false_type { }; + template <> struct is_floating_point : true_type { }; + template <> struct is_floating_point : true_type { }; + template <> struct is_floating_point : true_type { }; + template struct is_floating_point : is_floating_point { }; + template struct is_floating_point : is_floating_point { }; + template struct is_floating_point : is_floating_point { }; + + /// is_same + ///\ingroup type_traits + template struct is_same : public false_type { }; + template struct is_same : public true_type { }; + + /// is_void + ///\ingroup type_traits + template struct is_void : false_type { }; + template<> struct is_void : true_type { }; + + /// is_arithmetic + ///\ingroup type_traits + template struct is_arithmetic : integral_constant::value || is_floating_point::value> {}; + + /// is_fundamental + ///\ingroup type_traits + template struct is_fundamental : integral_constant::value || + is_void::value || + is_same::type>::value> {}; + + /// is_array + ///\ingroup type_traits + template struct is_array : false_type {}; + template struct is_array : true_type {}; + template struct is_array : true_type {}; + + /// is_pointer + ///\ingroup type_traits + template struct is_pointer : false_type { }; + template struct is_pointer : true_type { }; + + /// is_reference + ///\ingroup type_traits + template struct is_reference : false_type {}; + template struct is_reference : true_type {}; + + /// make_signed + ///\ingroup type_traits + template struct make_signed { typedef T type; }; + template <> struct make_signed { typedef signed char type; }; + template <> struct make_signed { typedef signed char type; }; + template <> struct make_signed { typedef short type; }; + template <> struct make_signed { typedef short type; }; + template <> struct make_signed { typedef int type; }; + template <> struct make_signed { typedef long type; }; + template <> struct make_signed { typedef long long type; }; + template struct make_signed : add_const::type> { }; + template struct make_signed : add_volatile::type> { }; + template struct make_signed : add_const::type>::type> { }; + + /// make_unsigned + ///\ingroup type_traits + template struct make_unsigned { typedef T type; }; + template <> struct make_unsigned { typedef unsigned char type; }; + template <> struct make_unsigned { typedef unsigned char type; }; + template <> struct make_unsigned { typedef unsigned short type; }; + template <> struct make_unsigned { typedef unsigned short type; }; + template <> struct make_unsigned { typedef unsigned int type; }; + template <> struct make_unsigned { typedef unsigned long type; }; + template <> struct make_unsigned { typedef unsigned long long type; }; + template struct make_unsigned : add_const::type> { }; + template struct make_unsigned : add_volatile::type> { }; + template struct make_unsigned : add_const::type>::type> { }; + + /// enable_if + ///\ingroup type_traits + template struct enable_if { }; + template struct enable_if { typedef T type; }; + + /// conditional + ///\ingroup type_traits + template struct conditional { typedef T type; }; + template struct conditional { typedef F type; }; + + /// extent + ///\ingroup type_traits + template + struct extent : std::integral_constant {}; + + template + struct extent : std::integral_constant {}; + + template + struct extent : std::integral_constant::value> {}; + + template + struct extent : std::integral_constant {}; + + template + struct extent : std::integral_constant::value> {}; + + /// remove_extent + ///\ingroup type_traits + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type;}; + + /// remove_all_extents + ///\ingroup type_traits + template struct remove_all_extents { typedef T type;}; + template struct remove_all_extents { typedef typename remove_all_extents::type type; }; + template struct remove_all_extents { typedef typename remove_all_extents::type type; }; + + /// rank + ///\ingroup type_traits + template struct rank : integral_constant {}; + template struct rank : public integral_constant::value + 1> {}; + template struct rank : public integral_constant::value + 1> {}; + + /// Alignment templates. + /// These require compiler specific intrinsics. + ///\ingroup type_traits +#ifdef _MSC_VER + // alignment_of + template struct alignment_of : integral_constant {}; +#endif + +#ifdef __GNUC__ + // alignment_of + template struct alignment_of : integral_constant {}; +#endif +} + +#endif