63 lines
2.4 KiB
C++
63 lines
2.4 KiB
C++
#ifndef _H_LIBCX_STL_MAKE_UNSIGNED
|
|
#define _H_LIBCX_STL_MAKE_UNSIGNED
|
|
|
|
#include <cx/stl/is_unsigned.hpp>
|
|
#include <cx/stl/conditional.hpp>
|
|
#if __has_builtin(__make_unsigned)
|
|
|
|
template <class _Tp>
|
|
using __make_unsigned_t = __make_unsigned(_Tp);
|
|
|
|
#else
|
|
using __unsigned_types = __type_list<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long
|
|
#if _CX_HAS_INT128
|
|
,
|
|
__uint128_t
|
|
#endif
|
|
>;
|
|
|
|
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
|
|
struct __make_unsigned{};
|
|
|
|
template <class _Tp>
|
|
struct __make_unsigned<_Tp, true> {
|
|
typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
|
|
};
|
|
|
|
// clang-format off
|
|
template <> struct __make_unsigned<bool, true> {};
|
|
template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;};
|
|
template <> struct __make_unsigned<unsigned short, true> {typedef unsigned short type;};
|
|
template <> struct __make_unsigned< signed int, true> {typedef unsigned int type;};
|
|
template <> struct __make_unsigned<unsigned int, true> {typedef unsigned int type;};
|
|
template <> struct __make_unsigned< signed long, true> {typedef unsigned long type;};
|
|
template <> struct __make_unsigned<unsigned long, true> {typedef unsigned long type;};
|
|
template <> struct __make_unsigned< signed long long, true> {typedef unsigned long long type;};
|
|
template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
|
|
# if _CX_HAS_INT128
|
|
template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;};
|
|
template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;};
|
|
# endif
|
|
// clang-format on
|
|
|
|
template <class _Tp>
|
|
using __make_unsigned_t = __copy_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp>>::type>;
|
|
|
|
#endif // __has_builtin(__make_unsigned)
|
|
|
|
template <class _Tp>
|
|
struct make_unsigned {
|
|
using type = __make_unsigned_t<_Tp>;
|
|
};
|
|
|
|
template <class _Tp>
|
|
using make_unsigned_t = __make_unsigned_t<_Tp>;
|
|
|
|
template <class _Tp>
|
|
__make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) {
|
|
return static_cast<__make_unsigned_t<_Tp>>(__x);
|
|
}
|
|
|
|
template <class _Tp, class _Up>
|
|
using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, __make_unsigned_t<_Up>, _Up>;
|
|
#endif // _H_LIBCX_STL_MAKE_UNSIGNED
|