collection_traits.hpp 9.32 KB
Newer Older
xuebingbing's avatar
xuebingbing committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
//  Boost string_algo library collection_traits.hpp header file  -------------//

//  Copyright Pavol Droba 2002-2003. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

// (C) Copyright Thorsten Ottosen 2002-2003. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

// (C) Copyright Jeremy Siek 2001. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  Original idea of container traits was proposed by Jeremy Siek and
//  Thorsten Ottosen. This implementation is lightweighted version
//  of container_traits adapter for usage with string_algo library

#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP

#include <boost/algorithm/string/config.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/mpl/eval_if.hpp>

// Implementation
#include <boost/range/detail/collection_traits_detail.hpp>

/*! \file
    Defines collection_traits class and related free-standing functions.
    This facility is used to unify the access to different types of collections.
    It allows the algorithms in the library to work with STL collections, c-style
    array, null-terminated c-strings (and more) using the same interface.
*/

namespace boost {
    namespace algorithm {

//  collection_traits template class -----------------------------------------//
        
        //! collection_traits class
        /*!
            Collection traits provide uniform access to different types of 
            collections. This functionality allows to write generic algorithms
            which work with several different kinds of collections.

            Currently following collection types are supported:
                - containers with STL compatible container interface ( see ContainerConcept )
                    ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... )
                - c-style array 
                   ( \c char[10], \c int[15] ... )
                - null-terminated c-strings
                    ( \c char*, \c wchar_T* )
                - std::pair of iterators 
                    ( i.e \c std::pair<vector<int>::iterator,vector<int>::iterator> )

            Collection traits provide an external collection interface operations.
            All are accessible using free-standing functions.

            The following operations are supported:
                - \c size()
                - \c empty()
                - \c begin()
                - \c end()

            Container traits have somewhat limited functionality on compilers not
            supporting partial template specialization and partial template ordering.
        */
        template< typename T >
        struct collection_traits
        {
        private:
            typedef BOOST_STRING_TYPENAME ::boost::mpl::eval_if< 
                    ::boost::algorithm::detail::is_pair<T>, 
                        detail::pair_container_traits_selector<T>,
                        BOOST_STRING_TYPENAME ::boost::mpl::eval_if< 
                        ::boost::is_array<T>, 
                            detail::array_container_traits_selector<T>,
                            BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
                            ::boost::is_pointer<T>,
                                detail::pointer_container_traits_selector<T>,
                                detail::default_container_traits_selector<T>
                            >
                        > 
                >::type container_helper_type;
        public:
            //! Function type       
            typedef container_helper_type function_type;        
            //! Value type
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::value_type value_type;
            //! Size type
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::size_type size_type;
            //! Iterator type
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::iterator iterator;
            //! Const iterator type
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::const_iterator const_iterator;
            //! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::result_iterator result_iterator;
            //! Difference type
            typedef BOOST_STRING_TYPENAME 
                container_helper_type::difference_type difference_type;

        }; // 'collection_traits'

//  collection_traits metafunctions -----------------------------------------//

        //! Container value_type trait
        /*!
            Extract the type of elements contained in a container
        */
        template< typename C >
        struct value_type_of
        {
            typedef BOOST_STRING_TYPENAME collection_traits<C>::value_type type;
        };
        
        //! Container difference trait
        /*!
            Extract the container's difference type
        */
        template< typename C >
        struct difference_type_of
        {
            typedef BOOST_STRING_TYPENAME collection_traits<C>::difference_type type;
        };

        //! Container iterator trait
        /*!
            Extract the container's iterator type
        */
        template< typename C >
        struct iterator_of
        {
            typedef BOOST_STRING_TYPENAME collection_traits<C>::iterator type;
        };

        //! Container const_iterator trait
        /*!
            Extract the container's const_iterator type
        */
        template< typename C >
        struct const_iterator_of
        {
            typedef BOOST_STRING_TYPENAME collection_traits<C>::const_iterator type;
        };


        //! Container result_iterator
        /*!
            Extract the container's result_iterator type. This type maps to \c C::iterator
            for mutable container and \c C::const_iterator for const containers.
        */
        template< typename C >
        struct result_iterator_of
        {
            typedef BOOST_STRING_TYPENAME collection_traits<C>::result_iterator type;
        };

//  collection_traits related functions -----------------------------------------//

        //! Free-standing size() function
        /*!
            Get the size of the container. Uses collection_traits.
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::size_type
        size( const C& c )
        {
            return collection_traits<C>::function_type::size( c ); 
        }

        //! Free-standing empty() function
        /*!
            Check whether the container is empty. Uses container traits.
        */
        template< typename C >
        inline bool empty( const C& c )
        {
            return collection_traits<C>::function_type::empty( c );
        }

#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING

        //! Free-standing begin() function
        /*!
            Get the begin iterator of the container. Uses collection_traits.
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
        begin( C& c )
        {
            return collection_traits<C>::function_type::begin( c ); 
        }

        //! Free-standing begin() function
        /*!
            \overload
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
        begin( const C& c )
        {
            return collection_traits<C>::function_type::begin( c ); 
        }

        //! Free-standing end() function
        /*!
            Get the begin iterator of the container. Uses collection_traits.
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
        end( C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

        //! Free-standing end() function
        /*!
            \overload           
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
        end( const C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

        //! Free-standing begin() function
        /*!
            \overload
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
        begin( C& c )
        {
            return collection_traits<C>::function_type::begin( c );
        }

        //! Free-standing end() function
        /*!
            \overload
        */
        template< typename C >
        inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
        end( C& c )
        {
            return collection_traits<C>::function_type::end( c );
        }

#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING

    } // namespace algorithm
} // namespace boost

#endif // BOOST_STRING_COLLECTION_TRAITS_HPP