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] 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.


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