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_UNSIGNED_HPP_INCLUDED
10 #define BOOST_TT_MAKE_UNSIGNED_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 pdalboost {
26 
27 template <class T>
28 struct make_unsigned
29 {
30 private:
31    BOOST_STATIC_ASSERT_MSG((::pdalboost::is_integral<T>::value || ::pdalboost::is_enum<T>::value), "The template argument to make_unsigned must be an integer or enum type.");
32    BOOST_STATIC_ASSERT_MSG((! ::pdalboost::is_same<typename remove_cv<T>::type, bool>::value), "The template argument to make_unsigned must not be the type bool");
33 
34    typedef typename remove_cv<T>::type t_no_cv;
35    typedef typename conditional<
36       (::pdalboost::is_unsigned<T>::value && ::pdalboost::is_integral<T>::value
37       && ! ::pdalboost::is_same<t_no_cv, char>::value
38       && ! ::pdalboost::is_same<t_no_cv, wchar_t>::value
39       && ! ::pdalboost::is_same<t_no_cv, bool>::value),
40       T,
41       typename conditional<
42          (::pdalboost::is_integral<T>::value
43          && ! ::pdalboost::is_same<t_no_cv, char>::value
44          && ! ::pdalboost::is_same<t_no_cv, wchar_t>::value
45          && ! ::pdalboost::is_same<t_no_cv, bool>::value),
46          typename conditional<
47             is_same<t_no_cv, signed char>::value,
48             unsigned char,
49             typename conditional<
50                is_same<t_no_cv, short>::value,
51                unsigned short,
52                typename conditional<
53                   is_same<t_no_cv, int>::value,
54                   unsigned int,
55                   typename conditional<
56                      is_same<t_no_cv, long>::value,
57                      unsigned long,
58 #if defined(BOOST_HAS_LONG_LONG)
59 #ifdef BOOST_HAS_INT128
60                      typename conditional<
61                         sizeof(t_no_cv) == sizeof(pdalboost::ulong_long_type),
62                         pdalboost::ulong_long_type,
63                         pdalboost::uint128_type
64                      >::type
65 #else
66                      pdalboost::ulong_long_type
67 #endif
68 #elif defined(BOOST_HAS_MS_INT64)
69                      unsigned __int64
70 #else
71                      unsigned long
72 #endif
73                   >::type
74                >::type
75             >::type
76          >::type,
77          // Not a regular integer type:
78          typename conditional<
79             sizeof(t_no_cv) == sizeof(unsigned char),
80             unsigned char,
81             typename conditional<
82                sizeof(t_no_cv) == sizeof(unsigned short),
83                unsigned short,
84                typename conditional<
85                   sizeof(t_no_cv) == sizeof(unsigned int),
86                   unsigned int,
87                   typename conditional<
88                      sizeof(t_no_cv) == sizeof(unsigned long),
89                      unsigned long,
90 #if defined(BOOST_HAS_LONG_LONG)
91 #ifdef BOOST_HAS_INT128
92                      typename conditional<
93                         sizeof(t_no_cv) == sizeof(pdalboost::ulong_long_type),
94                         pdalboost::ulong_long_type,
95                         pdalboost::uint128_type
96                      >::type
97 #else
98                      pdalboost::ulong_long_type
99 #endif
100 #elif defined(BOOST_HAS_MS_INT64)
101                      unsigned __int64
102 #else
103                      unsigned long
104 #endif
105                   >::type
106                >::type
107             >::type
108          >::type
109       >::type
110    >::type base_integer_type;
111 
112    // Add back any const qualifier:
113    typedef typename conditional<
114       is_const<T>::value,
115       typename add_const<base_integer_type>::type,
116       base_integer_type
117    >::type const_base_integer_type;
118 public:
119    // Add back any volatile qualifier:
120    typedef typename conditional<
121       is_volatile<T>::value,
122       typename add_volatile<const_base_integer_type>::type,
123       const_base_integer_type
124    >::type type;
125 };
126 
127 } // namespace pdalboost
128 
129 #endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
130 
131