00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
00153
00154
00155
00156
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
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
00226
00227 # if ! defined (_STLP_NO_ANACHRONISMS)
00228
00229
00230
00231
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
00274
00275 #endif
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
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
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
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
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
00455
00456
00457
00458
00459