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
00041
00042
00043
00051 #ifndef STLSOFT_INCL_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR
00052 #define STLSOFT_INCL_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR
00053
00054 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR_MAJOR 2
00056 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR_MINOR 4
00057 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR_REVISION 6
00058 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_MEMBER_SELECTOR_ITERATOR_EDIT 56
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00076 # include <stlsoft/stlsoft.h>
00077 #endif
00078 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00079 # include <stlsoft/util/std/iterator_helper.hpp>
00080 #endif
00081 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00082 # include <stlsoft/meta/capabilities.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_CONST_TYPE
00085 # include <stlsoft/meta/is_const_type.hpp>
00086 #endif
00087 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00088 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_BASE_TYPE_TRAITS
00089 # include <stlsoft/meta/base_type_traits.hpp>
00090 # endif
00091 # if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00092 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00093 # ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_DINKUMWARE_ITERATOR_TRAITS
00094 # include <stlsoft/util/std/dinkumware_iterator_traits.hpp>
00095 # endif
00096 # endif
00097 #endif
00098
00099 #ifdef STLSOFT_UNITTEST
00100 # include <algorithm>
00101 #endif
00102
00103
00104
00105
00106
00107 #ifndef _STLSOFT_NO_NAMESPACE
00108 namespace stlsoft
00109 {
00110 #endif
00111
00112
00113
00114
00115
00116 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00117 template< ss_typename_param_k I
00118 , ss_typename_param_k C
00119 , ss_typename_param_k M
00120 >
00121 struct msi_parent_type
00122
00123
00124
00125
00126
00127
00128
00129
00130 # if defined(STLSOFT_ITERATOR_ITERATOR_FORM1_SUPPORT) && \
00131 defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00132 ( !defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) || \
00133 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION >= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1) && \
00134 !defined(STLSOFT_COMPILER_IS_BORLAND) && \
00135 !defined(STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW)
00136 : public iterator_base< ss_typename_type_k stlsoft_ns_qual_std(iterator_traits)<I>::iterator_category
00137 , M
00138 , ss_ptrdiff_t
00139 , M*
00140 , M&
00141 >
00142 # elif defined(STLSOFT_ITERATOR_ITERATOR_FORM2_SUPPORT) || \
00143 ( defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00144 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION == STLSOFT_CF_DINKUMWARE_VC_VERSION_7_0) || \
00145 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
00146 _MSC_VER == 1300) || \
00147 defined(STLSOFT_COMPILER_IS_BORLAND) || \
00148 defined(STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW)
00149 : public iterator_base< stlsoft_ns_qual_std(input_iterator_tag)
00150 , M
00151 , ss_ptrdiff_t
00152 , M*
00153 , M&
00154 >
00155 # elif defined(STLSOFT_ITERATOR_ITERATOR_FORM3_SUPPORT)
00156
00157 # else
00158 # error iterator support type not discriminated
00159 # endif
00160 {
00163 public:
00164 # if defined(STLSOFT_ITERATOR_ITERATOR_FORM3_SUPPORT)
00165 typedef stlsoft_ns_qual_std(input_iterator_tag) iterator_category;
00166 # endif
00167 typedef I base_iterator_type;
00168 typedef C selected_class_type;
00169 typedef M value_type;
00170 typedef value_type* pointer;
00171 typedef value_type const* const_pointer;
00172 typedef value_type& reference;
00173 typedef value_type const& const_reference;
00174 typedef ss_size_t size_type;
00175 typedef ss_ptrdiff_t difference_type;
00177 };
00178 #endif
00179
00180
00190 template< ss_typename_param_k I
00191 , ss_typename_param_k C
00192 , ss_typename_param_k M
00193 >
00194
00195 class member_selector_iterator
00196 : public msi_parent_type<I, C, M>
00197 {
00200 private:
00201 typedef msi_parent_type<I, C, M> parent_class_type;
00202 public:
00203 typedef ss_typename_type_k parent_class_type::base_iterator_type base_iterator_type;
00204 typedef ss_typename_type_k parent_class_type::selected_class_type selected_class_type;
00205 typedef ss_typename_type_k parent_class_type::value_type value_type;
00206 typedef ss_typename_type_k parent_class_type::pointer pointer;
00207 typedef ss_typename_type_k parent_class_type::const_pointer const_pointer;
00208 typedef ss_typename_type_k parent_class_type::reference reference;
00209 typedef ss_typename_type_k parent_class_type::const_reference const_reference;
00210 typedef ss_typename_type_k parent_class_type::size_type size_type;
00211 typedef ss_typename_type_k parent_class_type::difference_type difference_type;
00212 typedef member_selector_iterator<I, C, M> class_type;
00214
00217 public:
00219 member_selector_iterator(base_iterator_type it, M C::*member)
00220 : m_it(it)
00221 , m_member(member)
00222 {}
00223
00225 member_selector_iterator(class_type const& rhs)
00226 : m_it(rhs.m_it)
00227 , m_member(rhs.m_member)
00228 {}
00229
00231 ~member_selector_iterator() stlsoft_throw_0()
00232 {
00233 void (*p)() = constraints;
00234
00235 STLSOFT_SUPPRESS_UNUSED(p);
00236 }
00237 private:
00238 static void constraints()
00239 {
00240 C *p = 0;
00241 M C::*pm = 0;
00242 #if defined(STLSOFT_COMPILER_IS_BORLAND)
00243 M &m = p->*pm;
00244 #else
00245 M const& m = p->*pm;
00246 #endif
00247
00248 STLSOFT_SUPPRESS_UNUSED(m);
00249 }
00250 public:
00252 base_iterator_type base() const
00253 {
00254 return m_it;
00255 }
00259 base_iterator_type current() const
00260 {
00261 return m_it;
00262 }
00264
00267 public:
00269 value_type C::* member() const
00270 {
00271 return m_member;
00272 }
00274
00277 public:
00281 class_type& operator ++()
00282 {
00283 ++m_it;
00284
00285 return *this;
00286 }
00290 class_type operator ++(int)
00291 {
00292 class_type r(*this);
00293
00294 operator ++();
00295
00296 return r;
00297 }
00298 # if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00299 !defined(STLSOFT_COMPILER_IS_BORLAND)
00301 reference operator *()
00302 {
00303 return (*m_it).*m_member;
00304 }
00305 # endif
00307 const_reference operator *() const
00308 {
00309 return (*m_it).*m_member;
00310 }
00311
00313 bool equal(class_type const& rhs) const
00314 {
00315 STLSOFT_ASSERT(m_member == rhs.m_member);
00316
00317 return m_it == rhs.m_it;
00318 }
00320
00323 public:
00327 class_type& operator --()
00328 {
00329 --m_it;
00330
00331 return *this;
00332 }
00336 class_type operator --(int)
00337 {
00338 class_type r(*this);
00339
00340 operator --();
00341
00342 return r;
00343 }
00345
00348 public:
00352 class_type& operator +=(difference_type n)
00353 {
00354 m_it += n;
00355
00356 return *this;
00357 }
00358
00362 class_type& operator -=(difference_type n)
00363 {
00364 m_it -= n;
00365
00366 return *this;
00367 }
00368
00372 value_type& operator [](difference_type index)
00373 {
00374 return m_it[index];
00375 }
00376
00380 value_type const& operator [](difference_type index) const
00381 {
00382 return m_it[index];
00383 }
00384
00386 difference_type distance(class_type const& rhs) const
00387 {
00388 return m_it - rhs.m_it;
00389 }
00391
00394 private:
00395 base_iterator_type m_it;
00396 M C:: *m_member;
00398 };
00399
00400 #if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00401 !defined(STLSOFT_COMPILER_IS_DMC) && \
00402 !defined(STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW)
00403
00404 # if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00405 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00406
00407 template <ss_typename_param_k I>
00408 struct msi_iterator_traits
00409 {
00410 public:
00411 enum
00412 {
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 is_const = Dinkumware_iterator_traits<I>::is_const
00435 };
00436 };
00437
00438 template<ss_typename_param_k T>
00439 struct msi_iterator_traits<T*>
00440 {
00441 enum { is_const = 0 };
00442 };
00443 template<ss_typename_param_k T>
00444 struct msi_iterator_traits<T const*>
00445 {
00446 enum { is_const = 1 };
00447 };
00448 template<ss_typename_param_k T>
00449 struct msi_iterator_traits<T volatile*>
00450 {
00451 enum { is_const = 0 };
00452 };
00453 template<ss_typename_param_k T>
00454 struct msi_iterator_traits<T const volatile*>
00455 {
00456 enum { is_const = 1 };
00457 };
00458 #endif
00459
00460
00466 template< ss_typename_param_k I
00467 , class C
00468 , ss_typename_param_k M
00469 >
00470 struct msi_traits
00471 {
00472 private:
00473 typedef member_selector_iterator<I, C, const M> const_msi_type;
00474 typedef member_selector_iterator<I, C, M> non_const_msi_type;
00475 #if !defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) || \
00476 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION >= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00477 typedef ss_typename_type_k std::iterator_traits<I>::pointer tested_member_type;
00478
00479 enum
00480 {
00481 is_const = base_type_traits<tested_member_type>::is_const
00482 };
00483 #endif
00484 public:
00485
00486 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00487 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00488 typedef ss_typename_type_k select_first_type_if< const_msi_type
00489 , non_const_msi_type
00490 , msi_iterator_traits<I>::is_const
00491 >::type type;
00492 #else
00493 typedef ss_typename_type_k select_first_type_if< const_msi_type
00494 , non_const_msi_type
00495 #if 0
00496 ,
00497 base_type_traits<tested_member_type>::is_const
00498
00499 #else
00500 , is_const
00501 #endif
00502
00503 >::type type;
00504 #endif
00505 };
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00553 template< ss_typename_param_k I
00554 , class C
00555 , ss_typename_param_k M
00556 >
00557 inline ss_typename_type_ret_k msi_traits<I, C, M>::type member_selector(I it, M C::*member)
00558 {
00559 typedef ss_typename_type_k msi_traits<I, C, M>::type iterator_t;
00560
00561 #if !defined(STLSOFT_COMPILER_IS_DMC) && \
00562 ( !defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) || \
00563 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION >= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1)
00564 STLSOFT_STATIC_ASSERT((int)is_const_type<ss_typename_type_k std::iterator_traits<I>::value_type>::value == (int)base_type_traits<ss_typename_type_k std::iterator_traits<I>::value_type>::is_const);
00565 #endif
00566
00567
00568
00569 return iterator_t(it, member);
00570 }
00571
00572 #else
00573
00574 # if 0 || \
00575 defined(STLSOFT_COMPILER_IS_DMC)
00576 template< ss_typename_param_k I
00577 , class C
00578 , ss_typename_param_k M
00579 >
00580 inline member_selector_iterator<I, C, M> member_selector(I it, M C::*member)
00581 {
00582 return member_selector_iterator<I, C, M>(it, member);
00583 }
00584 # endif
00585
00586 #if 0
00587
00591 template< ss_typename_param_k I
00592 , class C
00593 , ss_typename_param_k M
00594 >
00595 inline member_selector_iterator<I, C, const M> member_selector(I it, const M C::*member)
00596 {
00597 return member_selector_iterator<I, C, const M>(it, member);
00598 }
00599 #endif
00600
00601 #if 0 || \
00602 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
00603 _MSC_VER < 1310) || \
00604 defined(STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW)
00605 template< class C
00606 , ss_typename_param_k M
00607 >
00608 inline member_selector_iterator<C*, C, M> member_selector(C *it, M C::*member)
00609 {
00610 return member_selector_iterator<C*, C, M>(it, member);
00611 }
00612 #endif
00613
00614 # if 0
00615
00616 || \
00617 defined(STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW)
00618 template< class C
00619 , ss_typename_param_k M
00620 >
00621 inline member_selector_iterator<C const*, C, const M> member_selector(C const* it, M C::*member)
00622 {
00623 return member_selector_iterator<C const*, C, const M>(it, member);
00624 }
00625 #endif
00626
00627 #if 0
00628
00629
00630
00631
00632
00633
00634
00635 #endif
00636
00637 #if 0
00638 template< class C
00639 , ss_typename_param_k M
00640 >
00641 inline member_selector_const_iterator<C const*, C, const M> member_selector(C const* it, const M C::*member)
00642 {
00643 return member_selector_const_iterator<C const*, C, const M>(it, member);
00644 }
00645 #endif
00646
00647 # endif
00648
00649
00650
00651
00652
00653 template< ss_typename_param_k I
00654 , class C
00655 , ss_typename_param_k M
00656 >
00657 inline bool operator ==(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00658 {
00659 return lhs.equal(rhs);
00660 }
00661
00662 template< ss_typename_param_k I
00663 , class C
00664 , ss_typename_param_k M
00665 >
00666 inline bool operator !=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00667 {
00668 return !lhs.equal(rhs);
00669 }
00670
00671
00672 template< ss_typename_param_k I
00673 , class C
00674 , ss_typename_param_k M
00675 >
00676 inline member_selector_iterator<I, C, M> operator +(member_selector_iterator<I, C, M> const& lhs, ss_ptrdiff_t delta)
00677 {
00678 return member_selector_iterator<I, C, M>(lhs.current() + delta, lhs.member());
00679 }
00680
00681 template< ss_typename_param_k I
00682 , class C
00683 , ss_typename_param_k M
00684 >
00685 inline member_selector_iterator<I, C, M> operator -(member_selector_iterator<I, C, M> const& lhs, ss_ptrdiff_t delta)
00686 {
00687 return member_selector_iterator<I, C, M>(lhs.current() - delta, lhs.member());
00688 }
00689
00690 template< ss_typename_param_k I
00691 , class C
00692 , ss_typename_param_k M
00693 >
00694 inline ss_ptrdiff_t operator -(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00695 {
00696 return lhs.distance(rhs);
00697 }
00698
00699
00700 template< ss_typename_param_k I
00701 , class C
00702 , ss_typename_param_k M
00703 >
00704 inline bool operator <(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00705 {
00706 return lhs.distance(rhs) < 0;
00707 }
00708
00709 template< ss_typename_param_k I
00710 , class C
00711 , ss_typename_param_k M
00712 >
00713 inline bool operator <=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00714 {
00715 return lhs.distance(rhs) <= 0;
00716 }
00717
00718 template< ss_typename_param_k I
00719 , class C
00720 , ss_typename_param_k M
00721 >
00722 inline bool operator >(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00723 {
00724 return lhs.distance(rhs) > 0;
00725 }
00726
00727 template< ss_typename_param_k I
00728 , class C
00729 , ss_typename_param_k M
00730 >
00731 inline bool operator >=(member_selector_iterator<I, C, M> const& lhs, member_selector_iterator<I, C, M> const& rhs)
00732 {
00733 return lhs.distance(rhs) >= 0;
00734 }
00735
00736
00737
00738
00739
00740 #ifdef STLSOFT_UNITTEST
00741 # include "./unittest/member_selector_iterator_unittest_.h"
00742 #endif
00743
00744
00745
00746 #ifndef _STLSOFT_NO_NAMESPACE
00747 }
00748 #endif
00749
00750
00751
00752 #endif
00753
00754