This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [v3] ext/type_traits.h
On Thu, 28 Sep 2006 11:30:51 -0400, Howard Hinnant
<hhinnant@apple.com> wrote:
>[...]
>
>template <class T, bool make_const, bool make_volatile>
>struct union_cv;
>
>template <class T>
>struct union_cv<T, false, false>
>{
> typedef T type;
>};
>
>template <class T>
>struct union_cv<T, false, true>
>{
> typedef volatile T type;
>};
>
>template <class T>
>struct union_cv<T, true, false>
>{
> typedef const T type;
>};
>
>template <class T>
>struct union_cv<T, true, true>
>{
> typedef const volatile T type;
>};
>
>}
>
>template <class T, class U>
>struct union_cv
>{
> typedef typename std::tr1::remove_cv<T>::type Tr;
> typedef typename std::tr1::remove_cv<U>::type Ur;
> static const bool make_const = std::tr1::is_const<T>::value ||
>std::tr1::is_const<U>::value;
> static const bool make_volatile =
>std::tr1::is_volatile<T>::value || std::tr1::is_volatile<U>::value;
> typedef typename detail::union_cv<Tr, make_const,
>make_volatile>::type type;
>};
The problem I see with this is that it relies on too many other
templates to work correctly. I have a similar solution, which I
informally call the "const-volatile pass-through". Here's a
copy-and-paste from my SVN repository:
/*
$Id: $
Copyright 2006 Gennaro Prota
Last change: $Author: $
---------------------------------------------------------
The Contents of this file are made available subject
to the terms of the GNU General Public License Version 2.
---------------------------------------------------------
You should have received a copy of the GNU General Public License
along with this code; see the file LICENSE. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA.
====================================================================
*/
namespace meta {
template< typename T >
struct cv_qualifier
{
template< typename U>
struct pass_through
{ typedef U type; };
};
template< typename T >
struct cv_qualifier< const T >
{
template< typename U >
struct pass_through
{ typedef const U type; };
};
template< typename T >
struct cv_qualifier< volatile T >
{
template< typename U >
struct pass_through
{ typedef volatile U type; };
};
template< typename T >
struct cv_qualifier< const volatile T >
{
template< typename U >
struct pass_through
{ typedef const volatile U type; };
};
}
An example of usage is:
#define PREFIX_specialize_unsigned_of_cv( t, u ) \
template<> \
struct unsigned_of< t > \
{ typedef cv_qualifier< t >::pass_through< u >::type type; } /**/
#define PREFIX_specialize_unsigned_of( t, u ) \
PREFIX_specialize_unsigned_of_cv(t, u ); \
PREFIX_specialize_unsigned_of_cv(const t, const u ); \
PREFIX_specialize_unsigned_of_cv(volatile t, volatile u ); \
PREFIX_specialize_unsigned_of_cv(const volatile t, \
const volatile u ) /**/
namespace my_lib {
namespace meta {
PREFIX_specialize_unsigned_of( char, unsigned char );
PREFIX_specialize_unsigned_of( signed char, unsigned char );
PREFIX_specialize_unsigned_of( unsigned char, unsigned char );
}}
--
Genny.