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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #ifndef STLSOFT_INCL_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR
00049 #define STLSOFT_INCL_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR_MAJOR 1
00053 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR_MINOR 3
00054 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR_REVISION 5
00055 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_INDEX_ITERATOR_EDIT 25
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00075 # include <stlsoft/stlsoft.h>
00076 #endif
00077
00078 #if !defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT)
00079 # error index_iterator cannot be used with compilers that do not support partial template specialisation
00080 #else
00081 # ifndef STLSOFT_INCL_STLSOFT_ITERATOR_HPP_ADAPTED_ITERATOR_TRAITS
00082 # include <stlsoft/iterators/adapted_iterator_traits.hpp>
00083 # endif
00084 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_POINTER_TYPE
00085 # include <stlsoft/meta/is_pointer_type.hpp>
00086 # endif
00087 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_YESNO
00088 # include <stlsoft/meta/yesno.hpp>
00089 # endif
00090 #endif
00091
00092
00093
00094
00095
00096 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00097 # define STLSOFT_INDEX_ITERATOR_MUTABLE_OP_SUPPORT
00098 #endif
00099
00100 #if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT)
00101 # if !defined(STLSOFT_COMPILER_IS_GCC) || \
00102 __GNUC__ > 4 || \
00103 ( __GNUC__ == 3 && \
00104 __GNUC_MINOR__ >= 4)
00105 # define STLSOFT_INDEX_ITERATOR_MEM_SEL_OP_SUPPORT
00106 # endif
00107 #endif
00108
00109
00110
00111
00112
00113 #ifndef _STLSOFT_NO_NAMESPACE
00114 namespace stlsoft
00115 {
00116 #endif
00117
00118
00119
00120
00121
00128 template< ss_typename_param_k I
00129 , ss_typename_param_k T = adapted_iterator_traits<I>
00130 >
00131
00132 class index_iterator
00133 {
00136 private:
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 public:
00153 typedef I base_iterator_type;
00154 typedef T traits_type;
00155 typedef index_iterator<I> class_type;
00156 typedef ss_typename_type_k traits_type::iterator_category iterator_category;
00157 typedef ss_typename_type_k traits_type::value_type value_type;
00158 typedef ss_typename_type_k traits_type::pointer pointer;
00159 typedef ss_typename_type_k traits_type::reference reference;
00160 typedef ss_typename_type_k traits_type::difference_type difference_type;
00161 typedef ss_typename_type_k traits_type::const_pointer const_pointer;
00162 typedef ss_typename_type_k traits_type::const_reference const_reference;
00163 typedef ss_typename_type_k traits_type::effective_reference effective_reference;
00164 typedef ss_typename_type_k traits_type::effective_const_reference effective_const_reference;
00165 typedef ss_ptrdiff_t index_type;
00166 typedef ss_typename_type_k traits_type::effective_pointer effective_pointer;
00167 typedef ss_typename_type_k traits_type::effective_const_pointer effective_const_pointer;
00169
00172 public:
00173 index_iterator()
00174 : m_it(base_iterator_type())
00175 , m_index(0)
00176 {}
00177 ss_explicit_k index_iterator(base_iterator_type it, index_type index = 0)
00178 : m_it(it)
00179 , m_index(index)
00180 {}
00181 index_iterator(class_type const& rhs)
00182 : m_it(rhs.m_it)
00183 , m_index(rhs.m_index)
00184 {}
00185
00187 base_iterator_type base() const
00188 {
00189 return m_it;
00190 }
00192
00195 public:
00196 class_type& operator ++()
00197 {
00198 ++m_it;
00199 ++m_index;
00200
00201 return *this;
00202 }
00203
00204 class_type operator ++(int)
00205 {
00206 class_type r(*this);
00207
00208 operator ++();
00209
00210 return r;
00211 }
00212
00213 #ifdef STLSOFT_INDEX_ITERATOR_MUTABLE_OP_SUPPORT
00214 effective_reference operator *()
00215 {
00216 return *m_it;
00217 }
00218 #endif
00219
00220 effective_const_reference operator *() const
00221 {
00222 return *m_it;
00223 }
00224
00225
00226 #ifdef STLSOFT_INDEX_ITERATOR_MEM_SEL_OP_SUPPORT
00227
00228 #if 0
00229 effective_pointer operator ->()
00230 {
00231 return m_it.operator ->();
00232 }
00233
00234 effective_const_pointer operator ->() const
00235 {
00236 return m_it.operator ->();
00237 }
00238 #else
00239 # ifdef STLSOFT_INDEX_ITERATOR_MUTABLE_OP_SUPPORT
00240 effective_pointer operator ->()
00241 {
00242 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00243
00244
00245 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00246
00247 return invoke_member_selection_operator_(yesno_t());
00248 }
00249 # endif
00250
00251 effective_const_pointer operator ->() const
00252 {
00253 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00254
00255
00256 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00257
00258 return invoke_member_selection_operator_(yesno_t());
00259 }
00260 #endif
00261
00262 #endif
00264
00267 public:
00268 class_type& operator --()
00269 {
00270 --m_it;
00271 --m_index;
00272
00273 return *this;
00274 }
00275
00276 class_type operator --(int)
00277 {
00278 class_type r(*this);
00279
00280 operator --();
00281
00282 return r;
00283 }
00285
00288 public:
00292 class_type& operator +=(difference_type n)
00293 {
00294 m_it += n;
00295 m_index += n;
00296
00297 return *this;
00298 }
00299
00303 class_type& operator -=(difference_type n)
00304 {
00305 m_it -= n;
00306 m_index -= n;
00307
00308 return *this;
00309 }
00310
00314
00315 #ifdef STLSOFT_INDEX_ITERATOR_MUTABLE_OP_SUPPORT
00316 effective_reference operator [](difference_type index)
00317 {
00318 return m_it[index];
00319 }
00320 #endif
00321
00325 effective_const_reference operator [](difference_type index) const
00326 {
00327 return m_it[index];
00328 }
00329
00331 difference_type distance(class_type const& rhs) const
00332 {
00333 return m_it - rhs.m_it;
00334 }
00336
00339 public:
00340 index_type index() const
00341 {
00342 return m_index;
00343 }
00345
00348 public:
00349 ss_bool_t equal(class_type const& rhs) const
00350 {
00351 return m_it == rhs.m_it;
00352 }
00353
00354 int compare(class_type const& rhs) const
00355 {
00356 return (m_it < rhs.m_it) ? -1 : (rhs.m_it < m_it) ? +1 : 0;
00357 }
00359
00362 private:
00363 #ifdef STLSOFT_INDEX_ITERATOR_MEM_SEL_OP_SUPPORT
00364 effective_pointer invoke_member_selection_operator_(yes_type)
00365 {
00366 return m_it;
00367 }
00368 effective_pointer invoke_member_selection_operator_(no_type)
00369 {
00370 return m_it.operator ->();
00371 }
00372
00373 effective_const_pointer invoke_member_selection_operator_(yes_type) const
00374 {
00375 return m_it;
00376 }
00377 effective_const_pointer invoke_member_selection_operator_(no_type) const
00378 {
00379 return m_it.operator ->();
00380 }
00381 #endif
00383
00386 private:
00387 base_iterator_type m_it;
00388 index_type m_index;
00390 };
00391
00392
00393
00394
00395
00405 template< ss_typename_param_k I
00406 >
00407 inline index_iterator<I> make_index_iterator(I it, ss_ptrdiff_t index = 0)
00408 {
00409 return index_iterator<I>(it, index);
00410 }
00411
00423 template< ss_typename_param_k I
00424 >
00425 inline index_iterator<I> indexer(I it, ss_ptrdiff_t index = 0)
00426 {
00427 return make_index_iterator(it, index);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 template< ss_typename_param_k I
00437 , ss_typename_param_k T
00438 >
00439 inline ss_bool_t operator ==(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00440 {
00441 return lhs.equal(rhs);
00442 }
00443
00444
00445
00446 template< ss_typename_param_k I
00447 , ss_typename_param_k T
00448 >
00449 inline ss_bool_t operator !=(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00450 {
00451 return !lhs.equal(rhs);
00452 }
00453
00454
00455
00456 template< ss_typename_param_k I
00457 , ss_typename_param_k T
00458 >
00459 inline index_iterator<I, T> operator +(index_iterator<I, T> const& lhs, ss_typename_type_k index_iterator<I, T>::difference_type rhs)
00460 {
00461 return index_iterator<I, T>(lhs) += rhs;
00462 }
00463
00464
00465
00466 template< ss_typename_param_k I
00467 , ss_typename_param_k T
00468 >
00469 #if 0
00470 inline index_iterator<I, T> operator -(index_iterator<I, T> const& lhs, ss_typename_type_k index_iterator<I, T>::difference_type rhs)
00471 #else
00472 inline index_iterator<I, T> operator -(index_iterator<I, T> const& lhs, ss_ptrdiff_t rhs)
00473 #endif
00474 {
00475 return index_iterator<I, T>(lhs) -= rhs;
00476 }
00477
00478 template< ss_typename_param_k I
00479 , ss_typename_param_k T
00480 >
00481 inline ss_typename_type_ret_k index_iterator<I, T>::difference_type operator -(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00482 {
00483 return lhs.distance(rhs);
00484 }
00485
00486
00487
00488 template< ss_typename_param_k I
00489 , ss_typename_param_k T
00490 >
00491 inline ss_bool_t operator <(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00492 {
00493 return lhs.compare(rhs) < 0;
00494 }
00495
00496
00497
00498 template< ss_typename_param_k I
00499 , ss_typename_param_k T
00500 >
00501 inline ss_bool_t operator <=(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00502 {
00503 return lhs.compare(rhs) <= 0;
00504 }
00505
00506
00507
00508 template< ss_typename_param_k I
00509 , ss_typename_param_k T
00510 >
00511 inline ss_bool_t operator >(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00512 {
00513 return lhs.compare(rhs) > 0;
00514 }
00515
00516
00517
00518 template< ss_typename_param_k I
00519 , ss_typename_param_k T
00520 >
00521 inline ss_bool_t operator >=(index_iterator<I, T> const& lhs, index_iterator<I, T> const& rhs)
00522 {
00523 return lhs.compare(rhs) >= 0;
00524 }
00525
00527
00528
00529 #ifdef STLSOFT_UNITTEST
00530 # include "./unittest/index_iterator_unittest_.h"
00531 #endif
00532
00533
00534
00535 #ifndef _STLSOFT_NO_NAMESPACE
00536 }
00537 #endif
00538
00539 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00540 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00541
00542 namespace std
00543 {
00544 template< ss_typename_param_k I
00545 , ss_typename_param_k T
00546 >
00547 inline ss_typename_type_ret_k stlsoft_ns_qual(index_iterator)<I, T>::iterator_category _Iter_cat(stlsoft_ns_qual(index_iterator)<I, T> const&)
00548 {
00549 return ss_typename_type_k stlsoft_ns_qual(index_iterator)<I, T>::iterator_category();
00550 }
00551 template< ss_typename_param_k I
00552 , ss_typename_param_k T
00553 >
00554 inline ss_typename_type_ret_k stlsoft_ns_qual(index_iterator)<I, T>::value_type *_Val_type(stlsoft_ns_qual(index_iterator)<I, T> const&)
00555 {
00556 return static_cast<stlsoft_ns_qual(index_iterator)<I, T>::value_type*>(0);
00557 }
00558
00559 # if STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION == STLSOFT_CF_DINKUMWARE_VC_VERSION_7_0
00560 template< ss_typename_param_k I
00561 , ss_typename_param_k T
00562 >
00563 inline ss_typename_type_ret_k stlsoft_ns_qual(index_iterator)<I, T>::difference_type *_Dist_type(stlsoft_ns_qual(index_iterator)<I, T> const&)
00564 {
00565 return static_cast<stlsoft_ns_qual(index_iterator)<I, T>::difference_type*>(0);
00566 }
00567 # elif STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00568 # else
00569 # error Error in discrimination
00570 # endif
00571
00572 }
00573
00574
00575 #endif
00576
00577
00578
00579 #endif
00580
00581