///\file /****************************************************************************** The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl 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 #include "nullptr.h" ///\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; typedef integral_constant 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 {}; #ifdef PLATFORM_LINUX template <> struct is_signed : true_type {}; #endif 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 {}; #ifndef PLATFORM_LINUX template <> struct is_unsigned : true_type {}; #endif 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_compound ///\ingroup type_traits template struct is_compound : integral_constant::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 {}; /// conditional ///\ingroup type_traits template struct conditional { typedef T type; }; template struct conditional { typedef F 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 etl::conditional::type>::type>::type 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 etl::conditional::type>::type>::type 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; }; /// extent ///\ingroup type_traits template struct extent : integral_constant {}; template struct extent : integral_constant {}; template struct extent : integral_constant::value> {}; template struct extent : integral_constant {}; template struct extent : 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> {}; /// decay ///\ingroup type_traits template struct decay { typedef typename etl::remove_reference::type U; typedef typename etl::conditional::value, typename etl::remove_extent::type*, typename etl::remove_cv::type>::type type; }; /// Alignment templates. /// These require compiler specific intrinsics. ///\ingroup type_traits #ifdef COMPILER_MICROSOFT template struct alignment_of : integral_constant {}; #endif #ifdef COMPILER_GCC template struct alignment_of : integral_constant {}; #endif #ifdef COMPILER_KEIL template struct alignment_of : integral_constant {}; #endif #ifdef COMPILER_IAR template struct alignment_of : integral_constant {}; #endif /// Specialisation of 'alignment_of' for 'void'. ///\ingroup type_traits template <> struct alignment_of : integral_constant {}; } #endif