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