This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [v3] add_unsigned/remove_unsigned tweaks
On Sep 29, 2006, at 11:54 AM, Paolo Carlini wrote:
Paolo Carlini wrote:
All in all, probably the best way to go is using something like
your clever __union_cv for __add_unsigned and possibly, as a
backward compatible change, for cpp_type_traits traits, it would
not add so much code, after all.
Looking better, a practical problem of course is that the
implementation of __union_cv needs various traits, such as
is_const, is_volatile, which are not available in uglified form, in
cpp_type_traits... That is a problem, a very serious one.
If it helps, here's an extremely lightly tested implementation that
has been uglified and made independent of tr1/type_traits. I
attempted to add the parts Benjamin had as well (fail for bool,
wchar_t and non-integral types):
On Sep 29, 2006, at 12:30 PM, Benjamin Kosnik wrote:
At this point, I'd
discourage yet more work on duplicating traits, however.
But it does duplicate more tr1/traits (36 lines worth) :-\
Well, we could apply Mark's guidelines and just implement
std::type_traits since it is now in the WP (thus allowing it to be
included by arbitrary headers). However this suggestion could be
premature. The situation is that tr1/type_traits was voted into the
WP as a "show of faith" rather than as a "here's the final solution"
context. It is expected that there are some tweaks to this part of
the WP in the pipe (and similarly for a few other parts of tr1 -
notably random). Fwiw, here's my opinion on what those tweaks should
look like for type_traits:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2028.html
The tweaks include removing permission to get some traits "wrong".
Here is my suggestions on the C++ FE interface to implement that part:
http://home.twcny.rr.com/hinnant/cpp_extensions/builtin_traits.html
The __has_trivial_* intrinsics are probably the most important from
the view of optimizing libstdc++. These allow you to drop down to
memcpy for some user-defined non-pod classes.
Anyway, here's the __add_unsigned animal taking cv into account,
fwiw. I don't have strong feelings about it one way or the other.
Perhaps at least we should document with some comments in Benjamin's
version that we would like to handle cv-qualified types but it is
currently too messy. That way a future proposer is more likely to
get it right for the proposal.
-Howard
template <class _Tp>
struct __is_const
{
enum { __value = 0 };
typedef __false_type __type;
};
template <class _Tp>
struct __is_const<_Tp const>
{
enum { __value = 1 };
typedef __true_type __type;
};
template <class _Tp>
struct __is_volatile
{
enum { __value = 0 };
typedef __false_type __type;
};
template <class _Tp>
struct __is_volatile<_Tp volatile>
{
enum { __value = 1 };
typedef __true_type __type;
};
template <class _Tp> struct __remove_const {typedef _Tp
__type;};
template <class _Tp> struct __remove_const<const _Tp> {typedef _Tp
__type;};
template <class _Tp> struct __remove_volatile {typedef
_Tp __type;};
template <class _Tp> struct __remove_volatile<volatile _Tp> {typedef
_Tp __type;};
template <class _Tp> struct __remove_cv
{typedef typename __remove_volatile<typename
__remove_const<_Tp>::__type>::__type __type;};
template <class T, bool make_const, bool make_volatile>
struct __apply_cv;
template <class T>
struct __apply_cv<T, false, false>
{
typedef T __type;
};
template <class T>
struct __apply_cv<T, false, true>
{
typedef volatile T __type;
};
template <class T>
struct __apply_cv<T, true, false>
{
typedef const T __type;
};
template <class T>
struct __apply_cv<T, true, true>
{
typedef const volatile T __type;
};
template<typename _Value, bool = __is_integer<_Value>::__value>
struct __add_unsigned_imp
{ typedef _Value __type; };
template<typename _Value>
struct __add_unsigned_imp<_Value, false>
{};
template<> struct __add_unsigned_imp<bool, true>;
template<> struct __add_unsigned_imp<wchar_t, true>;
template<>
struct __add_unsigned_imp<char, true>
{ typedef unsigned char __type; };
template<>
struct __add_unsigned_imp<signed char, true>
{ typedef unsigned char __type; };
template<>
struct __add_unsigned_imp<short, true>
{ typedef unsigned short __type; };
template<>
struct __add_unsigned_imp<int, true>
{ typedef unsigned int __type; };
template<>
struct __add_unsigned_imp<long, true>
{ typedef unsigned long __type; };
template<>
struct __add_unsigned_imp<long long, true>
{ typedef unsigned long long __type; };
template <class _Tp>
struct __add_unsigned
{
typedef typename __apply_cv<typename __add_unsigned_imp<typename
__remove_cv<_Tp>::__type>::__type,
__is_const<_Tp>::__value,
__is_volatile<_Tp>::__value>::__type __type;
};