This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
};





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]