source: NonGTP/Boost/boost/range/detail/collection_traits_detail.hpp @ 857

Revision 857, 21.3 KB checked in by igarcia, 19 years ago (diff)
Line 
1//  Boost string_algo library collection_traits.hpp header file  -----------------------//
2
3//  Copyright Pavol Droba 2002-2003. Use, modification and
4//  distribution is subject to the Boost Software License, Version
5//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7
8//  See http://www.boost.org for updates, documentation, and revision history.
9
10#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
11#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
12
13#include <boost/algorithm/string/config.hpp>
14#include <cstddef>
15#include <string>
16#include <boost/type_traits/is_array.hpp>
17#include <boost/type_traits/is_pointer.hpp>
18#include <boost/type_traits/is_const.hpp>
19#include <boost/type_traits/is_convertible.hpp>
20#include <boost/type_traits/remove_pointer.hpp>
21#include <boost/type_traits/remove_cv.hpp>
22#include <boost/mpl/eval_if.hpp>
23#include <boost/mpl/identity.hpp>
24#include <boost/mpl/vector.hpp>
25#include <boost/mpl/fold.hpp>
26#include <boost/detail/iterator.hpp>
27#include <boost/algorithm/string/yes_no_type.hpp>
28
29// Container traits implementation ---------------------------------------------------------
30
31namespace boost {
32    namespace algorithm {
33        namespace detail {
34
35// Default collection traits -----------------------------------------------------------------
36
37            // Default collection helper
38            /*
39                Wraps std::container compliant containers
40            */
41            template< typename ContainerT >     
42            struct default_container_traits
43            {
44                typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type;
45                typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator;
46                typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator;
47                typedef BOOST_STRING_TYPENAME
48                    ::boost::mpl::if_< ::boost::is_const<ContainerT>,
49                        const_iterator,
50                        iterator
51                    >::type result_iterator;
52                typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type;
53                typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type;
54               
55                // static operations
56                template< typename C >
57                static size_type size( const C& c )
58                {
59                    return c.size();
60                }
61
62                template< typename C >
63                static bool empty( const C& c )
64                {
65                    return c.empty();
66                }
67
68#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
69
70                template< typename C >
71                static iterator begin( C& c )
72                {
73                    return c.begin();
74                }
75
76                template< typename C >
77                static const_iterator begin( const C& c )
78                {
79                    return c.begin();
80                }
81
82                template< typename C >
83                static iterator end( C& c )
84                {
85                    return c.end();
86                }
87
88                template< typename C >
89                static const_iterator end( const C& c )
90                {
91                    return c.end();
92                }
93
94#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
95
96                template< typename C >
97                static result_iterator begin( C& c )
98                {
99                    return c.begin();
100                }
101
102                template< typename C >
103                static result_iterator end( C& c )
104                {
105                    return c.end();
106                }
107
108#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING   
109
110            };
111
112            template<typename T>
113            struct default_container_traits_selector
114            {
115                typedef default_container_traits<T> type;
116            };
117
118// Pair container traits ---------------------------------------------------------------------
119                   
120            // pair selector
121            template< typename T, typename U >
122            yes_type is_pair_impl( const std::pair<T,U>* );
123            no_type is_pair_impl( ... );
124
125            template<typename T> struct is_pair
126            {
127            private:
128                static T* t;
129            public:
130                BOOST_STATIC_CONSTANT( bool, value=
131                    sizeof(is_pair_impl(t))==sizeof(yes_type) );
132            };
133
134            // pair helper
135            template< typename PairT >
136            struct pair_container_traits
137            {
138                typedef BOOST_STRING_TYPENAME PairT::first_type element_type;
139
140                typedef BOOST_STRING_TYPENAME ::boost::detail::
141                    iterator_traits<element_type>::value_type value_type;
142                typedef std::size_t size_type;
143                typedef BOOST_STRING_TYPENAME ::boost::detail::
144                    iterator_traits<element_type>::difference_type difference_type;
145
146                typedef element_type iterator;
147                typedef element_type const_iterator;
148                typedef element_type result_iterator;
149
150                // static operations
151                template< typename P >
152                static size_type size( const P& p )
153                {
154                    difference_type diff = std::distance( p.first, p.second );
155                    if ( diff < 0 )
156                        return 0;
157                    else
158                        return diff;
159                }
160
161                template< typename P >
162                static bool empty( const P& p )
163                {
164                    return p.first==p.second;
165                }
166
167                template< typename P >
168                static const_iterator begin( const P& p )
169                {
170                    return p.first;
171                }
172
173                template< typename P >
174                static const_iterator end( const P& p )
175                {
176                    return p.second;
177                }
178            }; // 'pair_container_helper'
179
180            template<typename T>
181            struct pair_container_traits_selector
182            {
183                typedef pair_container_traits<T> type;
184            };
185
186// Array container traits ---------------------------------------------------------------
187
188#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
189            // array traits ( partial specialization )
190            template< typename T >
191            struct array_traits;
192
193            template< typename T, std::size_t sz >
194            struct array_traits<T[sz]>
195            {
196                // typedef
197                typedef T* iterator;
198                typedef const T* const_iterator;
199                typedef T value_type;
200                typedef std::size_t size_type;
201                typedef std::ptrdiff_t difference_type;
202
203                // size of the array ( static );
204                BOOST_STATIC_CONSTANT( size_type, array_size = sz );
205            };
206
207#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
208
209            // array traits ( no partial specialization )
210            /*
211                without parial specialization we are able to
212                provide support only for a limited number of
213                types. Currently the primitive numeric types
214                are supported
215            */
216            template< typename T, typename BaseT >
217            struct array_traits_impl
218            {
219                typedef BaseT value_type;
220                typedef BaseT* iterator;
221                typedef const BaseT* const_iterator;
222                typedef std::size_t size_type;
223                typedef std::ptrdiff_t difference_type;
224
225                // size of the array
226                BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) );
227            };
228           
229            template< typename T, typename BaseT >
230            struct array_traits_impl_selector
231            {
232                typedef array_traits_impl<T,BaseT> type;
233            };
234
235            struct array_traits_void
236            {
237                typedef void type;
238            };
239
240            template< typename T, typename BaseT >
241            struct array_traits_cv_selector
242            {
243                typedef BOOST_STRING_TYPENAME
244                    ::boost::mpl::eval_if<
245                        ::boost::is_convertible<T,BaseT*>,
246                        array_traits_impl_selector<T,BaseT>,
247                        ::boost::mpl::eval_if<
248                            ::boost::is_convertible<T,const BaseT*>,
249                                array_traits_impl_selector<T, const BaseT>,
250                                ::boost::mpl::eval_if<
251                                    ::boost::is_convertible<T, volatile BaseT*>,
252                                    array_traits_impl_selector<T, volatile BaseT>,
253                                    array_traits_impl_selector<T, const volatile BaseT>
254                                >
255                            >
256                    >::type type;
257            };
258
259            template< typename T >
260            struct array_traits_select
261            {
262                template< typename T1, typename T2 >
263                struct apply
264                {
265                    typedef BOOST_STRING_TYPENAME
266                        ::boost::mpl::eval_if<
267                            ::boost::is_convertible<T,const volatile T2*>,
268                            array_traits_cv_selector<T,T2>,
269                            ::boost::mpl::identity<T1> >::type type;
270                };
271            };
272
273            template< typename T >
274            struct array_traits_selector
275            {
276            private:
277                // supported array base types
278#ifndef BOOST_NO_INTRINSIC_WCHAR_T
279                typedef BOOST_STRING_TYPENAME
280                    ::boost::mpl::vector10<
281                        wchar_t,
282#else // BOOST_NO_INTRINSIC_WCHAR_T
283                typedef BOOST_STRING_TYPENAME
284                    ::boost::mpl::vector9<
285#endif // BOOST_NO_INTRINSIC_WCHAR_T
286                        char,
287                        signed char,
288                        unsigned char,
289                        signed short,
290                        unsigned short,
291                        signed int,
292                        unsigned int,
293                        signed long,
294                        unsigned long
295                >::type array_base_types;
296
297            public:
298                typedef BOOST_STRING_TYPENAME
299                    ::boost::mpl::fold<
300                        array_base_types,
301                        ::boost::algorithm::detail::array_traits_void,
302                        ::boost::algorithm::detail::array_traits_select<T> >::type type;
303            };
304
305            template< typename T >
306            struct array_traits
307            {
308                typedef BOOST_STRING_TYPENAME
309                    array_traits_selector<T>::type traits_type;
310
311                typedef BOOST_STRING_TYPENAME
312                    traits_type::value_type value_type;
313                typedef BOOST_STRING_TYPENAME
314                    traits_type::iterator iterator;
315                typedef BOOST_STRING_TYPENAME
316                    traits_type::const_iterator const_iterator;
317                typedef BOOST_STRING_TYPENAME
318                    traits_type::size_type size_type;
319                typedef BOOST_STRING_TYPENAME
320                    traits_type::difference_type difference_type;
321
322                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
323            };
324
325#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
326           
327            // array lenght resolving
328            /*
329                Lenght of string contained in a static array could
330                be different from the size of the array.
331                For string processing we need the lenght without
332                terminating 0.
333
334                Therefore, the lenght is calulated for char and wchar_t
335                using char_traits, rather then simply returning
336                the array size.
337            */
338            template< typename T >
339            struct array_length_selector
340            {
341                template< typename TraitsT >
342                struct array_length
343                {
344                    typedef BOOST_STRING_TYPENAME
345                        TraitsT::size_type size_type;
346
347                    BOOST_STATIC_CONSTANT(
348                        size_type,
349                        array_size=TraitsT::array_size );
350
351                    template< typename A >
352                    static size_type length( const A& )
353                    {
354                        return array_size;
355                    }
356
357                    template< typename A >
358                    static bool empty( const A& )
359                    {
360                        return array_size==0;
361                    }
362                };
363            };
364
365            // specialization for char
366            template<>
367            struct array_length_selector<char>
368            {
369                template< typename TraitsT >
370                struct array_length
371                {
372                    typedef BOOST_STRING_TYPENAME
373                        TraitsT::size_type size_type;
374
375                    template< typename A >
376                    static size_type length( const A& a )
377                    {
378                        if ( a==0 )
379                            return 0;
380                        else
381                            return std::char_traits<char>::length(a);
382                    }
383                   
384                    template< typename A >
385                    static bool empty( const A& a )
386                    {
387                        return a==0 || a[0]==0;
388                    }
389                };
390            };
391
392            // specialization for wchar_t
393            template<>
394            struct array_length_selector<wchar_t>
395            {
396                template< typename TraitsT >
397                struct array_length
398                {
399                    typedef BOOST_STRING_TYPENAME
400                        TraitsT::size_type size_type;
401
402                    template< typename A >
403                    static size_type length( const A& a )
404                    {
405                        if ( a==0 )
406                            return 0;
407                        else
408                            return std::char_traits<wchar_t>::length(a);
409                    }
410
411                    template< typename A >
412                    static bool empty( const A& a )
413                    {
414                        return a==0 || a[0]==0;
415                    }
416                };
417            };
418
419            template< typename T >
420            struct array_container_traits
421            {
422            private:
423                // resolve array traits
424                typedef array_traits<T> traits_type;
425
426            public:
427                typedef BOOST_STRING_TYPENAME
428                    traits_type::value_type value_type;
429                typedef BOOST_STRING_TYPENAME
430                    traits_type::iterator iterator;
431                typedef BOOST_STRING_TYPENAME
432                    traits_type::const_iterator const_iterator;
433                typedef BOOST_STRING_TYPENAME
434                    traits_type::size_type size_type;
435                typedef BOOST_STRING_TYPENAME
436                    traits_type::difference_type difference_type;
437
438                typedef BOOST_STRING_TYPENAME
439                    ::boost::mpl::if_< ::boost::is_const<T>,
440                        const_iterator,
441                        iterator
442                    >::type result_iterator;
443               
444            private:
445                // resolve array size
446                typedef BOOST_STRING_TYPENAME
447                    ::boost::remove_cv<value_type>::type char_type;
448                typedef BOOST_STRING_TYPENAME
449                    array_length_selector<char_type>::
450                        BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
451
452            public:
453                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
454
455                // static operations
456                template< typename A >
457                static size_type size( const A& a )
458                {
459                    return array_length_type::length(a);
460                }
461
462                template< typename A >
463                static bool empty( const A& a )
464                {
465                    return array_length_type::empty(a);
466                }
467               
468
469#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
470
471                template< typename A >
472                static iterator begin( A& a )
473                {
474                    return a;
475                }
476
477                template< typename A >
478                static const_iterator begin( const A& a )
479                {
480                    return a;
481                }
482
483                template< typename A >
484                static iterator end( A& a )
485                {
486                    return a+array_length_type::length(a);
487                }
488
489                template< typename A >
490                static const_iterator end( const A& a )
491                {
492                    return a+array_length_type::length(a);
493                }
494
495#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
496
497                template< typename A >
498                static result_iterator begin( A& a )
499                {
500                    return a;
501                }
502
503                template< typename A >
504                static result_iterator end( A& a )
505                {
506                    return a+array_length_type::length(a);
507                }
508
509#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING   
510
511            };
512
513            template<typename T>
514            struct array_container_traits_selector
515            {
516                typedef array_container_traits<T> type;
517            };
518
519// Pointer container traits ---------------------------------------------------------------
520
521            template<typename T>
522            struct pointer_container_traits
523            {
524                typedef BOOST_STRING_TYPENAME
525                    ::boost::remove_pointer<T>::type value_type;
526
527                typedef BOOST_STRING_TYPENAME
528                    ::boost::remove_cv<value_type>::type char_type;
529                typedef ::std::char_traits<char_type> char_traits;
530
531                typedef value_type* iterator;
532                typedef const value_type* const_iterator;
533                typedef std::ptrdiff_t difference_type;
534                typedef std::size_t size_type;
535
536                typedef BOOST_STRING_TYPENAME
537                    ::boost::mpl::if_< ::boost::is_const<T>,
538                        const_iterator,
539                        iterator
540                    >::type result_iterator;
541
542                // static operations
543                template< typename P >
544                static size_type size( const P& p )
545                {
546                    if ( p==0 )
547                        return 0;
548                    else
549                        return char_traits::length(p);
550                }
551
552                template< typename P >
553                static bool empty( const P& p )
554                {
555                    return p==0 || p[0]==0;
556                }
557
558#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
559
560                template< typename P >
561                static iterator begin( P& p )
562                {
563                    return p;
564                }
565
566                template< typename P >
567                static const_iterator begin( const P& p )
568                {
569                    return p;
570                }
571
572                template< typename P >
573                static iterator end( P& p )
574                {
575                    if ( p==0 )
576                        return p;
577                    else
578                        return p+char_traits::length(p);
579                }
580
581                template< typename P >
582                static const_iterator end( const P& p )
583                {
584                    if ( p==0 )
585                        return p;
586                    else
587                        return p+char_traits::length(p);
588                }
589
590#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
591
592                template< typename P >
593                static result_iterator begin( P& p )
594                {
595                    return p;
596                }
597
598                template< typename P >
599                static result_iterator end( P& p )
600                {
601                    if ( p==0 )
602                        return p;
603                    else
604                        return p+char_traits::length(p);
605                }
606
607#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING   
608            };
609
610            template<typename T>
611            struct pointer_container_traits_selector
612            {
613                typedef pointer_container_traits<T> type;
614            };
615
616        } // namespace detail
617    } // namespace algorithm
618} // namespace boost
619
620
621#endif  // BOOST_STRING_DETAIL_COLLECTION_HPP
Note: See TracBrowser for help on using the repository browser.