STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

mfcstl_list_adaptor.h

Go to the documentation of this file.
00001 /* 
00002  * File:        mfcstl_list_adaptor.h
00003  *
00004  * Purpose:     Contains the definition of the list_adaptor template, and the
00005  *              specialisations.
00006  *
00007  * Created:     1st December 2002
00008  * Updated:     11th September 2004
00009  *
00010  * Home:        http://stlsoft.org/
00011  *
00012  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00013  * All rights reserved.
00014  *
00015  * Redistribution and use in source and binary forms, with or without
00016  * modification, are permitted provided that the following conditions are met:
00017  *
00018  * - Redistributions of source code must retain the above copyright notice, this
00019  *   list of conditions and the following disclaimer.
00020  * - Redistributions in binary form must reproduce the above copyright notice,
00021  *   this list of conditions and the following disclaimer in the documentation
00022  *   and/or other materials provided with the distribution.
00023  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00024  *   any contributors may be used to endorse or promote products derived from
00025  *   this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  *
00039  * 
00040 
00041 
00045 
00046 #ifndef MFCSTL_INCL_H_MFCSTL_LIST_ADAPTOR
00047 #define MFCSTL_INCL_H_MFCSTL_LIST_ADAPTOR
00048 
00049 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00050 # define MFCSTL_VER_H_MFCSTL_LIST_ADAPTOR_MAJOR     2
00051 # define MFCSTL_VER_H_MFCSTL_LIST_ADAPTOR_MINOR     0
00052 # define MFCSTL_VER_H_MFCSTL_LIST_ADAPTOR_REVISION  1
00053 # define MFCSTL_VER_H_MFCSTL_LIST_ADAPTOR_EDIT      29
00054 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00055 
00056 /* 
00057  * Includes
00058  */
00059 
00060 #ifndef MFCSTL_INCL_H_MFCSTL
00061 # include "mfcstl.h"    // Include the MFCSTL root header
00062 #endif /* !MFCSTL_INCL_H_MFCSTL */
00063 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00064 # include "stlsoft_iterator.h"
00065 #endif /* !STLSOFT_INCL_H_STLSOFT_ITERATOR */
00066 
00067 /* 
00068  * Namespace
00069  *
00070  * The MFCSTL components are contained within the mfcstl namespace. This is
00071  * actually an alias for stlsoft::mfcstl_project,
00072  *
00073  * The definition matrix is as follows:
00074  *
00075  * _STLSOFT_NO_NAMESPACE    _MFCSTL_NO_NAMESPACE    mfcstl definition
00076  * ---------------------    --------------------    -----------------
00077  *  not defined              not defined             = stlsoft::mfcstl_project
00078  *  not defined              defined                 not defined
00079  *  defined                  not defined             mfcstl
00080  *  defined                  defined                 not defined
00081  *
00082  */
00083 
00084 #ifndef _MFCSTL_NO_NAMESPACE
00085 # if defined(_STLSOFT_NO_NAMESPACE) || \
00086      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00087 /* There is no stlsoft namespace, so must define ::mfcstl */
00088 namespace mfcstl
00089 {
00090 # else
00091 /* Define stlsoft::mfcstl_project */
00092 
00093 namespace stlsoft
00094 {
00095 
00096 namespace mfcstl_project
00097 {
00098 
00099 # endif /* _STLSOFT_NO_NAMESPACE */
00100 #endif /* !_MFCSTL_NO_NAMESPACE */
00101 
00102 /* 
00103 
00106 
00110 
00115 
00116 /* 
00117  * Pre-processor options
00118  *
00119  * Because the CObList, CPtrList, CStringList and CList<,> implementations all
00120  * internally represent their logical position indicators (of type POSTION) as
00121  * pointers to the nodes within the lists, it is workable to be able to copy
00122  * these position variables.
00123  *
00124  * However, nothing in the MFC documentation stipulates this to be a reliable
00125  * and documented part of the classes' interfaces, so this is a potentially
00126  * unsafe assumption.
00127  *
00128  * Therefore, the iterator model for the list_adaptor class is Input Iterator.
00129  * If you wish to use forward iterators, you may specify the pre-processor
00130  * symbol _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR, in which case the iterator
00131  * classes will implement copy semantics, rather than the default move
00132  * semantics.
00133  */
00134 
00135 /* 
00136  * Classes
00137  */
00138 
00139 // struct list_adaptor_traits
00140 //
00141 // Regrettably, since MFC's template classes do not define any member types,
00142 // it is not possible to generalise the traits, so we must just use
00143 // specialisations. Sigh!
00144 
00145 template <class C>
00146 struct list_adaptor_traits;
00147 
00148 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00149 // For CObList
00150 
00151 STLSOFT_TEMPLATE_SPECIALISATION
00152 struct list_adaptor_traits<CObList>
00153 {
00154     typedef CObject         *value_type;
00155     typedef CObject         *arg_type;
00156 };
00157 
00158 // For CPtrList
00159 
00160 STLSOFT_TEMPLATE_SPECIALISATION
00161 struct list_adaptor_traits<CPtrList>
00162 {
00163     typedef void            *value_type;
00164     typedef void            *arg_type;
00165 };
00166 
00167 // For CStringList
00168 
00169 STLSOFT_TEMPLATE_SPECIALISATION
00170 struct list_adaptor_traits<CStringList>
00171 {
00172     typedef CString         value_type;
00173     typedef const CString   &arg_type;
00174 };
00175 
00176 // For CList<, >
00177 
00178 #ifdef __AFXTEMPL_H__
00179 # ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00180 /* If your translator supports partial template specialisation, then
00181  * you should be fine with the following specialisation ...
00182  */
00183 
00184 template <class V, class A>
00185 struct list_adaptor_traits<CList<V, A> >
00186 {
00187     typedef V               value_type;
00188     typedef A               arg_type;
00189 };
00190 
00191 # else
00192 
00193 /* ... otherwise you will need to provide your own traits class, e.g
00194  *
00195  *  struct my_traits_type
00196  *  {
00197  *    typedef MyValType       value_type;
00198  *    typedef MyValType const &arg_type;
00199  *  };
00200  */
00201 
00202 # endif // __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00203 #endif // __AFXTEMPL_H__
00204 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00205 
00223 
00224 template<   class C                             // The container type
00225         ,   class T = list_adaptor_traits<C>    // The traits type
00226         >
00227 class list_adaptor
00228 {
00229 public:
00230     typedef list_adaptor<C, T>                          class_type;
00231     typedef class_type                                  adapted_container_type;
00232 private:
00233     typedef C                                           container_type;
00234     typedef T                                           traits_type;
00235 public:
00236     // If you get a warning about a list_adaptor_traits<CList<,> > parameterisation not
00237     // having a value_type on the next line, you need to include afxtempl.h _before_
00238     // this header file
00239     typedef ss_typename_type_k traits_type::value_type  value_type;
00240     typedef ms_size_t                                   size_type;
00241 
00242 public:
00246     class const_iterator
00247         : public stlsoft_ns_qual(iterator_base)<mfcstl_ns_qual_std(input_iterator_tag), value_type, ms_ptrdiff_t, void, value_type>
00248     {
00249         friend class list_adaptor<C, T>;
00250 
00251         typedef const_iterator                                      class_type;
00252         // NOTE: If you get a compiler error on the next line, referring to
00253         // undefined 'value_type' then you need to provide a traits type
00254         // with the member type 'value_type' defined.
00255 # ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00256         typedef ss_typename_type_k list_adaptor<C, T>::value_type   value_type;
00257 # else
00258 # endif /* !__STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
00259 # ifndef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00260         typedef stlsoft_define_move_rhs_type(class_type)            rhs_type;
00261 # endif /* !_MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
00262 
00263     // Construction
00264     private:
00266         const_iterator(container_type *c, POSITION pos)
00267             : m_c(c)
00268             , m_pos(pos)
00269         {
00270             operator ++();
00271         }
00272     public:
00274         const_iterator()
00275             : m_c(0)
00276             , m_pos(NULL)
00277         {}
00278 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00279         // The copy constructor and copy assignment operator are not defined,
00280         // which allows the class to support copy-semantics. See the
00281         // description of _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR given for
00282         // a discussion of the ramifications of this choice.
00283 
00284 # else
00285 
00286         const_iterator(rhs_type rhs)
00287             : m_c(rhs.m_c)
00288             , m_pos(rhs.m_pos)
00289         {
00290             move_lhs_from_rhs(rhs).m_pos = NULL;
00291         }
00292 
00294         const_iterator const &operator =(rhs_type rhs)
00295         {
00296             m_c     =   rhs.m_c;
00297             m_pos   =   rhs.m_pos;
00298 
00299             move_lhs_from_rhs(rhs).m_pos = NULL;
00300 
00301             return *this;
00302         }
00303 # endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
00304 
00305     // Operators
00306     public:
00308         value_type operator *() const
00309         {
00310             mfcstl_message_assert("", m_c != 0);
00311 
00312             return m_value;
00313         }
00314 
00316         const_iterator &operator ++()
00317         {
00318             if(m_pos == NULL)
00319             {
00320                 mfcstl_message_assert("operator ++() called on invalid iterator", m_c != 0);
00321 
00322                 m_c = 0;
00323             }
00324             else
00325             {
00326                 m_value = m_c->GetNext(m_pos);
00327             }
00328 
00329             return *this;
00330         }
00331 
00333 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00334         const_iterator operator ++(int)
00335 # else
00336         void operator ++(int)
00337 # endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
00338         {
00339 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00340             class_type  ret(*this);
00341 # endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
00342 
00343             operator ++();
00344 
00345 # ifdef _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR
00346             return ret;
00347 # endif /* _MFCSTL_LIST_ADAPTOR_ENABLE_FWD_ITERATOR */
00348         }
00349 
00355         ms_bool_t operator ==(const_iterator const &rhs) const
00356         {
00357             // Because the C<Type><Container> containers, e.g. CStringList
00358             // work on the basis of get-and-advance, m_pos alone cannot be
00359             // the sentinel for an ended sequence. Hence, combining the
00360             // implementation of op++ to set m_c to 0 when m_pos is NULL, we
00361             // can test both members, which results in the after-the-fact
00362             // equality evaluating correctly.
00363 
00364             mfcstl_message_assert("invalid comparison between iterators from different ranges", m_c == 0 || rhs.m_c == 0 || m_c == rhs.m_c);
00365 
00366             return m_pos == rhs.m_pos && m_c == rhs.m_c;
00367         }
00373         ms_bool_t operator !=(const_iterator const &rhs) const
00374         {
00375             return !operator ==(rhs);
00376         }
00377 
00378     // Members
00379     private:
00380         container_type  *m_c;
00381         POSITION        m_pos;
00382         value_type      m_value;
00383     };
00384 
00385 // Construction
00386 public:
00390     ss_explicit_k list_adaptor(C &c)
00391         : m_c(c)
00392     {}
00393 
00394 // State
00395 public:
00397     size_type size() const
00398     {
00399         return static_cast<size_type>(m_c.GetCount());
00400     }
00402     ms_bool_t empty() const
00403     {
00404         return m_c.GetCount() == 0;
00405     }
00407     static size_type max_size()
00408     {
00409         return static_cast<size_type>(-1) / sizeof(value_type);
00410     }
00411 
00412 // Iteration
00413 public:
00417     const_iterator  begin() const
00418     {
00419         return const_iterator(&m_c, m_c.GetHeadPosition());
00420     }
00424     const_iterator  end() const
00425     {
00426         return const_iterator();
00427     }
00428 
00429 // Members
00430 private:
00431     container_type  &m_c;
00432 };
00433 
00434 /* 
00435 
00437 
00438 /* 
00439 
00440 #ifndef _MFCSTL_NO_NAMESPACE
00441 # if defined(_STLSOFT_NO_NAMESPACE) || \
00442      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00443 } // namespace mfcstl
00444 # else
00445 } // namespace mfcstl_project
00446 } // namespace stlsoft
00447 # endif /* _STLSOFT_NO_NAMESPACE */
00448 #endif /* !_MFCSTL_NO_NAMESPACE */
00449 
00450 /* 
00451 
00452 #endif /* !MFCSTL_INCL_H_MFCSTL_LIST_ADAPTOR */
00453 
00454 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004