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_array_adaptor.h

Go to the documentation of this file.
00001 /* 
00002  * File:        mfcstl_array_adaptor.h
00003  *
00004  * Purpose:     Contains the definition of the array_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_ARRAY_ADAPTOR
00047 #define MFCSTL_INCL_H_MFCSTL_ARRAY_ADAPTOR
00048 
00049 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00050 # define MFCSTL_VER_H_MFCSTL_ARRAY_ADAPTOR_MAJOR        2
00051 # define MFCSTL_VER_H_MFCSTL_ARRAY_ADAPTOR_MINOR        0
00052 # define MFCSTL_VER_H_MFCSTL_ARRAY_ADAPTOR_REVISION     1
00053 # define MFCSTL_VER_H_MFCSTL_ARRAY_ADAPTOR_EDIT         30
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  * Classes
00118  */
00119 
00120 // struct array_adaptor_traits
00121 //
00122 // Regrettably, since MFC's template classes do not define any member types,
00123 // it is not possible to generalise the traits, so we must just use
00124 // specialisations. Sigh!
00125 
00126 template <class C>
00127 struct array_adaptor_traits;
00128 
00129 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00130 // For CByteArray
00131 
00132 STLSOFT_TEMPLATE_SPECIALISATION
00133 struct array_adaptor_traits<CByteArray>
00134 {
00135     typedef BYTE            value_type;
00136     typedef BYTE            arg_type;
00137 };
00138 
00139 // For CDWordArray
00140 
00141 STLSOFT_TEMPLATE_SPECIALISATION
00142 struct array_adaptor_traits<CDWordArray>
00143 {
00144     typedef DWORD           value_type;
00145     typedef DWORD           arg_type;
00146 };
00147 
00148 // For CObArray
00149 
00150 STLSOFT_TEMPLATE_SPECIALISATION
00151 struct array_adaptor_traits<CObArray>
00152 {
00153     typedef CObject         *value_type;
00154     typedef CObject         *arg_type;
00155 };
00156 
00157 // For CPtrArray
00158 
00159 STLSOFT_TEMPLATE_SPECIALISATION
00160 struct array_adaptor_traits<CPtrArray>
00161 {
00162     typedef void            *value_type;
00163     typedef void            *arg_type;
00164 };
00165 
00166 // For CStringArray
00167 
00168 STLSOFT_TEMPLATE_SPECIALISATION
00169 struct array_adaptor_traits<CStringArray>
00170 {
00171     typedef CString         value_type;
00172     typedef const CString   &arg_type;
00173 };
00174 
00175 // For CUIntArray
00176 
00177 STLSOFT_TEMPLATE_SPECIALISATION
00178 struct array_adaptor_traits<CUIntArray>
00179 {
00180     typedef UINT            value_type;
00181     typedef UINT            arg_type;
00182 };
00183 
00184 // For CWordArray
00185 
00186 STLSOFT_TEMPLATE_SPECIALISATION
00187 struct array_adaptor_traits<CWordArray>
00188 {
00189     typedef WORD            value_type;
00190     typedef WORD            arg_type;
00191 };
00192 
00193 
00194 // For CArray<, >
00195 
00196 #ifdef __AFXTEMPL_H__
00197 # ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00198 /* If your translator supports partial template specialisation, then
00199  * you should be fine with the following specialisation ...
00200  */
00201 
00202 template <class V, class A>
00203 struct array_adaptor_traits<CArray<V, A> >
00204 {
00205     typedef V               value_type;
00206     typedef A               arg_type;
00207 };
00208 
00209 # else
00210 
00211 /* ... otherwise you will need to provide your own traits class, e.g
00212  *
00213  *  struct my_traits_type
00214  *  {
00215  *    typedef MyValType       value_type;
00216  *    typedef MyValType const &arg_type;
00217  *  };
00218  */
00219 
00220 # endif // __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00221 #endif // __AFXTEMPL_H__
00222 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00223 
00241 
00242 template<   class C                             // The container type
00243         ,   class T = array_adaptor_traits<C>   // The traits type
00244         >
00245 class array_adaptor
00246 {
00247 public:
00249     typedef array_adaptor<C, T>                         class_type;
00251     typedef C                                           container_type;
00252 private:
00253     typedef T                                           traits_type;
00254     typedef class_type                                  adapted_container_type;
00255 public:
00256     // If you get a warning about a array_adaptor_traits<CArray<,> > parameterisation not
00257     // having a value_type on the next line, you need to include afxtempl.h _before_
00258     // this header file
00259     typedef ss_typename_type_k traits_type::value_type  value_type;
00261     typedef ms_size_t                                   size_type;
00263     typedef ms_ptrdiff_t                                difference_type;
00264 
00265 public:
00269     class const_iterator
00270         : public stlsoft_ns_qual(iterator_base)<mfcstl_ns_qual_std(random_access_iterator_tag), value_type, ms_ptrdiff_t, void, value_type>
00271     {
00272         friend class array_adaptor<C, T>;
00273 
00274         typedef const_iterator                                      class_type;
00275         // NOTE: If you get a compiler error on the next line, referring to
00276         // undefined 'value_type' then you need to provide a traits type
00277         // with the member type 'value_type' defined.
00278         typedef int                                                 index_type;
00279 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00280         typedef ss_typename_type_k array_adaptor<C, T>::value_type  value_type;
00281 #else
00282 #endif /* !__STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
00283 
00284     // Construction
00285     private:
00286         friend class adapted_container_type;
00287 
00288         const_iterator(container_type *c, index_type index)
00289             : m_c(c)
00290             , m_index(index)
00291         {}
00292     public:
00294         const_iterator()
00295             : m_c(0)
00296             , m_index(0)
00297         {}
00301         const_iterator(class_type const &rhs)
00302             : m_c(rhs.m_c)
00303             , m_index(rhs.m_index)
00304         {}
00305 
00309         const_iterator const &operator =(class_type const &rhs)
00310         {
00311             m_c     =   rhs.m_c;
00312             m_index =   rhs.m_index;
00313 
00314             return *this;
00315         }
00316 
00317     // Operators
00318     public:
00319         ss_typename_type_k traits_type::value_type operator *() const
00320         {
00321             mfcstl_message_assert("", m_c != 0);
00322 
00323             return m_c->GetAt(m_index);
00324         }
00325 
00327         class_type &operator ++()
00328         {
00329             ++m_index;
00330 
00331             return *this;
00332         }
00333 
00335         class_type operator ++(int)
00336         {
00337             class_type  ret(*this);
00338 
00339             operator ++();
00340 
00341             return ret;
00342         }
00343 
00350         difference_type compare(class_type const &rhs) const
00351         {
00352             // Because the C<Type><Container> containers, e.g. CStringArray
00353             // work on the basis of get-and-advance, m_pos alone cannot be
00354             // the sentinel for an ended sequence. Hence, combining the
00355             // implementation of op++ to set m_c to 0 when m_pos is NULL, we
00356             // can test both members, which results in the after-the-fact
00357             // equality evaluating correctly.
00358 
00359             mfcstl_message_assert("invalid comparison between iterators from different ranges", m_c == 0 || rhs.m_c == 0 || m_c == rhs.m_c);
00360 
00361             return m_index - rhs.m_index;
00362         }
00363 
00369         ms_bool_t operator ==(class_type const &rhs) const
00370         {
00371             return compare(rhs) == 0;
00372         }
00373 
00379         ms_bool_t operator !=(class_type const &rhs) const
00380         {
00381             return compare(rhs) != 0;
00382         }
00383 
00384         // Bidirectional iterator operations
00385 
00387         class_type &operator --()
00388         {
00389             --m_index;
00390 
00391             return *this;
00392         }
00393 
00395         class_type operator --(int)
00396         {
00397             class_type  ret(*this);
00398 
00399             operator --();
00400 
00401             return ret;
00402         }
00403 
00404         // Random access operations
00405 
00409         class_type &operator +=(difference_type inc)
00410         {
00411             m_index += inc;
00412 
00413             return *this;
00414         }
00415 
00419         class_type &operator -=(difference_type dec)
00420         {
00421             m_index -= dec;
00422 
00423             return *this;
00424         }
00425 
00429         value_type &operator [](difference_type index)
00430         {
00431             return m_c->ElementAt(m_index + index);
00432         }
00433 
00437         value_type operator [](difference_type index) const
00438         {
00439             return m_c->GetAt(m_index + index);
00440         }
00441 
00442         difference_type distance(class_type const &rhs) const
00443         {
00444             return m_index - rhs.m_index;
00445         }
00446 
00447         class_type operator -(difference_type n)
00448         {
00449             return class_type(*this) -= n;
00450         }
00451 
00452         class_type operator +(difference_type n)
00453         {
00454             return class_type(*this) += n;
00455         }
00456 
00457         difference_type operator -(class_type const &rhs)
00458         {
00459             return distance(rhs);
00460         }
00461 
00462         ms_bool_t operator <(class_type const &rhs)
00463         {
00464             return compare(rhs) < 0;
00465         }
00466 
00467         ms_bool_t operator >(class_type const &rhs)
00468         {
00469             return compare(rhs) > 0;
00470         }
00471 
00472         ms_bool_t operator <=(class_type const &rhs)
00473         {
00474             return compare(rhs) <= 0;
00475         }
00476 
00477         ms_bool_t operator >=(class_type const &rhs)
00478         {
00479             return compare(rhs) >= 0;
00480         }
00481 
00482 
00483     // Members
00484     private:
00485         container_type  *m_c;
00486         size_type       m_index;
00487     };
00488 
00490 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00491     typedef stlsoft_ns_qual(const_reverse_bidirectional_iterator_base)< const_iterator,
00492                                                                         value_type,
00493                                                                         value_type, // Return by value!
00494                                                                         void*,
00495                                                                         difference_type>    const_reverse_iterator;
00496 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00497 
00498 
00499 // Construction
00500 public:
00504     ss_explicit_k array_adaptor(container_type &c)
00505         : m_c(c)
00506     {}
00507 
00508 // State
00509 public:
00511     size_type size() const
00512     {
00513         return static_cast<size_type>(m_c.GetSize());
00514     }
00516     ms_bool_t empty() const
00517     {
00518         return m_c.GetSize() == 0;
00519     }
00521     static size_type max_size()
00522     {
00523         return static_cast<size_type>(-1) / sizeof(value_type);
00524     }
00525 
00526 // Iteration
00527 public:
00531     const_iterator  begin() const
00532     {
00533         return const_iterator(const_cast<container_type*>(&m_c), 0);
00534     }
00538     const_iterator  end() const
00539     {
00540         return const_iterator(const_cast<container_type*>(&m_c), size());
00541     }
00542 
00543 //  const_reverse_iterator
00544 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00548     const_reverse_iterator  rbegin() const
00549     {
00550         return const_reverse_iterator(end());
00551     }
00555     const_reverse_iterator  rend() const
00556     {
00557         return const_reverse_iterator(begin());
00558     }
00559 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00560 
00561 // Accessors
00562 public:
00564     value_type &operator [](difference_type index)
00565     {
00566         return m_c.ElementAt(index);
00567     }
00568 
00570     value_type operator [](difference_type index) const
00571     {
00572         return m_c.GetAt(index);
00573     }
00574 
00575 // Members
00576 private:
00577     container_type const    &m_c;
00578 };
00579 
00580 /* 
00581 
00583 
00584 /* 
00585 
00586 #ifndef _MFCSTL_NO_NAMESPACE
00587 # if defined(_STLSOFT_NO_NAMESPACE) || \
00588      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00589 } // namespace mfcstl
00590 # else
00591 } // namespace mfcstl_project
00592 } // namespace stlsoft
00593 # endif /* _STLSOFT_NO_NAMESPACE */
00594 #endif /* !_MFCSTL_NO_NAMESPACE */
00595 
00596 /* 
00597 
00598 #endif /* !MFCSTL_INCL_H_MFCSTL_ARRAY_ADAPTOR */
00599 
00600 /* 

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