imgtools/imglib/boostlibrary/boost/range/mfc.hpp
changeset 2 39c28ec933dd
equal deleted inserted replaced
1:820b22e13ff1 2:39c28ec933dd
       
     1 #ifndef BOOST_RANGE_MFC_HPP
       
     2 #define BOOST_RANGE_MFC_HPP
       
     3 
       
     4 
       
     5 
       
     6 
       
     7 // Boost.Range MFC Extension
       
     8 //
       
     9 // Copyright Shunsuke Sogame 2005-2006.
       
    10 // Distributed under the Boost Software License, Version 1.0. 
       
    11 // (See accompanying file LICENSE_1_0.txt or copy at 
       
    12 // http://www.boost.org/LICENSE_1_0.txt)
       
    13 
       
    14 
       
    15 
       
    16 
       
    17 // config
       
    18 //
       
    19 
       
    20 
       
    21 #include <afx.h> // _MFC_VER
       
    22 
       
    23 
       
    24 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
    25     #if (_MFC_VER < 0x0700) // dubious
       
    26         #define BOOST_RANGE_MFC_NO_CPAIR
       
    27     #endif
       
    28 #endif
       
    29 
       
    30 
       
    31 #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
       
    32     #if (_MFC_VER < 0x0700) // dubious
       
    33         #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
       
    34     #endif
       
    35 #endif
       
    36 
       
    37 
       
    38 // A const collection of old MFC doesn't return const reference.
       
    39 //
       
    40 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
       
    41     #if (_MFC_VER < 0x0700) // dubious
       
    42         #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
       
    43     #endif
       
    44 #endif
       
    45 
       
    46 
       
    47 
       
    48 
       
    49 // forward declarations
       
    50 //
       
    51 
       
    52 
       
    53 template< class Type, class ArgType >
       
    54 class CArray;
       
    55 
       
    56 template< class Type, class ArgType >
       
    57 class CList;
       
    58 
       
    59 template< class Key, class ArgKey, class Mapped, class ArgMapped >
       
    60 class CMap;
       
    61 
       
    62 template< class BaseClass, class PtrType >
       
    63 class CTypedPtrArray;
       
    64 
       
    65 template< class BaseClass, class PtrType >
       
    66 class CTypedPtrList;
       
    67 
       
    68 template< class BaseClass, class KeyPtrType, class MappedPtrType >
       
    69 class CTypedPtrMap;
       
    70 
       
    71 
       
    72 
       
    73 
       
    74 // extended customizations
       
    75 //
       
    76 
       
    77 
       
    78 #include <cstddef> // ptrdiff_t
       
    79 #include <utility> // pair
       
    80 #include <boost/assert.hpp>
       
    81 #include <boost/mpl/if.hpp>
       
    82 #include <boost/range/atl.hpp>
       
    83 #include <boost/range/begin.hpp>
       
    84 #include <boost/range/const_iterator.hpp>
       
    85 #include <boost/range/detail/microsoft.hpp>
       
    86 #include <boost/range/end.hpp>
       
    87 #include <boost/iterator/iterator_adaptor.hpp>
       
    88 #include <boost/iterator/iterator_categories.hpp>
       
    89 #include <boost/iterator/iterator_facade.hpp>
       
    90 #include <boost/iterator/transform_iterator.hpp>
       
    91 #include <boost/type_traits/is_const.hpp>
       
    92 #include <boost/type_traits/remove_pointer.hpp>
       
    93 #include <boost/utility/addressof.hpp>
       
    94 #include <afx.h> // legacy CString
       
    95 #include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
       
    96 #include <tchar.h>
       
    97 
       
    98 
       
    99 namespace boost { namespace range_detail_microsoft {
       
   100 
       
   101 
       
   102     // mfc_ptr_array_iterator
       
   103     //
       
   104     // 'void **' is not convertible to 'void const **',
       
   105     // so we define...
       
   106     //
       
   107 
       
   108     template< class ArrayT, class PtrType >
       
   109     struct mfc_ptr_array_iterator;
       
   110 
       
   111     template< class ArrayT, class PtrType >
       
   112     struct mfc_ptr_array_iterator_super
       
   113     {
       
   114         typedef iterator_adaptor<
       
   115             mfc_ptr_array_iterator<ArrayT, PtrType>,
       
   116             std::ptrdiff_t, // Base!
       
   117             PtrType,        // Value
       
   118             random_access_traversal_tag,
       
   119             use_default,
       
   120             std::ptrdiff_t  // Difference
       
   121         > type;
       
   122     };
       
   123 
       
   124     template< class ArrayT, class PtrType >
       
   125     struct mfc_ptr_array_iterator :
       
   126         mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
       
   127     {
       
   128     private:
       
   129         typedef mfc_ptr_array_iterator self_t;
       
   130         typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
       
   131         typedef typename super_t::reference ref_t;
       
   132 
       
   133     public:
       
   134         explicit mfc_ptr_array_iterator()
       
   135         { }
       
   136 
       
   137         explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
       
   138             super_t(index), m_parr(boost::addressof(arr))
       
   139         { }
       
   140 
       
   141     template< class, class > friend struct mfc_ptr_array_iterator;
       
   142         template< class ArrayT_, class PtrType_ >
       
   143         mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
       
   144             super_t(other.base()), m_parr(other.m_parr)
       
   145         { }
       
   146 
       
   147     private:
       
   148         ArrayT *m_parr;
       
   149 
       
   150     friend class iterator_core_access;
       
   151         ref_t dereference() const
       
   152         {
       
   153             BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
       
   154             return *( m_parr->GetData() + this->base() );
       
   155         }
       
   156 
       
   157         bool equal(self_t const& other) const
       
   158         {
       
   159             BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
       
   160             return this->base() == other.base();
       
   161         }
       
   162     };
       
   163 
       
   164     struct mfc_ptr_array_functions
       
   165     {
       
   166         template< class Iterator, class X >
       
   167         Iterator begin(X& x)
       
   168         {
       
   169             return Iterator(x, 0);
       
   170         }
       
   171 
       
   172         template< class Iterator, class X >
       
   173         Iterator end(X& x)
       
   174         {
       
   175             return Iterator(x, x.GetSize());
       
   176         }
       
   177     };
       
   178 
       
   179 
       
   180     // arrays
       
   181     //
       
   182 
       
   183     template< >
       
   184     struct customization< ::CByteArray > :
       
   185         array_functions
       
   186     {
       
   187         template< class X >
       
   188         struct meta
       
   189         {
       
   190             typedef BYTE val_t;
       
   191 
       
   192             typedef val_t *mutable_iterator;
       
   193             typedef val_t const *const_iterator;
       
   194         };
       
   195     };
       
   196 
       
   197 
       
   198     template< >
       
   199     struct customization< ::CDWordArray > :
       
   200         array_functions
       
   201     {
       
   202         template< class X >
       
   203         struct meta
       
   204         {
       
   205             typedef DWORD val_t;
       
   206 
       
   207             typedef val_t *mutable_iterator;
       
   208             typedef val_t const *const_iterator;
       
   209         };
       
   210     };
       
   211 
       
   212 
       
   213     template< >
       
   214     struct customization< ::CObArray > :
       
   215         mfc_ptr_array_functions
       
   216     {
       
   217         template< class X >
       
   218         struct meta
       
   219         {
       
   220             typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
       
   221             typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
       
   222         };
       
   223     };
       
   224 
       
   225 
       
   226     template< >
       
   227     struct customization< ::CPtrArray > :
       
   228         mfc_ptr_array_functions
       
   229     {
       
   230         template< class X >
       
   231         struct meta
       
   232         {
       
   233             typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
       
   234             typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
       
   235         };
       
   236     };
       
   237 
       
   238 
       
   239     template< >
       
   240     struct customization< ::CStringArray > :
       
   241         array_functions
       
   242     {
       
   243         template< class X >
       
   244         struct meta
       
   245         {
       
   246             typedef ::CString val_t;
       
   247 
       
   248             typedef val_t *mutable_iterator;
       
   249             typedef val_t const *const_iterator;
       
   250         };
       
   251     };
       
   252 
       
   253 
       
   254     template< >
       
   255     struct customization< ::CUIntArray > :
       
   256         array_functions
       
   257     {
       
   258         template< class X >
       
   259         struct meta
       
   260         {
       
   261             typedef UINT val_t;
       
   262 
       
   263             typedef val_t *mutable_iterator;
       
   264             typedef val_t const *const_iterator;
       
   265         };
       
   266     };
       
   267 
       
   268 
       
   269     template< >
       
   270     struct customization< ::CWordArray > :
       
   271         array_functions
       
   272     {
       
   273         template< class X >
       
   274         struct meta
       
   275         {
       
   276             typedef WORD val_t;
       
   277 
       
   278             typedef val_t *mutable_iterator;
       
   279             typedef val_t const *const_iterator;
       
   280         };
       
   281     };
       
   282 
       
   283 
       
   284     // lists
       
   285     //
       
   286 
       
   287     template< >
       
   288     struct customization< ::CObList > :
       
   289         list_functions
       
   290     {
       
   291         template< class X >
       
   292         struct meta
       
   293         {
       
   294             typedef list_iterator<X, ::CObject *> mutable_iterator;
       
   295     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
       
   296             typedef list_iterator<X const, ::CObject const *> const_iterator;
       
   297     #else
       
   298             typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
       
   299     #endif
       
   300         };
       
   301     };
       
   302 
       
   303 
       
   304     template< >
       
   305     struct customization< ::CPtrList > :
       
   306         list_functions
       
   307     {
       
   308         template< class X >
       
   309         struct meta
       
   310         {
       
   311             typedef list_iterator<X, void *> mutable_iterator;
       
   312     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
       
   313             typedef list_iterator<X const, void const *> const_iterator;
       
   314     #else
       
   315             typedef list_iterator<X const, void const * const, void const * const> const_iterator;
       
   316     #endif
       
   317         };
       
   318     };
       
   319 
       
   320 
       
   321     template< >
       
   322     struct customization< ::CStringList > :
       
   323         list_functions
       
   324     {
       
   325         template< class X >
       
   326         struct meta
       
   327         {
       
   328             typedef ::CString val_t;
       
   329 
       
   330             typedef list_iterator<X, val_t> mutable_iterator;
       
   331     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
       
   332             typedef list_iterator<X const, val_t const> const_iterator;
       
   333     #else
       
   334             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
       
   335     #endif
       
   336         };
       
   337     };
       
   338 
       
   339 
       
   340     // mfc_map_iterator
       
   341     //
       
   342 
       
   343     template< class MapT, class KeyT, class MappedT >
       
   344     struct mfc_map_iterator;
       
   345 
       
   346     template< class MapT, class KeyT, class MappedT >
       
   347     struct mfc_map_iterator_super
       
   348     {
       
   349         typedef iterator_facade<
       
   350             mfc_map_iterator<MapT, KeyT, MappedT>,
       
   351             std::pair<KeyT, MappedT>,
       
   352             forward_traversal_tag,
       
   353             std::pair<KeyT, MappedT> const
       
   354         > type;
       
   355     };
       
   356 
       
   357     template< class MapT, class KeyT, class MappedT >
       
   358     struct mfc_map_iterator :
       
   359         mfc_map_iterator_super<MapT, KeyT, MappedT>::type
       
   360     {
       
   361     private:
       
   362         typedef mfc_map_iterator self_t;
       
   363         typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
       
   364         typedef typename super_t::reference ref_t;
       
   365 
       
   366     public:
       
   367         explicit mfc_map_iterator()
       
   368         { }
       
   369 
       
   370         explicit mfc_map_iterator(MapT const& map, POSITION pos) :
       
   371             m_pmap(boost::addressof(map)), m_posNext(pos)
       
   372         {
       
   373             increment();
       
   374         }
       
   375 
       
   376         explicit mfc_map_iterator(MapT const& map) :
       
   377             m_pmap(&map), m_pos(0) // end iterator
       
   378         { }
       
   379 
       
   380     template< class, class, class > friend struct mfc_map_iterator;
       
   381         template< class MapT_, class KeyT_, class MappedT_>
       
   382         mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
       
   383             m_pmap(other.m_pmap),
       
   384             m_pos(other.m_pos), m_posNext(other.m_posNext),
       
   385             m_key(other.m_key), m_mapped(other.m_mapped)
       
   386         { }
       
   387 
       
   388     private:
       
   389         MapT const *m_pmap;
       
   390         POSITION m_pos, m_posNext;
       
   391         KeyT m_key; MappedT m_mapped;
       
   392 
       
   393     friend class iterator_core_access;
       
   394         ref_t dereference() const
       
   395         {
       
   396             BOOST_ASSERT(m_pos != 0 && "out of range");
       
   397             return std::make_pair(m_key, m_mapped);
       
   398         }
       
   399 
       
   400         void increment()
       
   401         {
       
   402             BOOST_ASSERT(m_pos != 0 && "out of range");
       
   403 
       
   404             if (m_posNext == 0) {
       
   405                 m_pos = 0;
       
   406                 return;
       
   407             }
       
   408 
       
   409             m_pos = m_posNext;
       
   410             m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
       
   411         }
       
   412 
       
   413         bool equal(self_t const& other) const
       
   414         {
       
   415             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
       
   416             return m_pos == other.m_pos;
       
   417         }
       
   418     };
       
   419 
       
   420     struct mfc_map_functions
       
   421     {
       
   422         template< class Iterator, class X >
       
   423         Iterator begin(X& x)
       
   424         {
       
   425             return Iterator(x, x.GetStartPosition());
       
   426         }
       
   427 
       
   428         template< class Iterator, class X >
       
   429         Iterator end(X& x)
       
   430         {
       
   431             return Iterator(x);
       
   432         }
       
   433     };
       
   434 
       
   435 
       
   436 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   437 
       
   438 
       
   439     // mfc_cpair_map_iterator
       
   440     //
       
   441     // used by ::CMap and ::CMapStringToString
       
   442     //
       
   443 
       
   444     template< class MapT, class PairT >
       
   445     struct mfc_cpair_map_iterator;
       
   446 
       
   447     template< class MapT, class PairT >
       
   448     struct mfc_pget_map_iterator_super
       
   449     {
       
   450         typedef iterator_facade<
       
   451             mfc_cpair_map_iterator<MapT, PairT>,
       
   452             PairT,
       
   453             forward_traversal_tag
       
   454         > type;
       
   455     };
       
   456 
       
   457     template< class MapT, class PairT >
       
   458     struct mfc_cpair_map_iterator :
       
   459         mfc_pget_map_iterator_super<MapT, PairT>::type
       
   460     {
       
   461     private:
       
   462         typedef mfc_cpair_map_iterator self_t;
       
   463         typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
       
   464         typedef typename super_t::reference ref_t;
       
   465 
       
   466     public:
       
   467         explicit mfc_cpair_map_iterator()
       
   468         { }
       
   469 
       
   470         explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
       
   471             m_pmap(boost::addressof(map)), m_pp(pp)
       
   472         { }
       
   473 
       
   474     template< class, class > friend struct mfc_cpair_map_iterator;
       
   475         template< class MapT_, class PairT_>
       
   476         mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
       
   477             m_pmap(other.m_pmap), m_pp(other.m_pp)
       
   478         { }
       
   479 
       
   480     private:
       
   481         MapT  *m_pmap;
       
   482         PairT *m_pp;
       
   483 
       
   484     friend class iterator_core_access;
       
   485         ref_t dereference() const
       
   486         {
       
   487             BOOST_ASSERT(m_pp != 0 && "out of range");
       
   488             return *m_pp;
       
   489         }
       
   490 
       
   491         void increment()
       
   492         {
       
   493             BOOST_ASSERT(m_pp != 0 && "out of range");
       
   494             m_pp = m_pmap->PGetNextAssoc(m_pp);
       
   495         }
       
   496 
       
   497         bool equal(self_t const& other) const
       
   498         {
       
   499             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
       
   500             return m_pp == other.m_pp;
       
   501         }
       
   502     };
       
   503 
       
   504     struct mfc_cpair_map_functions
       
   505     {
       
   506         template< class Iterator, class X >
       
   507         Iterator begin(X& x)
       
   508         {
       
   509             // Workaround:
       
   510             // Assertion fails if empty.
       
   511             // MFC document is wrong.
       
   512     #if !defined(NDEBUG)
       
   513             if (x.GetCount() == 0) 
       
   514                 return Iterator(x, 0);
       
   515     #endif
       
   516 
       
   517             return Iterator(x, x.PGetFirstAssoc());
       
   518         }
       
   519 
       
   520         template< class Iterator, class X >
       
   521         Iterator end(X& x)
       
   522         {
       
   523             return Iterator(x, 0);
       
   524         }
       
   525     };
       
   526 
       
   527 
       
   528 #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   529 
       
   530 
       
   531     // maps
       
   532     //
       
   533 
       
   534     template< >
       
   535     struct customization< ::CMapPtrToWord > :
       
   536         mfc_map_functions
       
   537     {
       
   538         template< class X >
       
   539         struct meta
       
   540         {
       
   541             typedef void *key_t;
       
   542             typedef WORD mapped_t;
       
   543 
       
   544             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   545             typedef mutable_iterator const_iterator;
       
   546         };
       
   547     };
       
   548 
       
   549 
       
   550     template< >
       
   551     struct customization< ::CMapPtrToPtr > :
       
   552         mfc_map_functions
       
   553     {
       
   554         template< class X >
       
   555         struct meta
       
   556         {
       
   557             typedef void *key_t;
       
   558             typedef void *mapped_t;
       
   559 
       
   560             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   561             typedef mutable_iterator const_iterator;
       
   562         };
       
   563     };
       
   564 
       
   565 
       
   566     template< >
       
   567     struct customization< ::CMapStringToOb > :
       
   568         mfc_map_functions
       
   569     {
       
   570         template< class X >
       
   571         struct meta
       
   572         {
       
   573             typedef ::CString key_t;
       
   574             typedef ::CObject *mapped_t;
       
   575 
       
   576             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   577             typedef mutable_iterator const_iterator;
       
   578         };
       
   579     };
       
   580 
       
   581 
       
   582     template< >
       
   583     struct customization< ::CMapStringToPtr > :
       
   584         mfc_map_functions
       
   585     {
       
   586         template< class X >
       
   587         struct meta
       
   588         {
       
   589             typedef ::CString key_t;
       
   590             typedef void *mapped_t;
       
   591 
       
   592             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   593             typedef mutable_iterator const_iterator;
       
   594         };
       
   595     };
       
   596 
       
   597 
       
   598     template< >
       
   599     struct customization< ::CMapStringToString > :
       
   600     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   601         mfc_cpair_map_functions
       
   602     #else
       
   603         mfc_map_functions
       
   604     #endif
       
   605     {
       
   606         template< class X >
       
   607         struct meta
       
   608         {
       
   609     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   610             typedef typename X::CPair pair_t;
       
   611 
       
   612             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
       
   613             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
       
   614     #else
       
   615             typedef ::CString key_t;
       
   616             typedef ::CString mapped_t;
       
   617 
       
   618             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   619             typedef mutable_iterator const_iterator;
       
   620     #endif
       
   621         };
       
   622     };
       
   623 
       
   624 
       
   625     template< >
       
   626     struct customization< ::CMapWordToOb > :
       
   627         mfc_map_functions
       
   628     {
       
   629         template< class X >
       
   630         struct meta
       
   631         {
       
   632             typedef WORD key_t;
       
   633             typedef ::CObject *mapped_t;
       
   634 
       
   635             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   636             typedef mutable_iterator const_iterator;
       
   637         };
       
   638     };
       
   639 
       
   640 
       
   641     template< >
       
   642     struct customization< ::CMapWordToPtr > :
       
   643         mfc_map_functions
       
   644     {
       
   645         template< class X >
       
   646         struct meta
       
   647         {
       
   648             typedef WORD key_t;
       
   649             typedef void *mapped_t;
       
   650 
       
   651             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   652             typedef mutable_iterator const_iterator;
       
   653         };
       
   654     };
       
   655 
       
   656 
       
   657     // templates
       
   658     //
       
   659 
       
   660     template< class Type, class ArgType >
       
   661     struct customization< ::CArray<Type, ArgType> > :
       
   662         array_functions
       
   663     {
       
   664         template< class X >
       
   665         struct meta
       
   666         {
       
   667             typedef Type val_t;
       
   668 
       
   669             typedef val_t *mutable_iterator;
       
   670             typedef val_t const *const_iterator;
       
   671         };
       
   672     };
       
   673 
       
   674 
       
   675     template< class Type, class ArgType >
       
   676     struct customization< ::CList<Type, ArgType> > :
       
   677         list_functions
       
   678     {
       
   679         template< class X >
       
   680         struct meta
       
   681         {
       
   682             typedef Type val_t;
       
   683 
       
   684             typedef list_iterator<X, val_t> mutable_iterator;
       
   685     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
       
   686             typedef list_iterator<X const, val_t const> const_iterator;
       
   687     #else
       
   688             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
       
   689     #endif
       
   690         };
       
   691     };
       
   692 
       
   693 
       
   694     template< class Key, class ArgKey, class Mapped, class ArgMapped >
       
   695     struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
       
   696     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   697         mfc_cpair_map_functions
       
   698     #else
       
   699         mfc_map_functions
       
   700     #endif
       
   701     {
       
   702         template< class X >
       
   703         struct meta
       
   704         {
       
   705     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
       
   706             typedef typename X::CPair pair_t;
       
   707 
       
   708             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
       
   709             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
       
   710     #else
       
   711             typedef Key key_t;
       
   712             typedef Mapped mapped_t;
       
   713 
       
   714             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
       
   715             typedef mutable_iterator const_iterator;
       
   716     #endif            
       
   717         };
       
   718     };
       
   719 
       
   720 
       
   721     template< class BaseClass, class PtrType >
       
   722     struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
       
   723     {
       
   724         template< class X >
       
   725         struct fun
       
   726         {
       
   727             typedef typename remove_pointer<PtrType>::type val_t;
       
   728 
       
   729             typedef typename mpl::if_< is_const<X>,
       
   730                 val_t const,
       
   731                 val_t
       
   732             >::type val_t_;
       
   733 
       
   734             typedef val_t_ * const result_type;
       
   735 
       
   736             template< class PtrType_ >
       
   737             result_type operator()(PtrType_ p) const
       
   738             {
       
   739                 return static_cast<result_type>(p);
       
   740             }
       
   741         };
       
   742 
       
   743         template< class X >
       
   744         struct meta
       
   745         {
       
   746             typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
       
   747             typedef typename range_const_iterator<BaseClass>::type citer_t;
       
   748 
       
   749             typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
       
   750             typedef transform_iterator<fun<X const>, citer_t> const_iterator;
       
   751         };
       
   752 
       
   753         template< class Iterator, class X >
       
   754         Iterator begin(X& x)
       
   755         {
       
   756             return Iterator(boost::begin<BaseClass>(x), fun<X>());
       
   757         }
       
   758 
       
   759         template< class Iterator, class X >
       
   760         Iterator end(X& x)
       
   761         {
       
   762             return Iterator(boost::end<BaseClass>(x), fun<X>());
       
   763         }
       
   764     };
       
   765 
       
   766 
       
   767     template< class BaseClass, class PtrType >
       
   768     struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
       
   769         list_functions
       
   770     {
       
   771         template< class X >
       
   772         struct meta
       
   773         {
       
   774             typedef typename remove_pointer<PtrType>::type val_t;
       
   775 
       
   776             // not l-value
       
   777             typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
       
   778             typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
       
   779         };
       
   780     };
       
   781 
       
   782 
       
   783     template< class BaseClass, class KeyPtrType, class MappedPtrType >
       
   784     struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
       
   785         mfc_map_functions
       
   786     {
       
   787         template< class X >
       
   788         struct meta
       
   789         {
       
   790             typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
       
   791             typedef mutable_iterator const_iterator;
       
   792         };
       
   793     };
       
   794 
       
   795 
       
   796     // strings
       
   797     //
       
   798 
       
   799 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
       
   800 
       
   801     template< >
       
   802     struct customization< ::CString >
       
   803     {
       
   804         template< class X >
       
   805         struct meta
       
   806         {
       
   807             // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
       
   808             typedef TCHAR *mutable_iterator;
       
   809             typedef TCHAR const *const_iterator;
       
   810         };
       
   811 
       
   812         template< class Iterator, class X >
       
   813         typename mutable_<Iterator, X>::type begin(X& x)
       
   814         {
       
   815             return x.GetBuffer(0);
       
   816         }
       
   817 
       
   818         template< class Iterator, class X >
       
   819         Iterator begin(X const& x)
       
   820         {
       
   821             return x;
       
   822         }
       
   823 
       
   824         template< class Iterator, class X >
       
   825         Iterator end(X& x)
       
   826         {
       
   827             return begin<Iterator>(x) + x.GetLength();
       
   828         }
       
   829     };
       
   830 
       
   831 #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
       
   832 
       
   833 
       
   834 } } // namespace boost::range_detail_microsoft
       
   835 
       
   836 
       
   837 
       
   838 
       
   839 // range customizations
       
   840 //
       
   841 
       
   842 
       
   843 // arrays
       
   844 //
       
   845 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   846     boost::range_detail_microsoft::using_type_as_tag,
       
   847     BOOST_PP_NIL, CByteArray
       
   848 )
       
   849 
       
   850 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   851     boost::range_detail_microsoft::using_type_as_tag,
       
   852     BOOST_PP_NIL, CDWordArray
       
   853 )
       
   854 
       
   855 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   856     boost::range_detail_microsoft::using_type_as_tag,
       
   857     BOOST_PP_NIL, CStringArray
       
   858 )
       
   859 
       
   860 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   861     boost::range_detail_microsoft::using_type_as_tag,
       
   862     BOOST_PP_NIL, CUIntArray
       
   863 )
       
   864 
       
   865 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   866     boost::range_detail_microsoft::using_type_as_tag,
       
   867     BOOST_PP_NIL, CWordArray
       
   868 )
       
   869 
       
   870 
       
   871 // lists
       
   872 //
       
   873 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   874     boost::range_detail_microsoft::using_type_as_tag,
       
   875     BOOST_PP_NIL, CObList
       
   876 )
       
   877 
       
   878 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   879     boost::range_detail_microsoft::using_type_as_tag,
       
   880     BOOST_PP_NIL, CPtrList
       
   881 )
       
   882 
       
   883 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   884     boost::range_detail_microsoft::using_type_as_tag,
       
   885     BOOST_PP_NIL, CStringList
       
   886 )
       
   887 
       
   888 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   889     boost::range_detail_microsoft::using_type_as_tag,
       
   890     BOOST_PP_NIL, CObArray
       
   891 )
       
   892 
       
   893 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   894     boost::range_detail_microsoft::using_type_as_tag,
       
   895     BOOST_PP_NIL, CPtrArray
       
   896 )
       
   897 
       
   898 
       
   899 // maps
       
   900 //
       
   901 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   902     boost::range_detail_microsoft::using_type_as_tag,
       
   903     BOOST_PP_NIL, CMapPtrToWord
       
   904 )
       
   905 
       
   906 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   907     boost::range_detail_microsoft::using_type_as_tag,
       
   908     BOOST_PP_NIL, CMapPtrToPtr
       
   909 )
       
   910 
       
   911 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   912     boost::range_detail_microsoft::using_type_as_tag,
       
   913     BOOST_PP_NIL, CMapStringToOb
       
   914 )
       
   915 
       
   916 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   917     boost::range_detail_microsoft::using_type_as_tag,
       
   918     BOOST_PP_NIL, CMapStringToPtr
       
   919 )
       
   920 
       
   921 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   922     boost::range_detail_microsoft::using_type_as_tag,
       
   923     BOOST_PP_NIL, CMapStringToString
       
   924 )
       
   925 
       
   926 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   927     boost::range_detail_microsoft::using_type_as_tag,
       
   928     BOOST_PP_NIL, CMapWordToOb
       
   929 )
       
   930 
       
   931 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   932     boost::range_detail_microsoft::using_type_as_tag,
       
   933     BOOST_PP_NIL, CMapWordToPtr
       
   934 )
       
   935 
       
   936 
       
   937 // templates
       
   938 //
       
   939 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   940     boost::range_detail_microsoft::using_type_as_tag,
       
   941     BOOST_PP_NIL, CArray, 2
       
   942 )
       
   943 
       
   944 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   945     boost::range_detail_microsoft::using_type_as_tag,
       
   946     BOOST_PP_NIL, CList, 2
       
   947 )
       
   948 
       
   949 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   950     boost::range_detail_microsoft::using_type_as_tag,
       
   951     BOOST_PP_NIL, CMap, 4
       
   952 )
       
   953 
       
   954 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   955     boost::range_detail_microsoft::using_type_as_tag,
       
   956     BOOST_PP_NIL, CTypedPtrArray, 2
       
   957 )
       
   958 
       
   959 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   960     boost::range_detail_microsoft::using_type_as_tag,
       
   961     BOOST_PP_NIL, CTypedPtrList, 2
       
   962 )
       
   963 
       
   964 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
       
   965     boost::range_detail_microsoft::using_type_as_tag,
       
   966     BOOST_PP_NIL, CTypedPtrMap, 3
       
   967 )
       
   968 
       
   969 
       
   970 // strings
       
   971 //
       
   972 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
       
   973 
       
   974     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
       
   975         boost::range_detail_microsoft::using_type_as_tag,
       
   976         BOOST_PP_NIL, CString
       
   977     )
       
   978 
       
   979 #endif
       
   980 
       
   981 
       
   982 
       
   983 
       
   984 #endif