Boost logo

Boost :

From: Christian Holmquist (c.holmquist_at_[hidden])
Date: 2007-05-14 03:01:32


> It must be useful.
> It could be more useful if it supports 'is_std_pair' and 'is_std_vector'
etc.
> Also, <std_pair_fwd.hpp> and <std_vector_fwd.hpp> etc could be useful.

My first attempt was implemented this way, by simply forward declaring std
containers:

namespace std
{
    template<class T, class Alloc> class vector;
}

template<class T, class Alloc>
struct is_container< std::vector<T, Alloc> > : public boost::true_type
{
      typedef sequence_tag container_category;
};

This of course didn't scale very well, since it required is_container<> to
be manually specialized for every container class.
I needed something that worked automatically, so I decided for the following
implementation..
Do you think it would be better to forward declare classes instead? (i.e.,
multi_index, ptr_container, array etc..)

#ifndef TT_CONTAINER_TRAITS_HPP_INCLUDED
#define TT_CONTAINER_TRAITS_HPP_INCLUDED

#include <boost/type_traits/config.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/detail/bool_trait_def.hpp>

namespace container_traits
{
    struct non_container_tag {};
    struct container_tag {};
    struct sequence_container_tag : public container_tag {};
    struct associative_container_tag : public container_tag {};
    struct hashed_container_tag : public associative_container_tag {};

    template<class T, class Tag = container_tag>
    struct is_container;

    namespace detail
    {
        BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type);
        BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator);
        BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type);
        BOOST_MPL_HAS_XXX_TRAIT_DEF(reference);
        BOOST_MPL_HAS_XXX_TRAIT_DEF(key_type);
        BOOST_MPL_HAS_XXX_TRAIT_DEF(hasher);

        BOOST_TT_AUX_BOOL_TRAIT_DEF1(
            has_container_traits, T,
            has_value_type<T>::value &
            has_iterator<T>::value &
            has_size_type<T>::value &
            has_reference<T>::value)
    }

BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1(
    class T, is_container, T, container_tag,
    detail::has_container_traits<T>::value)

BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1(
    class T, is_container, T, sequence_container_tag,
    detail::has_container_traits<T>::value
    &!detail::has_key_type<T>::value)

BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1(
    class T, is_container, T, associative_container_tag,
    detail::has_container_traits<T>::value
    &detail::has_key_type<T>::value)

BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1(
    class T, is_container, T, hashed_container_tag,
    detail::has_container_traits<T>::value
    &detail::has_key_type<T>::value
    &detail::has_hasher<T>::value)

#include <boost/type_traits/detail/bool_trait_undef.hpp>

template<class T>
struct container_category_of
{
    typedef typename boost::mpl::if_
        <
            detail::has_container_traits<T>,
            typename boost::mpl::if_
            <
                detail::has_key_type<T>,
                typename boost::mpl::if_
                <
                    detail::has_hasher<T>,
                    hashed_container_tag,
                    associative_container_tag
>::type,
                sequence_container_tag
>::type,
            non_container_tag
>::type type;

};

}

#endif

On 14/05/07, shunsuke <pstade.mb_at_[hidden] > wrote:
>
> Christian Holmquist wrote:
> > Hello,
> >
> > I've had much use of a small traits class for identifying types that
> matches
> > the STL Container concept (roughly) .
> > Two functions is made available, is_container<T> and
> > container_category_of<T>.
> >
> > is_container simply evaluates to true_type or false_type,
> > container_category_of tries to categorize T with the following tags.
> >
> > struct non_container_tag {};
> > struct container_tag {};
> > struct sequence_container_tag : public container_tag {};
> > struct associative_container_tag : public container_tag {};
> > struct hashed_container_tag : public associative_container_tag {};
> >
> > template<class T, class Tag = container_tag>
> > struct is_container
>
> It must be useful.
> It could be more useful if it supports 'is_std_pair' and 'is_std_vector'
> etc.
> Also, <std_pair_fwd.hpp> and <std_vector_fwd.hpp> etc could be useful.
>
> --
> Shunsuke Sogame
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk