1 2 // (C) Copyright John Maddock 2007. 3 // Use, modification and distribution are subject to the Boost Software License, 4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt). 6 // 7 // See http://www.boost.org/libs/type_traits for most recent version including documentation. 8 9 #ifndef BOOST_TT_MAKE_SIGNED_HPP_INCLUDED 10 #define BOOST_TT_MAKE_SIGNED_HPP_INCLUDED 11 12 #include <boost/type_traits/conditional.hpp> 13 #include <boost/type_traits/is_integral.hpp> 14 #include <boost/type_traits/is_signed.hpp> 15 #include <boost/type_traits/is_unsigned.hpp> 16 #include <boost/type_traits/is_enum.hpp> 17 #include <boost/type_traits/is_same.hpp> 18 #include <boost/type_traits/remove_cv.hpp> 19 #include <boost/type_traits/is_const.hpp> 20 #include <boost/type_traits/is_volatile.hpp> 21 #include <boost/type_traits/add_const.hpp> 22 #include <boost/type_traits/add_volatile.hpp> 23 #include <boost/static_assert.hpp> 24 25 namespace boost { 26 27 template <class T> 28 struct make_signed 29 { 30 private: 31 BOOST_STATIC_ASSERT_MSG(( ::boost::is_integral<T>::value || ::boost::is_enum<T>::value), "The template argument to make_signed must be an integer or enum type."); 32 BOOST_STATIC_ASSERT_MSG(!(::boost::is_same<typename remove_cv<T>::type, bool>::value), "The template argument to make_signed must not be the type bool."); 33 34 typedef typename remove_cv<T>::type t_no_cv; 35 typedef typename conditional< 36 (::boost::is_signed<T>::value 37 && ::boost::is_integral<T>::value 38 && ! ::boost::is_same<t_no_cv, char>::value 39 && ! ::boost::is_same<t_no_cv, wchar_t>::value 40 && ! ::boost::is_same<t_no_cv, bool>::value), 41 T, 42 typename conditional< 43 (::boost::is_integral<T>::value 44 && ! ::boost::is_same<t_no_cv, char>::value 45 && ! ::boost::is_same<t_no_cv, wchar_t>::value 46 && ! ::boost::is_same<t_no_cv, bool>::value), 47 typename conditional< 48 is_same<t_no_cv, unsigned char>::value, 49 signed char, 50 typename conditional< 51 is_same<t_no_cv, unsigned short>::value, 52 signed short, 53 typename conditional< 54 is_same<t_no_cv, unsigned int>::value, 55 int, 56 typename conditional< 57 is_same<t_no_cv, unsigned long>::value, 58 long, 59 #if defined(BOOST_HAS_LONG_LONG) 60 #ifdef BOOST_HAS_INT128 61 typename conditional< 62 sizeof(t_no_cv) == sizeof(boost::long_long_type), 63 boost::long_long_type, 64 boost::int128_type 65 >::type 66 #else 67 boost::long_long_type 68 #endif 69 #elif defined(BOOST_HAS_MS_INT64) 70 __int64 71 #else 72 long 73 #endif 74 >::type 75 >::type 76 >::type 77 >::type, 78 // Not a regular integer type: 79 typename conditional< 80 sizeof(t_no_cv) == sizeof(unsigned char), 81 signed char, 82 typename conditional< 83 sizeof(t_no_cv) == sizeof(unsigned short), 84 signed short, 85 typename conditional< 86 sizeof(t_no_cv) == sizeof(unsigned int), 87 int, 88 typename conditional< 89 sizeof(t_no_cv) == sizeof(unsigned long), 90 long, 91 #if defined(BOOST_HAS_LONG_LONG) 92 #ifdef BOOST_HAS_INT128 93 typename conditional< 94 sizeof(t_no_cv) == sizeof(boost::long_long_type), 95 boost::long_long_type, 96 boost::int128_type 97 >::type 98 #else 99 boost::long_long_type 100 #endif 101 #elif defined(BOOST_HAS_MS_INT64) 102 __int64 103 #else 104 long 105 #endif 106 >::type 107 >::type 108 >::type 109 >::type 110 >::type 111 >::type base_integer_type; 112 113 // Add back any const qualifier: 114 typedef typename conditional< 115 is_const<T>::value, 116 typename add_const<base_integer_type>::type, 117 base_integer_type 118 >::type const_base_integer_type; 119 public: 120 // Add back any volatile qualifier: 121 typedef typename conditional< 122 is_volatile<T>::value, 123 typename add_volatile<const_base_integer_type>::type, 124 const_base_integer_type 125 >::type type; 126 }; 127 128 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) 129 130 template <class T> using make_signed_t = typename make_signed<T>::type; 131 132 #endif 133 134 } // namespace boost 135 136 #endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED 137 138