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

Go to the documentation of this file.
00001 /* 
00002  * File:        mfcstl_array_veneer.h
00003  *
00004  * Purpose:     Contains the definition of the array_veneer template.
00005  *
00006  * Created:     28th January 2003
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2003-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef MFCSTL_INCL_H_MFCSTL_ARRAY_VENEER
00046 #define MFCSTL_INCL_H_MFCSTL_ARRAY_VENEER
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define MFCSTL_VER_H_MFCSTL_ARRAY_VENEER_MAJOR     2
00050 # define MFCSTL_VER_H_MFCSTL_ARRAY_VENEER_MINOR     0
00051 # define MFCSTL_VER_H_MFCSTL_ARRAY_VENEER_REVISION  1
00052 # define MFCSTL_VER_H_MFCSTL_ARRAY_VENEER_EDIT      27
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef MFCSTL_INCL_H_MFCSTL
00060 # include "mfcstl.h"    // Include the MFCSTL root header
00061 #endif /* !MFCSTL_INCL_H_MFCSTL */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00063 # include "stlsoft_iterator.h"
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_ITERATOR */
00065 #ifndef STLSOFT_INCL_H_STLSOFT_CONSTRAINTS
00066 # include "stlsoft_constraints.h"
00067 #endif /* !STLSOFT_INCL_H_STLSOFT_CONSTRAINTS */
00068 
00069 /* 
00070  * Namespace
00071  *
00072  * The MFCSTL components are contained within the mfcstl namespace. This is
00073  * actually an alias for stlsoft::mfcstl_project,
00074  *
00075  * The definition matrix is as follows:
00076  *
00077  * _STLSOFT_NO_NAMESPACE    _MFCSTL_NO_NAMESPACE    mfcstl definition
00078  * ---------------------    --------------------    -----------------
00079  *  not defined              not defined             = stlsoft::mfcstl_project
00080  *  not defined              defined                 not defined
00081  *  defined                  not defined             mfcstl
00082  *  defined                  defined                 not defined
00083  *
00084  */
00085 
00086 #ifndef _MFCSTL_NO_NAMESPACE
00087 # if defined(_STLSOFT_NO_NAMESPACE) || \
00088      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00089 /* There is no stlsoft namespace, so must define ::mfcstl */
00090 namespace mfcstl
00091 {
00092 # else
00093 /* Define stlsoft::mfcstl_project */
00094 
00095 namespace stlsoft
00096 {
00097 
00098 namespace mfcstl_project
00099 {
00100 
00101 # endif /* _STLSOFT_NO_NAMESPACE */
00102 #endif /* !_MFCSTL_NO_NAMESPACE */
00103 
00104 /* 
00105 
00108 
00112 
00117 
00118 /* 
00119  * Classes
00120  */
00121 
00122 // struct array_veneer_traits
00123 //
00124 // Regrettably, since MFC's template classes do not define any member types,
00125 // it is not possible to generalise the traits, so we must just use
00126 // specialisations. Sigh!
00127 
00128 template <class C>
00129 struct array_veneer_traits;
00130 
00131 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00132 // For CByteArray
00133 
00134 STLSOFT_TEMPLATE_SPECIALISATION
00135 struct array_veneer_traits<CByteArray>
00136 {
00137     typedef BYTE            value_type;
00138     typedef BYTE            arg_type;
00139 };
00140 
00141 // For CDWordArray
00142 
00143 STLSOFT_TEMPLATE_SPECIALISATION
00144 struct array_veneer_traits<CDWordArray>
00145 {
00146     typedef DWORD           value_type;
00147     typedef DWORD           arg_type;
00148 };
00149 
00150 // For CObArray
00151 
00152 STLSOFT_TEMPLATE_SPECIALISATION
00153 struct array_veneer_traits<CObArray>
00154 {
00155     typedef CObject         *value_type;
00156     typedef CObject         *arg_type;
00157 };
00158 
00159 // For CPtrArray
00160 
00161 STLSOFT_TEMPLATE_SPECIALISATION
00162 struct array_veneer_traits<CPtrArray>
00163 {
00164     typedef void            *value_type;
00165     typedef void            *arg_type;
00166 };
00167 
00168 // For CStringArray
00169 
00170 STLSOFT_TEMPLATE_SPECIALISATION
00171 struct array_veneer_traits<CStringArray>
00172 {
00173     typedef CString         value_type;
00174     typedef const CString   &arg_type;
00175 };
00176 
00177 // For CUIntArray
00178 
00179 STLSOFT_TEMPLATE_SPECIALISATION
00180 struct array_veneer_traits<CUIntArray>
00181 {
00182     typedef UINT            value_type;
00183     typedef UINT            arg_type;
00184 };
00185 
00186 // For CWordArray
00187 
00188 STLSOFT_TEMPLATE_SPECIALISATION
00189 struct array_veneer_traits<CWordArray>
00190 {
00191     typedef WORD            value_type;
00192     typedef WORD            arg_type;
00193 };
00194 
00195 
00196 // For CArray<, >
00197 
00198 #ifdef __AFXTEMPL_H__
00199 # ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00200 /* If your translator supports partial template specialisation, then
00201  * you should be fine with the following specialisation ...
00202  */
00203 
00204 template <class V, class A>
00205 struct array_veneer_traits<CArray<V, A> >
00206 {
00207     typedef V               value_type;
00208     typedef A               arg_type;
00209 };
00210 
00211 # else
00212 
00213 /* ... otherwise you will need to provide your own traits class, e.g
00214  *
00215  *  struct my_traits_type
00216  *  {
00217  *    typedef MyValType       value_type;
00218  *    typedef MyValType const &arg_type;
00219  *  };
00220  */
00221 
00222 # endif // __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00223 #endif // __AFXTEMPL_H__
00224 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00225 
00243 
00244 template<   class C                             // The container type
00245         ,   class T = array_veneer_traits<C>    // The traits type
00246         >
00247 class array_veneer
00248     : public C
00249 {
00250 public:
00252     typedef array_veneer<C, T>                          class_type;
00254     typedef C                                           container_type;
00255 private:
00256     typedef T                                           traits_type;
00257     typedef class_type                                  adapted_container_type;
00258 public:
00259     // If you get a warning about a array_veneer_traits<CArray<,> > parameterisation not
00260     // having a value_type on the next line, you need to include afxtempl.h _before_
00261     // this header file
00262     typedef ss_typename_type_k traits_type::value_type  value_type;
00264     typedef ms_size_t                                   size_type;
00266     typedef ms_ptrdiff_t                                difference_type;
00267 
00268 public:
00272     class const_iterator
00273         : public stlsoft_ns_qual(iterator_base)<mfcstl_ns_qual_std(random_access_iterator_tag), value_type, ms_ptrdiff_t, void, value_type>
00274     {
00275     protected:
00276         friend class array_veneer<C, T>;
00277 
00278         typedef const_iterator                                      class_type;
00279         // NOTE: If you get a compiler error on the next line, referring to
00280         // undefined 'value_type' then you need to provide a traits type
00281         // with the member type 'value_type' defined.
00282     public:
00283         typedef int                                                 index_type;
00284 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00285         typedef ss_typename_type_k array_veneer<C, T>::value_type   value_type;
00286 #else
00287 #endif /* !__STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
00288 
00289     // Construction
00290     protected:
00291         const_iterator(container_type const *const c, index_type index)
00292             : m_c(c)
00293             , m_index(index)
00294         {}
00295     public:
00297         const_iterator()
00298             : m_c(0)
00299             , m_index(0)
00300         {}
00304         const_iterator(class_type const &rhs)
00305             : m_c(rhs.m_c)
00306             , m_index(rhs.m_index)
00307         {}
00308 
00312         const_iterator const &operator =(class_type const &rhs)
00313         {
00314             mfcstl_message_assert("Attempting to assign iterator from another container!", m_c == NULL || rhs.m_c == NULL || m_c == rhs.m_c);
00315 
00316             m_c     =   rhs.m_c;
00317             m_index =   rhs.m_index;
00318 
00319             return *this;
00320         }
00321 
00322     // Operators
00323     public:
00324         ss_typename_type_k traits_type::value_type operator *() const
00325         {
00326             mfcstl_message_assert("", m_c != 0);
00327 
00328             return m_c->GetAt(m_index);
00329         }
00330 
00332         class_type &operator ++()
00333         {
00334             ++m_index;
00335 
00336             return *this;
00337         }
00338 
00340         class_type operator ++(int)
00341         {
00342             class_type  ret(*this);
00343 
00344             operator ++();
00345 
00346             return ret;
00347         }
00348 
00355         difference_type compare(class_type const &rhs) const
00356         {
00357             // Because the C<Type><Container> containers, e.g. CStringArray
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_index - rhs.m_index;
00367         }
00368 
00374         ms_bool_t operator ==(class_type const &rhs) const
00375         {
00376             return compare(rhs) == 0;
00377         }
00378 
00384         ms_bool_t operator !=(class_type const &rhs) const
00385         {
00386             return compare(rhs) != 0;
00387         }
00388 
00389         // Bidirectional iterator operations
00390 
00392         class_type &operator --()
00393         {
00394             --m_index;
00395 
00396             return *this;
00397         }
00398 
00400         class_type operator --(int)
00401         {
00402             class_type  ret(*this);
00403 
00404             operator --();
00405 
00406             return ret;
00407         }
00408 
00409         // Random access operations
00410 
00411         class_type &operator +=(difference_type index)
00412         {
00413             m_index += index;
00414 
00415             return *this;
00416         }
00417 
00418         class_type &operator -=(difference_type index)
00419         {
00420             m_index -= index;
00421 
00422             return *this;
00423         }
00424 
00425         value_type operator [](difference_type index) const
00426         {
00427             return m_c->GetAt(m_index + index);
00428         }
00429 
00430         difference_type distance(class_type const &rhs) const
00431         {
00432             return m_index - rhs.m_index;
00433         }
00434 
00435         class_type operator -(difference_type n)
00436         {
00437             return class_type(*this) -= n;
00438         }
00439 
00440         class_type operator +(difference_type n)
00441         {
00442             return class_type(*this) += n;
00443         }
00444 
00445         difference_type operator -(class_type const &rhs)
00446         {
00447             return distance(rhs);
00448         }
00449 
00450         ms_bool_t operator <(class_type const &rhs)
00451         {
00452             return compare(rhs) < 0;
00453         }
00454 
00455         ms_bool_t operator >(class_type const &rhs)
00456         {
00457             return compare(rhs) > 0;
00458         }
00459 
00460         ms_bool_t operator <=(class_type const &rhs)
00461         {
00462             return compare(rhs) <= 0;
00463         }
00464 
00465         ms_bool_t operator >=(class_type const &rhs)
00466         {
00467             return compare(rhs) >= 0;
00468         }
00469 
00470 
00471     // Members
00472     protected:
00473         container_type const    *m_c;
00474         size_type               m_index;
00475     };
00476 
00478     class iterator
00479         : public const_iterator
00480     {
00481         friend class array_veneer<C, T>;
00482 
00483     private:
00484         typedef const_iterator                                      parent_class_type;
00485         typedef iterator                                            class_type;
00486         typedef ss_typename_type_k parent_class_type::index_type    index_type;
00487 
00488     private:
00489         iterator(container_type *const c, index_type index)
00490             : parent_class_type(c, index)
00491         {}
00492     public:
00494         iterator()
00495         {}
00499         iterator(class_type const &rhs)
00500             : parent_class_type(rhs)
00501         {}
00502 
00506         iterator const &operator =(class_type const &rhs)
00507         {
00508             mfcstl_message_assert("Attempting to assign iterator from another container!", m_c == NULL || rhs.m_c == NULL || m_c == rhs.m_c);
00509 
00510             parent_class_type::operator =(rhs);
00511 
00512             return *this;
00513         }
00514 
00515         // Random access operations
00516 
00517         value_type &operator [](difference_type index)
00518         {
00519             return const_cast<container_type *>(m_c)->ElementAt(m_index + index);
00520         }
00521 
00522         value_type operator [](difference_type index) const
00523         {
00524             return parent_class_type::operator [](index);
00525         }
00526     };
00527 
00529 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00530     typedef stlsoft_ns_qual(const_reverse_bidirectional_iterator_base)< const_iterator,
00531                                                                         value_type,
00532                                                                         value_type, // Return by value!
00533                                                                         void*,
00534                                                                         difference_type>    const_reverse_iterator;
00535 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00536 
00537 
00538 // Construction
00539 public:
00541     ss_explicit_k array_veneer()
00542     {
00543         stlsoft_constraint_must_be_same_size(C, class_type);
00544     }
00545 
00546 // Operations
00547 public:
00548     void push_back(value_type const &v)
00549     {
00550         Add(v);
00551     }
00552 
00553 // State
00554 public:
00556     size_type size() const
00557     {
00558         return static_cast<size_type>(GetSize());
00559     }
00561     ms_bool_t empty() const
00562     {
00563         return GetSize() == 0;
00564     }
00566     static size_type max_size()
00567     {
00568         return static_cast<size_type>(-1) / sizeof(value_type);
00569     }
00570 
00571 // Iteration
00572 public:
00576     const_iterator begin() const
00577     {
00578         return const_iterator(this, 0);
00579     }
00583     const_iterator end() const
00584     {
00585         return const_iterator(this, size());
00586     }
00587 
00591     iterator begin()
00592     {
00593         return iterator(this, 0);
00594     }
00598     iterator end()
00599     {
00600         return iterator(this, size());
00601     }
00602 
00603 //  const_reverse_iterator
00604 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00608     const_reverse_iterator  rbegin() const
00609     {
00610         return const_reverse_iterator(end());
00611     }
00615     const_reverse_iterator  rend() const
00616     {
00617         return const_reverse_iterator(begin());
00618     }
00619 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00620 
00621 // Accessors
00622 public:
00624     value_type &operator [](difference_type index)
00625     {
00626         return container_type::operator [](index);
00627     }
00628 
00630     value_type operator [](difference_type index) const
00631     {
00632         return GetAt(index);
00633     }
00634 };
00635 
00636 /* 
00637 
00639 
00640 /* 
00641 
00642 #ifndef _MFCSTL_NO_NAMESPACE
00643 # if defined(_STLSOFT_NO_NAMESPACE) || \
00644      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00645 } // namespace mfcstl
00646 # else
00647 } // namespace mfcstl_project
00648 } // namespace stlsoft
00649 # endif /* _STLSOFT_NO_NAMESPACE */
00650 #endif /* !_MFCSTL_NO_NAMESPACE */
00651 
00652 /* 
00653 
00654 #endif /* !MFCSTL_INCL_H_MFCSTL_ARRAY_VENEER */
00655 
00656 /* 

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