_iterator_base.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Copyright (c) 1996-1998
00007  * Silicon Graphics Computer Systems, Inc.
00008  *
00009  * Copyright (c) 1997
00010  * Moscow Center for SPARC Technology
00011  *
00012  * Copyright (c) 1999 
00013  * Boris Fomitchev
00014  *
00015  * This material is provided "as is", with absolutely no warranty expressed
00016  * or implied. Any use is at your own risk.
00017  *
00018  * Permission to use or copy this software for any purpose is hereby granted 
00019  * without fee, provided the above notices are retained on all copies.
00020  * Permission to modify the code and to distribute modified code is granted,
00021  * provided the above notices are retained, and a notice that the code was
00022  * modified is included with the above copyright notice.
00023  *
00024  */
00025 
00026 /* NOTE: This is an internal header file, included by other STL headers.
00027  *   You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _STLP_INTERNAL_ITERATOR_BASE_H
00031 #define _STLP_INTERNAL_ITERATOR_BASE_H
00032 
00033 #ifndef _STLP_CSTDDEF
00034 # include <cstddef>
00035 #endif
00036 
00037 #ifndef __TYPE_TRAITS_H
00038 # include <stl/type_traits.h>
00039 #endif
00040 
00041 _STLP_BEGIN_NAMESPACE
00042 
00043 struct input_iterator_tag {};
00044 struct output_iterator_tag {};
00045 struct forward_iterator_tag : public input_iterator_tag {};
00046 struct bidirectional_iterator_tag : public forward_iterator_tag {};
00047 struct random_access_iterator_tag : public bidirectional_iterator_tag {};
00048 
00049 
00050 template <class _Category, class _Tp, __DFL_TMPL_PARAM(_Distance,ptrdiff_t),
00051           __DFL_TMPL_PARAM(_Pointer,_Tp*), __DFL_TMPL_PARAM(_Reference,_Tp&) >
00052 struct iterator {
00053   typedef _Category  iterator_category;
00054   typedef _Tp        value_type;
00055   typedef _Distance  difference_type;
00056   typedef _Pointer   pointer;
00057   typedef _Reference reference;
00058 };
00059 _STLP_TEMPLATE_NULL
00060 struct iterator<output_iterator_tag, void, void, void, void> {
00061   typedef output_iterator_tag  iterator_category;
00062 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00063   typedef void                value_type;
00064   typedef void                difference_type;
00065   typedef void                pointer;
00066   typedef void                reference;
00067 #endif
00068 };
00069 
00070 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00071 #  define _STLP_ITERATOR_CATEGORY(_It, _Tp) iterator_category(_It)
00072 #  define _STLP_DISTANCE_TYPE(_It, _Tp)     distance_type(_It)
00073 #  define _STLP_VALUE_TYPE(_It, _Tp)        value_type(_It)
00074 # else
00075 #  ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00076 #   define _STLP_VALUE_TYPE(_It, _Tp)        (typename iterator_traits< _Tp >::value_type*)0
00077 #   define _STLP_DISTANCE_TYPE(_It, _Tp)     (typename iterator_traits< _Tp >::difference_type*)0
00078 #   if defined (__BORLANDC__) || defined (__SUNPRO_CC) || ( defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || ( defined (__sgi) && defined (_COMPILER_VERSION)) 
00079 #    define _STLP_ITERATOR_CATEGORY(_It, _Tp) iterator_traits< _Tp >::iterator_category()
00080 #   else
00081 #    define _STLP_ITERATOR_CATEGORY(_It, _Tp) typename iterator_traits< _Tp >::iterator_category()
00082 #   endif
00083 #  else
00084 #   define _STLP_ITERATOR_CATEGORY(_It, _Tp) __iterator_category(_It, _IsPtrType<_Tp>::_Ret())
00085 #   define _STLP_DISTANCE_TYPE(_It, _Tp)     (ptrdiff_t*)0
00086 #   define _STLP_VALUE_TYPE(_It, _Tp)        __value_type(_It, _IsPtrType<_Tp>::_Ret() )
00087 #  endif
00088 # endif
00089 
00090 template <class _Iterator>
00091 struct iterator_traits {
00092   typedef typename _Iterator::iterator_category iterator_category;
00093   typedef typename _Iterator::value_type        value_type;
00094   typedef typename _Iterator::difference_type   difference_type;
00095   typedef typename _Iterator::pointer           pointer;
00096   typedef typename _Iterator::reference         reference;
00097 };
00098 
00099 
00100 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && ! defined (__SUNPRO_CC)
00101 #  define _STLP_DIFFERENCE_TYPE(_Iterator) typename iterator_traits<_Iterator>::difference_type
00102 # else
00103 #  define _STLP_DIFFERENCE_TYPE(_Iterator) ptrdiff_t
00104 # endif
00105 
00106 # ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00107 
00108 // fbp : this order keeps gcc happy
00109 template <class _Tp>
00110 struct iterator_traits<const _Tp*> {
00111   typedef random_access_iterator_tag iterator_category;
00112   typedef _Tp                         value_type;
00113   typedef ptrdiff_t                   difference_type;
00114   typedef const _Tp*                  pointer;
00115   typedef const _Tp&                  reference;
00116 };
00117 
00118 template <class _Tp>
00119 struct iterator_traits<_Tp*> {
00120   typedef random_access_iterator_tag iterator_category;
00121   typedef _Tp                         value_type;
00122   typedef ptrdiff_t                   difference_type;
00123   typedef _Tp*                        pointer;
00124   typedef _Tp&                        reference;
00125 };
00126 
00127 #  if defined (__BORLANDC__)
00128 template <class _Tp>
00129 struct iterator_traits<_Tp* const> {
00130   typedef random_access_iterator_tag iterator_category;
00131   typedef _Tp                         value_type;
00132   typedef ptrdiff_t                   difference_type;
00133   typedef const _Tp*                  pointer;
00134   typedef const _Tp&                  reference;
00135 };
00136 #  endif
00137 
00138 # endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00139 
00140 
00141 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) \
00142   || (defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && ! defined (_STLP_NO_ARROW_OPERATOR))
00143 #  define _STLP_POINTERS_SPECIALIZE( _TpP )
00144 #  define _STLP_DEFINE_ARROW_OPERATOR  pointer operator->() const { return &(operator*()); }
00145 # else 
00146    _STLP_END_NAMESPACE
00147 #  include <stl/_ptrs_specialize.h>
00148    _STLP_BEGIN_NAMESPACE
00149 # endif
00150 
00151 # ifndef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00152 // The overloaded functions iterator_category, distance_type, and
00153 // value_type are not part of the C++ standard.  (They have been
00154 // replaced by struct iterator_traits.)  They are included for
00155 // backward compatibility with the HP STL.
00156 // We introduce internal names for these functions.
00157 
00158 #  ifdef  _STLP_CLASS_PARTIAL_SPECIALIZATION
00159 
00160 template <class _Iter>
00161 inline typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) {
00162   typedef typename iterator_traits<_Iter>::iterator_category _Category;
00163   return _Category();
00164 }
00165 
00166 template <class _Iter>
00167 inline typename iterator_traits<_Iter>::difference_type* __distance_type(const _Iter&) {
00168   typedef typename iterator_traits<_Iter>::difference_type _diff_type;
00169   return __STATIC_CAST(_diff_type*,0);
00170 }
00171 
00172 template <class _Iter>
00173 inline typename iterator_traits<_Iter>::value_type* __value_type(const _Iter&) {
00174   typedef typename iterator_traits<_Iter>::value_type _value_type;
00175   return __STATIC_CAST(_value_type*,0);
00176 }
00177 
00178 # else
00179 
00180 template <class _Iter>
00181 inline random_access_iterator_tag 
00182 __iterator_category(const _Iter&, const __true_type&) {
00183   return random_access_iterator_tag();
00184 }
00185 
00186 template <class _Iter>
00187 inline _STLP_TYPENAME_ON_RETURN_TYPE iterator_traits<_Iter>::iterator_category
00188 __iterator_category(const _Iter&, const __false_type&) {
00189   typedef typename iterator_traits<_Iter>::iterator_category _Category;
00190   return _Category();
00191 }
00192 
00193 
00194 template <class _Iter>
00195 inline ptrdiff_t* _STLP_CALL __distance_type(const _Iter&) { return (ptrdiff_t*)(0); }
00196 
00197 template <class _Iter>
00198 inline _STLP_TYPENAME_ON_RETURN_TYPE iterator_traits<_Iter>::value_type* 
00199 __value_type(const _Iter&, const __false_type&) {
00200   typedef typename iterator_traits<_Iter>::value_type _value_type;
00201   return __STATIC_CAST(_value_type*,0);
00202 }
00203 
00204 template <class _Tp>
00205 inline _Tp*  
00206 __value_type(const _Tp*, const __true_type&) {
00207   return __STATIC_CAST(_Tp*, 0);
00208 }
00209 
00210 # endif
00211 
00212 #else /* old queries */
00213 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
00214 inline _Category _STLP_CALL iterator_category(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return _Category(); }
00215 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
00216 inline _Tp* _STLP_CALL value_type(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return (_Tp*)(0); }
00217 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
00218 inline _Distance* _STLP_CALL distance_type(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return (_Distance*)(0); }
00219 template <class _Tp>
00220 inline random_access_iterator_tag _STLP_CALL iterator_category(const _Tp*) { return random_access_iterator_tag(); }
00221 template <class _Tp>
00222 inline _Tp* _STLP_CALL value_type(const _Tp*) { return (_Tp*)(0); }
00223 template <class _Tp>
00224 inline ptrdiff_t* _STLP_CALL distance_type(const _Tp*) { return (ptrdiff_t*)(0); }
00225 #endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
00226 
00227 # if ! defined (_STLP_NO_ANACHRONISMS)
00228 // The base classes input_iterator, output_iterator, forward_iterator,
00229 // bidirectional_iterator, and random_access_iterator are not part of
00230 // the C++ standard.  (They have been replaced by struct iterator.)
00231 // They are included for backward compatibility with the HP STL.
00232 template <class _Tp, class _Distance> struct input_iterator : 
00233   public iterator <input_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
00234 struct output_iterator : public iterator <output_iterator_tag, void, void, void, void> {};
00235 template <class _Tp, class _Distance> struct forward_iterator :
00236   public iterator<forward_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
00237 template <class _Tp, class _Distance> struct bidirectional_iterator :
00238   public iterator<bidirectional_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
00239 template <class _Tp, class _Distance> struct random_access_iterator :
00240   public iterator<random_access_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
00241 
00242 # if defined (_STLP_BASE_MATCH_BUG) && defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
00243 template <class _Tp, class _Distance> 
00244 inline input_iterator_tag _STLP_CALL 
00245 iterator_category(const input_iterator<_Tp, _Distance>&) { return input_iterator_tag(); }
00246 inline output_iterator_tag _STLP_CALL
00247 iterator_category(const output_iterator&) { return output_iterator_tag(); }
00248 template <class _Tp, class _Distance> 
00249 inline forward_iterator_tag _STLP_CALL
00250 iterator_category(const forward_iterator<_Tp, _Distance>&) { return forward_iterator_tag(); }
00251 template <class _Tp, class _Distance> 
00252 inline bidirectional_iterator_tag _STLP_CALL 
00253 iterator_category(const bidirectional_iterator<_Tp, _Distance>&) { return bidirectional_iterator_tag(); }
00254 template <class _Tp, class _Distance> 
00255 inline random_access_iterator_tag _STLP_CALL
00256 iterator_category(const random_access_iterator<_Tp, _Distance>&) { return random_access_iterator_tag(); }
00257 template <class _Tp, class _Distance> 
00258 inline _Tp*  _STLP_CALL value_type(const input_iterator<_Tp, _Distance>&) { return (_Tp*)(0); }
00259 template <class _Tp, class _Distance> 
00260 inline _Tp* _STLP_CALL value_type(const forward_iterator<_Tp, _Distance>&) { return (_Tp*)(0); }
00261 template <class _Tp, class _Distance> 
00262 inline _Tp* _STLP_CALL value_type(const bidirectional_iterator<_Tp, _Distance>&) { return (_Tp*)(0); }
00263 template <class _Tp, class _Distance> 
00264 inline _Tp* _STLP_CALL value_type(const random_access_iterator<_Tp, _Distance>&) { return (_Tp*)(0); }
00265 template <class _Tp, class _Distance> 
00266 inline _Distance* _STLP_CALL distance_type(const input_iterator<_Tp, _Distance>&) { return (_Distance*)(0); }
00267 template <class _Tp, class _Distance> 
00268 inline _Distance* _STLP_CALL distance_type(const forward_iterator<_Tp, _Distance>&) { return (_Distance*)(0); }
00269 template <class _Tp, class _Distance> 
00270 inline _Distance* _STLP_CALL distance_type(const bidirectional_iterator<_Tp, _Distance>&) { return (_Distance*)(0);}
00271 template <class _Tp, class _Distance> 
00272 inline _Distance* _STLP_CALL distance_type(const random_access_iterator<_Tp, _Distance>&) { return (_Distance*)(0); }
00273 # endif /* BASE_MATCH */
00274 
00275 #endif /* _STLP_NO_ANACHRONISMS */
00276 
00277 template <class _InputIterator, class _Distance>
00278 inline void _STLP_CALL __distance(const _InputIterator& __first, const _InputIterator& __last,
00279                                   _Distance& __n, const input_iterator_tag &) {
00280   _InputIterator __it(__first);
00281   while (__it != __last) { ++__it; ++__n; }
00282 }
00283 
00284 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 
00285 template <class _ForwardIterator, class _Distance>
00286 inline void _STLP_CALL __distance(const _ForwardIterator& __first, const _ForwardIterator& __last,
00287                                   _Distance& __n, const forward_iterator_tag &) {
00288   _ForwardIterator __it(__first);
00289   while (__it != __last) { ++__first; ++__n; }
00290 }
00291 
00292 template <class _BidirectionalIterator, class _Distance>
00293 _STLP_INLINE_LOOP void _STLP_CALL __distance(const _BidirectionalIterator& __first, 
00294                                              const _BidirectionalIterator& __last,
00295                                              _Distance& __n, const bidirectional_iterator_tag &) {
00296   _BidirectionalIterator __it(__first);
00297   while (__it != __last) { ++__it; ++__n; }
00298 }
00299 # endif
00300 
00301 template <class _RandomAccessIterator, class _Distance>
00302 inline void _STLP_CALL __distance(const _RandomAccessIterator& __first, 
00303                                   const _RandomAccessIterator& __last, 
00304                                   _Distance& __n, const random_access_iterator_tag &) {
00305   __n += __last - __first;
00306 }
00307 
00308 #ifndef _STLP_NO_ANACHRONISMS 
00309 template <class _InputIterator, class _Distance>
00310 inline void _STLP_CALL distance(const _InputIterator& __first, 
00311                                 const _InputIterator& __last, _Distance& __n) {
00312   __distance(__first, __last, __n, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00313 }
00314 #endif
00315 
00316 template <class _InputIterator>
00317 inline _STLP_DIFFERENCE_TYPE(_InputIterator) _STLP_CALL
00318 __distance(const _InputIterator& __first, const _InputIterator& __last, const input_iterator_tag &) {
00319   _STLP_DIFFERENCE_TYPE(_InputIterator) __n = 0;
00320   _InputIterator __it(__first);  
00321   while (__it != __last) {
00322     ++__it; ++__n;
00323   }
00324   return __n;
00325 }
00326 
00327 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 
00328 template <class _ForwardIterator>
00329 inline _STLP_DIFFERENCE_TYPE(_ForwardIterator) _STLP_CALL 
00330 __distance(const _ForwardIterator& __first, const _ForwardIterator& __last,
00331            const forward_iterator_tag &)
00332 {
00333   _STLP_DIFFERENCE_TYPE(_ForwardIterator) __n = 0;
00334   _ForwardIterator __it(__first);
00335   while (__it != __last) {
00336     ++__it; ++__n;
00337   }
00338   return __n;
00339 }
00340 
00341 template <class _BidirectionalIterator>
00342 _STLP_INLINE_LOOP _STLP_DIFFERENCE_TYPE(_BidirectionalIterator) _STLP_CALL 
00343 __distance(const _BidirectionalIterator& __first, 
00344            const _BidirectionalIterator& __last,
00345            const bidirectional_iterator_tag &) {
00346   _STLP_DIFFERENCE_TYPE(_BidirectionalIterator) __n = 0;
00347   _BidirectionalIterator __it(__first);
00348   while (__it != __last) {
00349     ++__it; ++__n;
00350   }
00351   return __n;
00352 }
00353 # endif
00354 
00355 template <class _RandomAccessIterator>
00356 inline _STLP_DIFFERENCE_TYPE(_RandomAccessIterator) _STLP_CALL
00357 __distance(const _RandomAccessIterator& __first, const _RandomAccessIterator& __last,
00358            const random_access_iterator_tag &) {
00359   return __last - __first;
00360 }
00361 
00362 template <class _InputIterator>
00363 inline _STLP_DIFFERENCE_TYPE(_InputIterator) _STLP_CALL
00364 distance(const _InputIterator& __first, const _InputIterator& __last) {
00365   return __distance(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));  
00366 }
00367 
00368 
00369 // fbp: those are being used for iterator/const_iterator definitions everywhere
00370 template <class _Tp>
00371 struct _Nonconst_traits;
00372 
00373 template <class _Tp>
00374 struct _Const_traits {
00375   typedef _Tp value_type;
00376   typedef const _Tp&  reference;
00377   typedef const _Tp*  pointer;
00378   typedef _Nonconst_traits<_Tp> _Non_const_traits;
00379 };
00380 
00381 template <class _Tp>
00382 struct _Nonconst_traits {
00383   typedef _Tp value_type;
00384   typedef _Tp& reference;
00385   typedef _Tp* pointer;
00386   typedef _Nonconst_traits<_Tp> _Non_const_traits;
00387 };
00388 
00389 #  if defined (_STLP_BASE_TYPEDEF_BUG)
00390 // this workaround is needed for SunPro 4.0.1
00391 template <class _Traits>
00392 struct __cnst_traits_aux : private _Traits
00393 {
00394   typedef typename _Traits::value_type value_type;
00395 };
00396 #  define __TRAITS_VALUE_TYPE(_Traits) __cnst_traits_aux<_Traits>::value_type
00397 #  else
00398 #  define __TRAITS_VALUE_TYPE(_Traits) _Traits::value_type
00399 #  endif
00400 
00401 # if defined (_STLP_MSVC)
00402 // MSVC specific
00403 template <class _InputIterator, class _Dist>
00404 inline void  _STLP_CALL _Distance(_InputIterator __first, 
00405                       _InputIterator __last, _Dist& __n) {
00406   __distance(__first, __last, __n, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00407 }
00408 # endif
00409 
00410 template <class _InputIter, class _Distance>
00411 _STLP_INLINE_LOOP void  _STLP_CALL __advance(_InputIter& __i, _Distance __n, const input_iterator_tag &) {
00412   while (__n--) ++__i;
00413 }
00414 
00415 // fbp : added output iterator tag variant
00416 template <class _InputIter, class _Distance>
00417 _STLP_INLINE_LOOP void  _STLP_CALL __advance(_InputIter& __i, _Distance __n, const output_iterator_tag &) {
00418   while (__n--) ++__i;
00419 }
00420 
00421 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
00422 template <class _ForwardIterator, class _Distance>
00423 _STLP_INLINE_LOOP void _STLP_CALL __advance(_ForwardIterator& i, _Distance n, const forward_iterator_tag &) {
00424     while (n--) ++i;
00425 }
00426 # endif
00427 
00428 template <class _BidirectionalIterator, class _Distance>
00429 _STLP_INLINE_LOOP void _STLP_CALL __advance(_BidirectionalIterator& __i, _Distance __n, 
00430                       const bidirectional_iterator_tag &) {
00431   if (__n > 0)
00432     while (__n--) ++__i;
00433   else
00434     while (__n++) --__i;
00435 }
00436 
00437 template <class _RandomAccessIterator, class _Distance>
00438 inline void _STLP_CALL __advance(_RandomAccessIterator& __i, _Distance __n, 
00439                       const random_access_iterator_tag &) {
00440   __i += __n;
00441 }
00442 
00443 template <class _InputIterator, class _Distance>
00444 inline void _STLP_CALL advance(_InputIterator& __i, _Distance __n) {
00445   __advance(__i, __n, _STLP_ITERATOR_CATEGORY(__i, _InputIterator));
00446 }
00447 
00448 _STLP_END_NAMESPACE
00449 
00450 # if defined (_STLP_DEBUG) && ! defined (_STLP_DEBUG_H)
00451 #  include <stl/debug/_debug.h>
00452 # endif
00453 
00454 #endif /* _STLP_INTERNAL_ITERATOR_BASE_H */
00455 
00456 
00457 // Local Variables:
00458 // mode:C++
00459 // End:

Generated on Mon Jun 5 10:20:46 2006 for Intelligence.kdevelop by  doxygen 1.4.6