Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 1994
      4  * Hewlett-Packard Company
      5  *
      6  * Copyright (c) 1996-1998
      7  * Silicon Graphics Computer Systems, Inc.
      8  *
      9  * Copyright (c) 1997
     10  * Moscow Center for SPARC Technology
     11  *
     12  * Copyright (c) 1999
     13  * Boris Fomitchev
     14  *
     15  * This material is provided "as is", with absolutely no warranty expressed
     16  * or implied. Any use is at your own risk.
     17  *
     18  * Permission to use or copy this software for any purpose is hereby granted
     19  * without fee, provided the above notices are retained on all copies.
     20  * Permission to modify the code and to distribute modified code is granted,
     21  * provided the above notices are retained, and a notice that the code was
     22  * modified is included with the above copyright notice.
     23  *
     24  */
     25 
     26 /* NOTE: This is an internal header file, included by other STL headers.
     27  *   You should not attempt to use it directly.
     28  */
     29 
     30 #ifndef _STLP_INTERNAL_ITERATOR_BASE_H
     31 #define _STLP_INTERNAL_ITERATOR_BASE_H
     32 
     33 #ifndef _STLP_INTERNAL_CSTDDEF
     34 #  include <stl/_cstddef.h>
     35 #endif
     36 
     37 //# if defined  (_STLP_IMPORT_VENDOR_CSTD) && ! defined (_STLP_VENDOR_GLOBAL_CSTD)
     38 //_STLP_BEGIN_NAMESPACE
     39 //using namespace _STLP_VENDOR_CSTD;
     40 //_STLP_END_NAMESPACE
     41 //#endif /* _STLP_IMPORT_VENDOR_CSTD */
     42 
     43 #if !defined(_STLP_USE_OLD_HP_ITERATOR_QUERIES) && !defined(_STLP_CLASS_PARTIAL_SPECIALIZATION)
     44 #  ifndef _STLP_TYPE_TRAITS_H
     45 #    include <stl/type_traits.h>
     46 #  endif
     47 #endif
     48 
     49 _STLP_BEGIN_NAMESPACE
     50 
     51 struct input_iterator_tag {};
     52 struct output_iterator_tag {};
     53 struct forward_iterator_tag : public input_iterator_tag {};
     54 struct bidirectional_iterator_tag : public forward_iterator_tag {};
     55 struct random_access_iterator_tag : public bidirectional_iterator_tag {};
     56 
     57 template <class _Category, class _Tp, _STLP_DFL_TMPL_PARAM(_Distance,ptrdiff_t),
     58           _STLP_DFL_TMPL_PARAM(_Pointer,_Tp*), _STLP_DFL_TMPL_PARAM(_Reference,_Tp&) >
     59 struct iterator {
     60   typedef _Category  iterator_category;
     61   typedef _Tp        value_type;
     62   typedef _Distance  difference_type;
     63   typedef _Pointer   pointer;
     64   typedef _Reference reference;
     65 };
     66 _STLP_TEMPLATE_NULL
     67 struct iterator<output_iterator_tag, void, void, void, void> {
     68   typedef output_iterator_tag  iterator_category;
     69 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
     70   typedef void                value_type;
     71   typedef void                difference_type;
     72   typedef void                pointer;
     73   typedef void                reference;
     74 #endif
     75 };
     76 
     77 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
     78 #  define _STLP_ITERATOR_CATEGORY(_It, _Tp) _STLP_STD::iterator_category(_It)
     79 #  define _STLP_DISTANCE_TYPE(_It, _Tp)     _STLP_STD::distance_type(_It)
     80 #  define _STLP_VALUE_TYPE(_It, _Tp)        _STLP_STD::value_type(_It)
     81 //Old HP iterator queries do not give information about the iterator
     82 //associated reference type so we consider that it is not a real reference.
     83 #  define _STLP_IS_REF_TYPE_REAL_REF(_It, _Tp) __false_type()
     84 #else
     85 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
     86 #    define _STLP_VALUE_TYPE(_It, _Tp)        (_STLP_TYPENAME _STLP_STD::iterator_traits< _Tp >::value_type*)0
     87 #    define _STLP_DISTANCE_TYPE(_It, _Tp)     (_STLP_TYPENAME _STLP_STD::iterator_traits< _Tp >::difference_type*)0
     88 #    if defined (__BORLANDC__) || defined (__SUNPRO_CC) || ( defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || \
     89        (defined (__sgi) && defined (_COMPILER_VERSION)) || defined (__DMC__)
     90 #      define _STLP_ITERATOR_CATEGORY(_It, _Tp) _STLP_STD::iterator_traits< _Tp >::iterator_category()
     91 #    else
     92 #      define _STLP_ITERATOR_CATEGORY(_It, _Tp) _STLP_TYPENAME _STLP_STD::iterator_traits< _Tp >::iterator_category()
     93 #    endif
     94 #    define _STLP_IS_REF_TYPE_REAL_REF(_It, _Tp) _STLP_STD::_IsRefType< _STLP_TYPENAME _STLP_STD::iterator_traits< _Tp >::reference >::_Ret()
     95 #  else
     96 #    define _STLP_ITERATOR_CATEGORY(_It, _Tp)   _STLP_STD::__iterator_category(_It, _STLP_STD::_IsPtrType<_Tp>::_Ret())
     97 #    define _STLP_DISTANCE_TYPE(_It, _Tp)       _STLP_STD::__distance_type(_It, _STLP_STD::_IsPtrType<_Tp>::_Ret())
     98 #    define _STLP_VALUE_TYPE(_It, _Tp)          _STLP_STD::__value_type(_It, _STLP_STD::_IsPtrType<_Tp>::_Ret())
     99 #    define _STLP_IS_REF_TYPE_REAL_REF(_It, _Tp) __false_type()
    100 #  endif
    101 #endif
    102 
    103 #if defined (_STLP_DONT_REDEFINE_STD) && defined (_STLP_WHOLE_NATIVE_STD)
    104 /* In this mode we will see both STLport implementation and native
    105  * one. To allow some interaction between both implementations through
    106  * iterators we have to map std iterator categories to stlport ones. This
    107  * way we will be able to initialize STLport containers with native
    108  * iterators, the other side won't work except when STLport iterators are
    109  * simple pointers. */
    110 
    111 _STLP_END_NAMESPACE
    112 
    113 #  if defined (_STLP_HAS_INCLUDE_NEXT)
    114 #    include_next <iterator>
    115 #  else
    116 #    include _STLP_NATIVE_HEADER(iterator)
    117 #  endif
    118 
    119 _STLP_BEGIN_NAMESPACE
    120 
    121 template <class _IteCat>
    122 struct _CategoryMapping
    123 { typedef _IteCat _Tag; };
    124 
    125 _STLP_TEMPLATE_NULL
    126 struct _CategoryMapping<::std::input_iterator_tag>
    127 { typedef input_iterator_tag _Tag; };
    128 _STLP_TEMPLATE_NULL
    129 struct _CategoryMapping<::std::output_iterator_tag>
    130 { typedef output_iterator_tag _Tag; };
    131 _STLP_TEMPLATE_NULL
    132 struct _CategoryMapping<::std::forward_iterator_tag>
    133 { typedef forward_iterator_tag _Tag; };
    134 _STLP_TEMPLATE_NULL
    135 struct _CategoryMapping<::std::bidirectional_iterator_tag>
    136 { typedef bidirectional_iterator_tag _Tag; };
    137 _STLP_TEMPLATE_NULL
    138 struct _CategoryMapping<::std::random_access_iterator_tag>
    139 { typedef random_access_iterator_tag _Tag; };
    140 
    141 template <class _Iterator>
    142 struct iterator_traits {
    143   typedef typename _Iterator::iterator_category _OriginalTag;
    144   typedef typename _CategoryMapping<_OriginalTag>::_Tag iterator_category;
    145 #else
    146 template <class _Iterator>
    147 struct iterator_traits {
    148   typedef typename _Iterator::iterator_category iterator_category;
    149 #endif
    150   typedef typename _Iterator::value_type        value_type;
    151   typedef typename _Iterator::difference_type   difference_type;
    152   typedef typename _Iterator::pointer           pointer;
    153   typedef typename _Iterator::reference         reference;
    154 };
    155 
    156 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (__SUNPRO_CC)
    157 #  define _STLP_DIFFERENCE_TYPE(_Iterator) typename iterator_traits<_Iterator>::difference_type
    158 #else
    159 #  define _STLP_DIFFERENCE_TYPE(_Iterator) ptrdiff_t
    160 #endif
    161 
    162 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
    163 
    164 // fbp : this order keeps gcc happy
    165 template <class _Tp>
    166 struct iterator_traits<const _Tp*> {
    167   typedef random_access_iterator_tag  iterator_category;
    168   typedef _Tp                         value_type;
    169   typedef ptrdiff_t                   difference_type;
    170   typedef const _Tp*                  pointer;
    171   typedef const _Tp&                  reference;
    172 };
    173 
    174 template <class _Tp>
    175 struct iterator_traits<_Tp*> {
    176   typedef random_access_iterator_tag  iterator_category;
    177   typedef _Tp                         value_type;
    178   typedef ptrdiff_t                   difference_type;
    179   typedef _Tp*                        pointer;
    180   typedef _Tp&                        reference;
    181 };
    182 
    183 #  if defined (__BORLANDC__)
    184 template <class _Tp>
    185 struct iterator_traits<_Tp* const> {
    186   typedef random_access_iterator_tag  iterator_category;
    187   typedef _Tp                         value_type;
    188   typedef ptrdiff_t                   difference_type;
    189   typedef const _Tp*                  pointer;
    190   typedef const _Tp&                  reference;
    191 };
    192 #  endif
    193 
    194 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
    195 
    196 _STLP_END_NAMESPACE
    197 #include <stl/_ptrs_specialize.h>
    198 _STLP_BEGIN_NAMESPACE
    199 
    200 #ifndef _STLP_USE_OLD_HP_ITERATOR_QUERIES
    201 // The overloaded functions iterator_category, distance_type, and
    202 // value_type are not part of the C++ standard.  (They have been
    203 // replaced by struct iterator_traits.)  They are included for
    204 // backward compatibility with the HP STL.
    205 // We introduce internal names for these functions.
    206 
    207 #  ifndef _STLP_CLASS_PARTIAL_SPECIALIZATION
    208 
    209 template <class _Tp>
    210 inline _STLP_STD::random_access_iterator_tag
    211 __iterator_category(const _Tp*, const __true_type&)
    212 { return _STLP_STD::random_access_iterator_tag(); }
    213 
    214 template <class _Iter>
    215 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_STD::iterator_traits<_Iter>::iterator_category
    216 __iterator_category(const _Iter&, const __false_type&) {
    217   typedef _STLP_TYPENAME _STLP_STD::iterator_traits<_Iter>::iterator_category _Category;
    218   return _Category();
    219 }
    220 
    221 template <class _Tp>
    222 inline ptrdiff_t*
    223 __distance_type(const _Tp*, const __true_type&)
    224 { return __STATIC_CAST(ptrdiff_t*, 0); }
    225 
    226 template <class _Iter>
    227 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_STD::iterator_traits<_Iter>::difference_type*
    228 __distance_type(const _Iter&, const __false_type&) {
    229   typedef _STLP_TYPENAME _STLP_STD::iterator_traits<_Iter>::difference_type _diff_type;
    230   return __STATIC_CAST(_diff_type*,0);
    231 }
    232 
    233 template <class _Tp>
    234 inline _Tp*
    235 __value_type(const _Tp*, const __true_type&)
    236 { return __STATIC_CAST(_Tp*, 0); }
    237 
    238 template <class _Iter>
    239 inline _STLP_TYPENAME_ON_RETURN_TYPE _STLP_STD::iterator_traits<_Iter>::value_type*
    240 __value_type(const _Iter&, const __false_type&) {
    241   typedef _STLP_TYPENAME _STLP_STD::iterator_traits<_Iter>::value_type _value_type;
    242   return __STATIC_CAST(_value_type*,0);
    243 }
    244 
    245 #  endif
    246 
    247 #else /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
    248 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
    249 inline _Category _STLP_CALL iterator_category(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return _Category(); }
    250 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
    251 inline _Tp* _STLP_CALL value_type(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return __STATIC_CAST(_Tp*, 0); }
    252 template <class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
    253 inline _Distance* _STLP_CALL distance_type(const iterator<_Category,_Tp,_Distance,_Pointer,_Reference>&) { return __STATIC_CAST(_Distance*, 0); }
    254 template <class _Tp>
    255 inline random_access_iterator_tag _STLP_CALL iterator_category(const _Tp*) { return random_access_iterator_tag(); }
    256 template <class _Tp>
    257 inline _Tp* _STLP_CALL value_type(const _Tp*) { return __STATIC_CAST(_Tp*, 0); }
    258 template <class _Tp>
    259 inline ptrdiff_t* _STLP_CALL distance_type(const _Tp*) { return __STATIC_CAST(ptrdiff_t*, 0); }
    260 #endif /* _STLP_USE_OLD_HP_ITERATOR_QUERIES */
    261 
    262 #if !defined (_STLP_NO_ANACHRONISMS)
    263 // The base classes input_iterator, output_iterator, forward_iterator,
    264 // bidirectional_iterator, and random_access_iterator are not part of
    265 // the C++ standard.  (They have been replaced by struct iterator.)
    266 // They are included for backward compatibility with the HP STL.
    267 template <class _Tp, class _Distance> struct input_iterator :
    268   public iterator <input_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
    269 struct output_iterator : public iterator <output_iterator_tag, void, void, void, void> {};
    270 template <class _Tp, class _Distance> struct forward_iterator :
    271   public iterator<forward_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
    272 template <class _Tp, class _Distance> struct bidirectional_iterator :
    273   public iterator<bidirectional_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
    274 template <class _Tp, class _Distance> struct random_access_iterator :
    275   public iterator<random_access_iterator_tag, _Tp, _Distance, _Tp*, _Tp&> {};
    276 
    277 #  if defined (_STLP_BASE_MATCH_BUG) && defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
    278 template <class _Tp, class _Distance>
    279 inline input_iterator_tag _STLP_CALL
    280 iterator_category(const input_iterator<_Tp, _Distance>&) { return input_iterator_tag(); }
    281 inline output_iterator_tag _STLP_CALL
    282 iterator_category(const output_iterator&) { return output_iterator_tag(); }
    283 template <class _Tp, class _Distance>
    284 inline forward_iterator_tag _STLP_CALL
    285 iterator_category(const forward_iterator<_Tp, _Distance>&) { return forward_iterator_tag(); }
    286 template <class _Tp, class _Distance>
    287 inline bidirectional_iterator_tag _STLP_CALL
    288 iterator_category(const bidirectional_iterator<_Tp, _Distance>&) { return bidirectional_iterator_tag(); }
    289 template <class _Tp, class _Distance>
    290 inline random_access_iterator_tag _STLP_CALL
    291 iterator_category(const random_access_iterator<_Tp, _Distance>&) { return random_access_iterator_tag(); }
    292 template <class _Tp, class _Distance>
    293 inline _Tp*  _STLP_CALL value_type(const input_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Tp*, 0); }
    294 template <class _Tp, class _Distance>
    295 inline _Tp* _STLP_CALL value_type(const forward_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Tp*, 0); }
    296 template <class _Tp, class _Distance>
    297 inline _Tp* _STLP_CALL value_type(const bidirectional_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Tp*, 0); }
    298 template <class _Tp, class _Distance>
    299 inline _Tp* _STLP_CALL value_type(const random_access_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Tp*, 0); }
    300 template <class _Tp, class _Distance>
    301 inline _Distance* _STLP_CALL distance_type(const input_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Distance*, 0); }
    302 template <class _Tp, class _Distance>
    303 inline _Distance* _STLP_CALL distance_type(const forward_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Distance*, 0); }
    304 template <class _Tp, class _Distance>
    305 inline _Distance* _STLP_CALL distance_type(const bidirectional_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Distance*, 0);}
    306 template <class _Tp, class _Distance>
    307 inline _Distance* _STLP_CALL distance_type(const random_access_iterator<_Tp, _Distance>&) { return __STATIC_CAST(_Distance*, 0); }
    308 #  endif
    309 #endif
    310 
    311 _STLP_MOVE_TO_PRIV_NAMESPACE
    312 
    313 template <class _InputIterator>
    314 inline _STLP_DIFFERENCE_TYPE(_InputIterator) _STLP_CALL
    315 __distance(const _InputIterator& __first, const _InputIterator& __last,
    316            const input_iterator_tag &) {
    317   _STLP_DIFFERENCE_TYPE(_InputIterator) __n = 0;
    318   _InputIterator __it(__first);
    319   while (__it != __last) {
    320     ++__it; ++__n;
    321   }
    322   return __n;
    323 }
    324 
    325 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
    326 template <class _ForwardIterator>
    327 inline _STLP_DIFFERENCE_TYPE(_ForwardIterator) _STLP_CALL
    328 __distance(const _ForwardIterator& __first, const _ForwardIterator& __last,
    329            const forward_iterator_tag &) {
    330   _STLP_DIFFERENCE_TYPE(_ForwardIterator) __n = 0;
    331   _ForwardIterator __it(__first);
    332   while (__it != __last) {
    333     ++__it; ++__n;
    334   }
    335   return __n;
    336 }
    337 
    338 template <class _BidirectionalIterator>
    339 _STLP_INLINE_LOOP _STLP_DIFFERENCE_TYPE(_BidirectionalIterator) _STLP_CALL
    340 __distance(const _BidirectionalIterator& __first, const _BidirectionalIterator& __last,
    341            const bidirectional_iterator_tag &) {
    342   _STLP_DIFFERENCE_TYPE(_BidirectionalIterator) __n = 0;
    343   _BidirectionalIterator __it(__first);
    344   while (__it != __last) {
    345     ++__it; ++__n;
    346   }
    347   return __n;
    348 }
    349 #endif
    350 
    351 template <class _RandomAccessIterator>
    352 inline _STLP_DIFFERENCE_TYPE(_RandomAccessIterator) _STLP_CALL
    353 __distance(const _RandomAccessIterator& __first, const _RandomAccessIterator& __last,
    354            const random_access_iterator_tag &)
    355 { return __last - __first; }
    356 
    357 _STLP_MOVE_TO_STD_NAMESPACE
    358 
    359 template <class _InputIterator>
    360 inline _STLP_DIFFERENCE_TYPE(_InputIterator) _STLP_CALL
    361 distance(_InputIterator __first, _InputIterator __last)
    362 { return _STLP_PRIV __distance(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator)); }
    363 
    364 #if !defined (_STLP_NO_ANACHRONISMS)
    365 template <class _InputIterator, class _Distance>
    366 inline void _STLP_CALL distance(const _InputIterator& __first,
    367                                 const _InputIterator& __last, _Distance& __n)
    368 { __n += _STLP_STD::distance(__first, __last); }
    369 
    370 #  if defined (_STLP_MSVC)
    371 // MSVC specific
    372 template <class _InputIterator, class _Dist>
    373 inline void  _STLP_CALL _Distance(_InputIterator __first,
    374                                   _InputIterator __last, _Dist& __n)
    375 { __n += _STLP_STD::distance(__first, __last); }
    376 #  endif
    377 #endif
    378 
    379 // fbp: those are being used for iterator/const_iterator definitions everywhere
    380 template <class _Tp>
    381 struct _Nonconst_traits;
    382 
    383 template <class _Tp>
    384 struct _Const_traits {
    385   typedef _Tp value_type;
    386   typedef const _Tp&  reference;
    387   typedef const _Tp*  pointer;
    388   typedef _Const_traits<_Tp> _ConstTraits;
    389   typedef _Nonconst_traits<_Tp> _NonConstTraits;
    390 };
    391 
    392 template <class _Tp>
    393 struct _Nonconst_traits {
    394   typedef _Tp value_type;
    395   typedef _Tp& reference;
    396   typedef _Tp* pointer;
    397   typedef _Const_traits<_Tp> _ConstTraits;
    398   typedef _Nonconst_traits<_Tp> _NonConstTraits;
    399 };
    400 
    401 /*
    402  * dums: A special iterator/const_iterator traits for set and multiset for which even
    403  * the iterator is not mutable
    404  */
    405 template <class _Tp>
    406 struct _Nonconst_Const_traits;
    407 
    408 template <class _Tp>
    409 struct _Const_Const_traits {
    410   typedef _Tp value_type;
    411   typedef const _Tp&  reference;
    412   typedef const _Tp*  pointer;
    413   typedef _Const_Const_traits<_Tp> _ConstTraits;
    414   typedef _Nonconst_Const_traits<_Tp> _NonConstTraits;
    415 };
    416 
    417 template <class _Tp>
    418 struct _Nonconst_Const_traits {
    419   typedef _Tp value_type;
    420   typedef const _Tp& reference;
    421   typedef const _Tp* pointer;
    422   typedef _Const_Const_traits<_Tp> _ConstTraits;
    423   typedef _Nonconst_Const_traits<_Tp> _NonConstTraits;
    424 };
    425 
    426 /*
    427  * A macro to generate a new iterator traits from one of the
    428  * previous one. Changing the iterator traits type make iterators
    429  * from different containers not comparable.
    430  */
    431 #define _STLP_CREATE_ITERATOR_TRAITS_BASE(Motif, Traits)        \
    432 template <class _Tp>                                            \
    433 struct _##Motif;                                                \
    434 template <class _Tp>                                            \
    435 struct _Const##Motif : public _STLP_STD::_Const_##Traits<_Tp> {  \
    436   typedef _Const##Motif<_Tp> _ConstTraits;                      \
    437   typedef _##Motif<_Tp> _NonConstTraits;                        \
    438 };                                                              \
    439 template <class _Tp>                                            \
    440 struct _##Motif : public _STLP_STD::_Nonconst_##Traits<_Tp> {    \
    441   typedef _Const##Motif<_Tp> _ConstTraits;                      \
    442   typedef _##Motif<_Tp> _NonConstTraits;                        \
    443 };
    444 
    445 #define _STLP_CREATE_ITERATOR_TRAITS(Motif, Traits)             \
    446 _STLP_MOVE_TO_PRIV_NAMESPACE                                    \
    447 _STLP_CREATE_ITERATOR_TRAITS_BASE(Motif, Traits)                \
    448 _STLP_MOVE_TO_STD_NAMESPACE
    449 
    450 #define _STLP_CREATE_HASH_ITERATOR_TRAITS(Motif, Traits)        \
    451 _STLP_MOVE_TO_PRIV_NAMESPACE                                    \
    452 _STLP_CREATE_ITERATOR_TRAITS_BASE(NonLocal##Motif, Traits)      \
    453 _STLP_CREATE_ITERATOR_TRAITS_BASE(Local##Motif, Traits)         \
    454 template <class _Tp>                                            \
    455 struct _##Motif {                                               \
    456   typedef _ConstNonLocal##Motif<_Tp> _ConstTraits;              \
    457   typedef _NonLocal##Motif<_Tp> _NonConstTraits;                \
    458   typedef _ConstLocal##Motif<_Tp> _ConstLocalTraits;            \
    459   typedef _Local##Motif<_Tp> _NonConstLocalTraits;              \
    460 };                                                              \
    461 _STLP_MOVE_TO_STD_NAMESPACE
    462 
    463 /*
    464 #  if defined (_STLP_BASE_TYPEDEF_BUG)
    465 // this workaround is needed for SunPro 4.0.1
    466 template <class _Traits>
    467 struct __cnst_traits_aux : private _Traits {
    468   typedef typename _Traits::value_type value_type;
    469 };
    470 #  define __TRAITS_VALUE_TYPE(_Traits) __cnst_traits_aux<_Traits>::value_type
    471 #  else
    472 #  define __TRAITS_VALUE_TYPE(_Traits) _Traits::value_type
    473 #  endif
    474 */
    475 
    476 _STLP_MOVE_TO_PRIV_NAMESPACE
    477 
    478 template <class _InputIter, class _Distance>
    479 _STLP_INLINE_LOOP void _STLP_CALL
    480 __advance(_InputIter& __i, _Distance __n, const input_iterator_tag &)
    481 { while (__n--) ++__i; }
    482 
    483 // fbp : added output iterator tag variant
    484 template <class _InputIter, class _Distance>
    485 _STLP_INLINE_LOOP void _STLP_CALL
    486 __advance(_InputIter& __i, _Distance __n, const output_iterator_tag &)
    487 { while (__n--) ++__i; }
    488 
    489 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
    490 template <class _ForwardIterator, class _Distance>
    491 _STLP_INLINE_LOOP void _STLP_CALL
    492 __advance(_ForwardIterator& i, _Distance n, const forward_iterator_tag &)
    493 { while (n--) ++i; }
    494 #endif
    495 
    496 template <class _BidirectionalIterator, class _Distance>
    497 _STLP_INLINE_LOOP void _STLP_CALL
    498 __advance(_BidirectionalIterator& __i, _Distance __n,
    499           const bidirectional_iterator_tag &) {
    500   if (__n > 0)
    501     while (__n--) ++__i;
    502   else
    503     while (__n++) --__i;
    504 }
    505 
    506 template <class _RandomAccessIterator, class _Distance>
    507 inline void _STLP_CALL
    508 __advance(_RandomAccessIterator& __i, _Distance __n,
    509           const random_access_iterator_tag &)
    510 { __i += __n; }
    511 
    512 _STLP_MOVE_TO_STD_NAMESPACE
    513 
    514 template <class _InputIterator, class _Distance>
    515 inline void _STLP_CALL advance(_InputIterator& __i, _Distance __n)
    516 { _STLP_PRIV __advance(__i, __n, _STLP_ITERATOR_CATEGORY(__i, _InputIterator)); }
    517 
    518 _STLP_END_NAMESPACE
    519 
    520 #endif /* _STLP_INTERNAL_ITERATOR_BASE_H */
    521 
    522 
    523 // Local Variables:
    524 // mode:C++
    525 // End:
    526