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 
00049 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS
00050 #define MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS
00051 
00052 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00053 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS_MAJOR     3
00054 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS_MINOR     0
00055 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS_REVISION  6
00056 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CLIST_ADAPTORS_EDIT      62
00057 #endif 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 #ifndef MFCSTL_INCL_MFCSTL_HPP_MFCSTL
00073 # include <mfcstl/mfcstl.hpp>
00074 #endif 
00075 #ifndef MFCSTL_INCL_MFCSTL_MEMORY_HPP_AFX_ALLOCATOR
00076 # include <mfcstl/memory/afx_allocator.hpp>
00077 #endif 
00078 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CLIST_SWAP
00079 # include <mfcstl/collections/clist_swap.hpp>
00080 #endif 
00081 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CLIST_TRAITS
00082 # include <mfcstl/collections/clist_traits.hpp>
00083 #endif 
00084 #ifndef MFCSTL_INCL_MFCSTL_UTIL_HPP_MEMORY_EXCEPTION_TRANSLATION_POLICIES
00085 # include <mfcstl/util/memory_exception_translation_policies.hpp>
00086 #endif 
00087 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_GENERATORS
00088 # include <stlsoft/util/std/iterator_generators.hpp>
00089 #endif 
00090 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00091 # include <stlsoft/meta/capabilities.hpp>
00092 #endif 
00093 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00094 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_SAME_TYPE
00095 #  include <stlsoft/meta/is_same_type.hpp>
00096 # endif 
00097 #endif 
00098 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00099 # include <stlsoft/collections/util/collections.hpp>
00100 #endif 
00101 #if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00102     !defined(MFCSTL_NO_INCLUDE_AFXTEMPL_BY_DEFAULT)
00103 # include <afxtempl.h>
00104 #endif 
00105 
00106 #ifdef STLSOFT_UNITTEST
00107 # include <afxtempl.h>
00108 # include <stlsoft/string/simple_string.hpp>
00109 #endif 
00110 
00111 
00112 
00113 
00114 
00115 #ifndef _MFCSTL_NO_NAMESPACE
00116 # if defined(_STLSOFT_NO_NAMESPACE) || \
00117      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00118 
00119 namespace mfcstl
00120 {
00121 # else
00122 
00123 
00124 namespace stlsoft
00125 {
00126 
00127 namespace mfcstl_project
00128 {
00129 
00130 # endif 
00131 #endif 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00157 
00158 template<   ss_typename_param_k L
00159         ,   ss_typename_param_k I
00160         ,   ss_typename_param_k T
00161         >
00162 class CList_adaptor_base;
00163 
00164 
00165 template<   ss_typename_param_k L
00166         ,   ss_typename_param_k T
00167         >
00168 class CList_cadaptor;
00169 
00170 template<   ss_typename_param_k L
00171         ,   ss_typename_param_k T
00172         >
00173 class CList_iadaptor;
00174 
00175 #endif 
00176 
00188 template<   ss_typename_param_k L
00189         ,   ss_typename_param_k I
00190         ,   ss_typename_param_k T
00191         >
00192 class CList_adaptor_base
00193     : public stlsoft_ns_qual(stl_collection_tag)
00194 {
00197 public:
00199     typedef L                                                                   list_type;
00200 private:
00201     typedef I                                                                   interface_class_type;
00202     typedef T                                                                   list_traits_type;
00203 #if defined(MFCSTL_CLIST_ADAPTORS_USE_BAD_ALLOC_POLICY)
00204     typedef bad_alloc_throwing_policy                                           exception_translation_policy_type;
00205 #else 
00206     typedef CMemoryException_throwing_policy                                    exception_translation_policy_type;
00207 #endif 
00208 public:
00213     typedef ss_typename_type_k list_traits_type::value_type                     value_type;
00215     typedef afx_allocator<value_type>                                           allocator_type;
00217     typedef ss_typename_type_k allocator_type::reference                        reference;
00219     typedef ss_typename_type_k allocator_type::const_reference                  const_reference;
00221     typedef ss_typename_type_k allocator_type::pointer                          pointer;
00223     typedef ss_typename_type_k allocator_type::const_pointer                    const_pointer;
00225     typedef ms_size_t                                                           size_type;
00227     typedef ms_ptrdiff_t                                                        difference_type;
00229     typedef CList_adaptor_base<L, I, T>                                         class_type;
00230 public:
00234     class const_iterator
00235         : public stlsoft_ns_qual(iterator_base)<mfcstl_ns_qual_std(input_iterator_tag)
00236                                             ,   value_type
00237                                             ,   ms_ptrdiff_t
00238                                             ,   void        
00239                                             ,   value_type  
00240                                             >
00241     {
00242         friend class CList_adaptor_base<L, I, T>;
00243 
00244         typedef const_iterator                                              class_type;
00245         
00246         
00247         
00248 # ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00249         typedef ss_typename_type_k CList_adaptor_base<L, I, T>::value_type  value_type;
00250 # endif 
00251 # ifndef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00252         typedef stlsoft_define_move_rhs_type(class_type)                    rhs_type;
00253 # endif 
00254 
00255     
00256     private:
00258         const_iterator(list_type const* list, POSITION pos)
00259             : m_list(list)
00260             , m_pos(pos)
00261             , m_value()
00262         {
00263             operator ++();
00264         }
00265     public:
00267         const_iterator()
00268             : m_list(NULL)
00269             , m_pos(NULL)
00270             , m_value()
00271         {}
00272 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00273         
00274         
00275         
00276         
00277 
00278 # else 
00280         const_iterator(rhs_type rhs)
00281             : m_list(rhs.m_list)
00282             , m_pos(rhs.m_pos)
00283             , m_value(rhs.m_value)
00284         {
00285             move_lhs_from_rhs(rhs).m_pos = NULL;
00286         }
00287 
00289         const_iterator const& operator =(rhs_type rhs)
00290         {
00291             m_list  =   rhs.m_list;
00292             m_pos   =   rhs.m_pos;
00293             m_value =   rhs.m_value;
00294 
00295             move_lhs_from_rhs(rhs).m_pos = NULL;
00296 
00297             return *this;
00298         }
00299 # endif 
00300 
00301     
00302     public:
00304         value_type operator *() const
00305         {
00306             MFCSTL_MESSAGE_ASSERT("", NULL != m_list);
00307 
00308             return m_value;
00309         }
00310 
00312         const_iterator& operator ++()
00313         {
00314             if(m_pos == NULL)
00315             {
00316                 MFCSTL_MESSAGE_ASSERT("operator ++() called on invalid iterator", NULL != m_list);
00317 
00318                 m_list = NULL;
00319             }
00320             else
00321             {
00322                 m_value = m_list->GetNext(m_pos);
00323             }
00324 
00325             return *this;
00326         }
00327 
00329 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00330         const_iterator operator ++(int)
00331 # else 
00332         void operator ++(int)
00333 # endif 
00334         {
00335 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00336             class_type  ret(*this);
00337 # endif 
00338 
00339             operator ++();
00340 
00341 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00342             return ret;
00343 # endif 
00344         }
00345 
00351         ms_bool_t operator ==(const_iterator const& rhs) const
00352         {
00353             
00354             
00355             
00356             
00357             
00358             
00359 
00360             MFCSTL_MESSAGE_ASSERT("invalid comparison between iterators from different ranges", (NULL == m_list || NULL == rhs.m_list || m_list == rhs.m_list));
00361 
00362             return m_pos == rhs.m_pos && m_list == rhs.m_list;
00363         }
00369         ms_bool_t operator !=(const_iterator const& rhs) const
00370         {
00371             return !operator ==(rhs);
00372         }
00373 
00374     
00375     private:
00376         list_type const*    m_list;
00377         POSITION            m_pos;
00378         value_type          m_value;
00379     };
00381 
00384 public:
00386     list_type&          get_CList()
00387     {
00388         return static_cast<interface_class_type*>(this)->get_actual_list();
00389     }
00391     list_type const&    get_CList() const
00392     {
00393         return static_cast<interface_class_type const*>(this)->get_actual_list();
00394     }
00396 
00399 protected:
00404     CList_adaptor_base()
00405     {}
00407     ~CList_adaptor_base() stlsoft_throw_0()
00408     {}
00409 public:
00411     allocator_type get_allocator() const
00412     {
00413         return allocator_type();
00414     }
00416 
00419 public:
00421     size_type size() const
00422     {
00423         return static_cast<size_type>(get_CList().GetSize());
00424     }
00426     size_type max_size() const
00427     {
00428         return get_allocator().max_size();
00429     }
00431     ms_bool_t empty() const
00432     {
00433         return 0 == size();
00434     }
00436 
00439 public:
00441 
00444 public:
00445     void push_back(value_type const& val)
00446     {
00447         get_CList().AddTail(val);
00448     }
00450 
00453 public:
00457     const_iterator  begin() const
00458     {
00459         return const_iterator(&get_CList(), get_CList().GetHeadPosition());
00460     }
00464     const_iterator  end() const
00465     {
00466         return const_iterator();
00467     }
00469 };
00470 
00500 template<   ss_typename_param_k A
00501         ,   ss_typename_param_k T = CList_traits<A>
00502         >
00503 class CList_iadaptor
00504         : public CList_adaptor_base<A, CList_iadaptor<A, T>, T>
00505 {
00508 private:
00509     typedef CList_adaptor_base<A, CList_iadaptor<A, T>, T>        parent_class_type;
00510 public:
00512     typedef ss_typename_type_k parent_class_type::list_type        list_type;
00514     typedef ss_typename_type_k parent_class_type::value_type        value_type;
00516     typedef ss_typename_type_k parent_class_type::allocator_type    allocator_type;
00518     typedef ss_typename_type_k parent_class_type::reference         reference;
00520     typedef ss_typename_type_k parent_class_type::const_reference   const_reference;
00522     typedef ss_typename_type_k parent_class_type::pointer           pointer;
00524     typedef ss_typename_type_k parent_class_type::const_pointer     const_pointer;
00525 #if 0
00527     typedef ss_typename_type_k parent_class_type::const_iterator    const_iterator;
00528 #endif 
00530     typedef ss_typename_type_k parent_class_type::size_type         size_type;
00532     typedef ss_typename_type_k parent_class_type::difference_type   difference_type;
00534     typedef CList_iadaptor<A, T>                                   class_type;
00536 
00539 private:
00540     friend class CList_adaptor_base<A, CList_iadaptor<A, T>, T>;
00541 
00542     list_type          &get_actual_list()
00543     {
00544         MFCSTL_ASSERT(NULL != m_pList);
00545         return *m_pList;
00546     }
00547     list_type const    &get_actual_list() const
00548     {
00549         MFCSTL_ASSERT(NULL != m_pList);
00550         return *m_pList;
00551     }
00553 
00556 public:
00557     template <ss_typename_param_k A2>
00558     CList_iadaptor(A2 &list)
00559          : m_pList(&list)
00560     {
00561         STLSOFT_STATIC_ASSERT(sizeof(list_type) == sizeof(A2));
00562 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00563         STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<list_type, A2>::value));
00564 #else 
00565         ASSERT(0 == ::lstrcmpA(list.GetRuntimeClass()->m_lpszClassName, list_type().GetRuntimeClass()->m_lpszClassName));
00566 # ifdef _CPPRTTI
00567         ASSERT(0 == ::lstrcmpA(typeid(A2).name(), typeid(list_type).name()));
00568 # endif 
00569 #endif 
00570     }
00571     template <ss_typename_param_k A2>
00572     CList_iadaptor(A2 *pList)
00573          : m_pList(pList)
00574     {
00575         MFCSTL_MESSAGE_ASSERT("Cannot initialise a CList_iadaptor with a NULL pointer", NULL != pList);
00576 
00577         STLSOFT_STATIC_ASSERT(sizeof(list_type) == sizeof(A2));
00578 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00579         STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<list_type, A2>::value));
00580 #else 
00581         ASSERT(0 == ::lstrcmpA(pList->GetRuntimeClass()->m_lpszClassName, list_type().GetRuntimeClass()->m_lpszClassName));
00582 # ifdef _CPPRTTI
00583         ASSERT(0 == ::lstrcmpA(typeid(A2).name(), typeid(list_type).name()));
00584 # endif 
00585 #endif 
00586     }
00588 
00591 private:
00592     list_type  *m_pList;
00594 
00597 private:
00598     CList_iadaptor(class_type const& rhs);            
00599     class_type& operator =(class_type const& rhs);  
00601 };
00602 
00604 
00605 
00606 #ifdef STLSOFT_UNITTEST
00607 # include "./unittest/clist_adaptors_unittest_.h"
00608 #endif 
00609 
00610 
00611 
00612 #ifndef _MFCSTL_NO_NAMESPACE
00613 # if defined(_STLSOFT_NO_NAMESPACE) || \
00614      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00615 } 
00616 # else
00617 } 
00618 } 
00619 # endif 
00620 #endif 
00621 
00622 
00623 
00624 #endif 
00625 
00626