
A while ago I proposed adding a signed_traits class and then after receiving some input decided it better this be a property of some existing traits object, ideally "integer_traits" since only integer can be signed. I tried to contact some people to whom I'd been referred about changing integer_traits.hpp but never heard back. Otherwise I have received no negative feedback from this proposal. The idea is simple, as with the min and max constants associated with boost::integer_traits, there would be: boost::integer_traits<x>::unsigned_type boost::integer_traits<x>::signed_type I also proposed a boost::integer_traits<x>::type But that would be x and so wouldn't be very useful. With these additions, one would be able to get the signed or unsigned form of a type without knowing the type detail. In other words, one can apply "signed" or "unsigned" to any specialized integral type that supports it. (Obviously bool would not be supported, nor would any non-integral types.) OTOH, a user-defined pseudo-integral type could provide its own specialization which would be a way of converting between signed and unsigned Abstract Integral Types (AITs) in a generic way: template <> class integer_traits<my_signed_type> : public std::numeric_limits<my_signed_type>, public detail::signed_integer_traits_base<my_signed_type, my_unsigned_type> { BOOST_STATIC_CONSTANT(bool, is_integral = true); }; Note: here I do not use the boost::detail::integer_traits_base helper because my_signed_type does not have a min or max value and even if it did, it is not possible to do in-class initialization with abstract data types. I would also be providing a specialization of std::numeric_limits. Note also because of these orthagonal properties, I provide a separate base class for signed_integer_traits_base, rather than adding to integer_traits_base. The idea would then be to have a new type in the boost::details namespace: template <class ST, class UT> class signed_integer_traits_base { public: typedef ST signed_type; typedef UT unsigned_type; }; And define each integral type correspondingly, e.g.: template<> class integer_traits<bool> : public std::numeric_limits<bool>, public detail::integer_traits_base<bool, false, true>, public detail::signed_integer_traits_base<bool, bool> { }; template<> class integer_traits<char> : public std::numeric_limits<char>, public detail::integer_traits_base<char, CHAR_MIN, CHAR_MAX>, public detail::signed_integer_traits_base<signed char, unsigned char> { }; // ... template<> class integer_traits<int> : public std::numeric_limits<int>, public detail::integer_traits_base<int, INT_MIN, INT_MAX>, public detail::signed_integer_traits_base<signed int, unsigned int> { }; template<> class integer_traits<unsigned int> : public std::numeric_limits<unsigned int>, public detail::integer_traits_base<unsigned int, 0, UINT_MAX>, public detail::signed_integer_traits_base<signed int, unsigned int> { }; // ... The one problem with this as I see is cv-qualification. Clearly, this will only provide the cv-unqualified types input as if I read ISOC++ 14.1.5 correctly, and I may not be, the top-level cv-qualification of the integral type template parameter would be dropped. E.g.: boost::integer_traits<const int>::signed_type would be [signed] int, NOT const [signed] int. In general, this is what you want because it saves you from writing specialization for each cv-qualification, but it then looses information about the source type, namely how it was cv-qualified. For the other traits, where static functions or constants are provided, the cv-qualification does not matter; it is only in the manifestation of the typedef that causes this inconvenience. However, I think this approach better than none though suggestions and corrections are welcome. Jeffrey.