Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 08:28:29

0001 #ifndef BOOST_RANGE_MFC_HPP
0002 #define BOOST_RANGE_MFC_HPP
0003 
0004 
0005 
0006 
0007 // Boost.Range MFC Extension
0008 //
0009 // Copyright Shunsuke Sogame 2005-2006.
0010 // Distributed under the Boost Software License, Version 1.0. 
0011 // (See accompanying file LICENSE_1_0.txt or copy at 
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 
0015 
0016 
0017 // config
0018 //
0019 
0020 
0021 #include <afx.h> // _MFC_VER
0022 
0023 
0024 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0025     #if (_MFC_VER < 0x0700) // dubious
0026         #define BOOST_RANGE_MFC_NO_CPAIR
0027     #endif
0028 #endif
0029 
0030 
0031 #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0032     #if (_MFC_VER < 0x0700) // dubious
0033         #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
0034     #endif
0035 #endif
0036 
0037 
0038 // A const collection of old MFC doesn't return const reference.
0039 //
0040 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0041     #if (_MFC_VER < 0x0700) // dubious
0042         #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
0043     #endif
0044 #endif
0045 
0046 
0047 
0048 
0049 // forward declarations
0050 //
0051 
0052 
0053 template< class Type, class ArgType >
0054 class CArray;
0055 
0056 template< class Type, class ArgType >
0057 class CList;
0058 
0059 template< class Key, class ArgKey, class Mapped, class ArgMapped >
0060 class CMap;
0061 
0062 template< class BaseClass, class PtrType >
0063 class CTypedPtrArray;
0064 
0065 template< class BaseClass, class PtrType >
0066 class CTypedPtrList;
0067 
0068 template< class BaseClass, class KeyPtrType, class MappedPtrType >
0069 class CTypedPtrMap;
0070 
0071 
0072 
0073 
0074 // extended customizations
0075 //
0076 
0077 
0078 #include <cstddef> // ptrdiff_t
0079 #include <utility> // pair
0080 #include <boost/assert.hpp>
0081 #include <boost/mpl/if.hpp>
0082 #include <boost/range/atl.hpp>
0083 #include <boost/range/begin.hpp>
0084 #include <boost/range/const_iterator.hpp>
0085 #include <boost/range/detail/microsoft.hpp>
0086 #include <boost/range/end.hpp>
0087 #include <boost/iterator/iterator_adaptor.hpp>
0088 #include <boost/iterator/iterator_categories.hpp>
0089 #include <boost/iterator/iterator_facade.hpp>
0090 #include <boost/iterator/transform_iterator.hpp>
0091 #include <boost/type_traits/is_const.hpp>
0092 #include <boost/type_traits/remove_pointer.hpp>
0093 #include <boost/utility/addressof.hpp>
0094 #include <afx.h> // legacy CString
0095 #include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
0096 #include <tchar.h>
0097 
0098 
0099 namespace boost { namespace range_detail_microsoft {
0100 
0101 
0102     // mfc_ptr_array_iterator
0103     //
0104     // 'void **' is not convertible to 'void const **',
0105     // so we define...
0106     //
0107 
0108     template< class ArrayT, class PtrType >
0109     struct mfc_ptr_array_iterator;
0110 
0111     template< class ArrayT, class PtrType >
0112     struct mfc_ptr_array_iterator_super
0113     {
0114         typedef iterator_adaptor<
0115             mfc_ptr_array_iterator<ArrayT, PtrType>,
0116             std::ptrdiff_t, // Base!
0117             PtrType,        // Value
0118             random_access_traversal_tag,
0119             use_default,
0120             std::ptrdiff_t  // Difference
0121         > type;
0122     };
0123 
0124     template< class ArrayT, class PtrType >
0125     struct mfc_ptr_array_iterator :
0126         mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
0127     {
0128     private:
0129         typedef mfc_ptr_array_iterator self_t;
0130         typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
0131         typedef typename super_t::reference ref_t;
0132 
0133     public:
0134         explicit mfc_ptr_array_iterator()
0135         { }
0136 
0137         explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
0138             super_t(index), m_parr(boost::addressof(arr))
0139         { }
0140 
0141     template< class, class > friend struct mfc_ptr_array_iterator;
0142         template< class ArrayT_, class PtrType_ >
0143         mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
0144             super_t(other.base()), m_parr(other.m_parr)
0145         { }
0146 
0147     private:
0148         ArrayT *m_parr;
0149 
0150     friend class iterator_core_access;
0151         ref_t dereference() const
0152         {
0153             BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
0154             return *( m_parr->GetData() + this->base() );
0155         }
0156 
0157         bool equal(self_t const& other) const
0158         {
0159             BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
0160             return this->base() == other.base();
0161         }
0162     };
0163 
0164     struct mfc_ptr_array_functions
0165     {
0166         template< class Iterator, class X >
0167         Iterator begin(X& x)
0168         {
0169             return Iterator(x, 0);
0170         }
0171 
0172         template< class Iterator, class X >
0173         Iterator end(X& x)
0174         {
0175             return Iterator(x, x.GetSize());
0176         }
0177     };
0178 
0179 
0180     // arrays
0181     //
0182 
0183     template< >
0184     struct customization< ::CByteArray > :
0185         array_functions
0186     {
0187         template< class X >
0188         struct meta
0189         {
0190             typedef BYTE val_t;
0191 
0192             typedef val_t *mutable_iterator;
0193             typedef val_t const *const_iterator;
0194         };
0195     };
0196 
0197 
0198     template< >
0199     struct customization< ::CDWordArray > :
0200         array_functions
0201     {
0202         template< class X >
0203         struct meta
0204         {
0205             typedef DWORD val_t;
0206 
0207             typedef val_t *mutable_iterator;
0208             typedef val_t const *const_iterator;
0209         };
0210     };
0211 
0212 
0213     template< >
0214     struct customization< ::CObArray > :
0215         mfc_ptr_array_functions
0216     {
0217         template< class X >
0218         struct meta
0219         {
0220             typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
0221             typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
0222         };
0223     };
0224 
0225 
0226     template< >
0227     struct customization< ::CPtrArray > :
0228         mfc_ptr_array_functions
0229     {
0230         template< class X >
0231         struct meta
0232         {
0233             typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
0234             typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
0235         };
0236     };
0237 
0238 
0239     template< >
0240     struct customization< ::CStringArray > :
0241         array_functions
0242     {
0243         template< class X >
0244         struct meta
0245         {
0246             typedef ::CString val_t;
0247 
0248             typedef val_t *mutable_iterator;
0249             typedef val_t const *const_iterator;
0250         };
0251     };
0252 
0253 
0254     template< >
0255     struct customization< ::CUIntArray > :
0256         array_functions
0257     {
0258         template< class X >
0259         struct meta
0260         {
0261             typedef UINT val_t;
0262 
0263             typedef val_t *mutable_iterator;
0264             typedef val_t const *const_iterator;
0265         };
0266     };
0267 
0268 
0269     template< >
0270     struct customization< ::CWordArray > :
0271         array_functions
0272     {
0273         template< class X >
0274         struct meta
0275         {
0276             typedef WORD val_t;
0277 
0278             typedef val_t *mutable_iterator;
0279             typedef val_t const *const_iterator;
0280         };
0281     };
0282 
0283 
0284     // lists
0285     //
0286 
0287     template< >
0288     struct customization< ::CObList > :
0289         list_functions
0290     {
0291         template< class X >
0292         struct meta
0293         {
0294             typedef list_iterator<X, ::CObject *> mutable_iterator;
0295             // const CObList and const CPtrList both return a value (and probably always will)
0296             typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
0297         };
0298     };
0299 
0300 
0301     template< >
0302     struct customization< ::CPtrList > :
0303         list_functions
0304     {
0305         template< class X >
0306         struct meta
0307         {
0308             typedef list_iterator<X, void *> mutable_iterator;
0309             // const CObList and const CPtrList both return a value (and probably always will)
0310             typedef list_iterator<X const, void const * const, void const * const> const_iterator;
0311         };
0312     };
0313 
0314 
0315     template< >
0316     struct customization< ::CStringList > :
0317         list_functions
0318     {
0319         template< class X >
0320         struct meta
0321         {
0322             typedef ::CString val_t;
0323 
0324             typedef list_iterator<X, val_t> mutable_iterator;
0325     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0326             typedef list_iterator<X const, val_t const> const_iterator;
0327     #else
0328             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
0329     #endif
0330         };
0331     };
0332 
0333 
0334     // mfc_map_iterator
0335     //
0336 
0337     template< class MapT, class KeyT, class MappedT >
0338     struct mfc_map_iterator;
0339 
0340     template< class MapT, class KeyT, class MappedT >
0341     struct mfc_map_iterator_super
0342     {
0343         typedef iterator_facade<
0344             mfc_map_iterator<MapT, KeyT, MappedT>,
0345             std::pair<KeyT, MappedT>,
0346             forward_traversal_tag,
0347             std::pair<KeyT, MappedT> const
0348         > type;
0349     };
0350 
0351     template< class MapT, class KeyT, class MappedT >
0352     struct mfc_map_iterator :
0353         mfc_map_iterator_super<MapT, KeyT, MappedT>::type
0354     {
0355     private:
0356         typedef mfc_map_iterator self_t;
0357         typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
0358         typedef typename super_t::reference ref_t;
0359 
0360     public:
0361         explicit mfc_map_iterator()
0362         { }
0363 
0364         explicit mfc_map_iterator(MapT const& map, POSITION pos) :
0365             m_pmap(boost::addressof(map)), m_posNext(pos)
0366         {
0367             increment();
0368         }
0369 
0370         explicit mfc_map_iterator(MapT const& map) :
0371             m_pmap(&map), m_pos(0) // end iterator
0372         { }
0373 
0374     template< class, class, class > friend struct mfc_map_iterator;
0375         template< class MapT_, class KeyT_, class MappedT_>
0376         mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
0377             m_pmap(other.m_pmap),
0378             m_pos(other.m_pos), m_posNext(other.m_posNext),
0379             m_key(other.m_key), m_mapped(other.m_mapped)
0380         { }
0381 
0382     private:
0383         MapT const *m_pmap;
0384         POSITION m_pos, m_posNext;
0385         KeyT m_key; MappedT m_mapped;
0386 
0387     friend class iterator_core_access;
0388         ref_t dereference() const
0389         {
0390             BOOST_ASSERT(m_pos != 0 && "out of range");
0391             return std::make_pair(m_key, m_mapped);
0392         }
0393 
0394         void increment()
0395         {
0396             BOOST_ASSERT(m_pos != 0 && "out of range");
0397 
0398             if (m_posNext == 0) {
0399                 m_pos = 0;
0400                 return;
0401             }
0402 
0403             m_pos = m_posNext;
0404             m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
0405         }
0406 
0407         bool equal(self_t const& other) const
0408         {
0409             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
0410             return m_pos == other.m_pos;
0411         }
0412     };
0413 
0414     struct mfc_map_functions
0415     {
0416         template< class Iterator, class X >
0417         Iterator begin(X& x)
0418         {
0419             return Iterator(x, x.GetStartPosition());
0420         }
0421 
0422         template< class Iterator, class X >
0423         Iterator end(X& x)
0424         {
0425             return Iterator(x);
0426         }
0427     };
0428 
0429 
0430 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0431 
0432 
0433     // mfc_cpair_map_iterator
0434     //
0435     // used by ::CMap and ::CMapStringToString
0436     //
0437 
0438     template< class MapT, class PairT >
0439     struct mfc_cpair_map_iterator;
0440 
0441     template< class MapT, class PairT >
0442     struct mfc_pget_map_iterator_super
0443     {
0444         typedef iterator_facade<
0445             mfc_cpair_map_iterator<MapT, PairT>,
0446             PairT,
0447             forward_traversal_tag
0448         > type;
0449     };
0450 
0451     template< class MapT, class PairT >
0452     struct mfc_cpair_map_iterator :
0453         mfc_pget_map_iterator_super<MapT, PairT>::type
0454     {
0455     private:
0456         typedef mfc_cpair_map_iterator self_t;
0457         typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
0458         typedef typename super_t::reference ref_t;
0459 
0460     public:
0461         explicit mfc_cpair_map_iterator()
0462         { }
0463 
0464         explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
0465             m_pmap(boost::addressof(map)), m_pp(pp)
0466         { }
0467 
0468     template< class, class > friend struct mfc_cpair_map_iterator;
0469         template< class MapT_, class PairT_>
0470         mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
0471             m_pmap(other.m_pmap), m_pp(other.m_pp)
0472         { }
0473 
0474     private:
0475         MapT  *m_pmap;
0476         PairT *m_pp;
0477 
0478     friend class iterator_core_access;
0479         ref_t dereference() const
0480         {
0481             BOOST_ASSERT(m_pp != 0 && "out of range");
0482             return *m_pp;
0483         }
0484 
0485         void increment()
0486         {
0487             BOOST_ASSERT(m_pp != 0 && "out of range");
0488             m_pp = m_pmap->PGetNextAssoc(m_pp);
0489         }
0490 
0491         bool equal(self_t const& other) const
0492         {
0493             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
0494             return m_pp == other.m_pp;
0495         }
0496     };
0497 
0498     struct mfc_cpair_map_functions
0499     {
0500         template< class Iterator, class X >
0501         Iterator begin(X& x)
0502         {
0503             // Workaround:
0504             // Assertion fails if empty.
0505             // MFC document is wrong.
0506     #if !defined(NDEBUG)
0507             if (x.GetCount() == 0) 
0508                 return Iterator(x, 0);
0509     #endif
0510 
0511             return Iterator(x, x.PGetFirstAssoc());
0512         }
0513 
0514         template< class Iterator, class X >
0515         Iterator end(X& x)
0516         {
0517             return Iterator(x, 0);
0518         }
0519     };
0520 
0521 
0522 #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
0523 
0524 
0525     // maps
0526     //
0527 
0528     template< >
0529     struct customization< ::CMapPtrToWord > :
0530         mfc_map_functions
0531     {
0532         template< class X >
0533         struct meta
0534         {
0535             typedef void *key_t;
0536             typedef WORD mapped_t;
0537 
0538             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0539             typedef mutable_iterator const_iterator;
0540         };
0541     };
0542 
0543 
0544     template< >
0545     struct customization< ::CMapPtrToPtr > :
0546         mfc_map_functions
0547     {
0548         template< class X >
0549         struct meta
0550         {
0551             typedef void *key_t;
0552             typedef void *mapped_t;
0553 
0554             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0555             typedef mutable_iterator const_iterator;
0556         };
0557     };
0558 
0559 
0560     template< >
0561     struct customization< ::CMapStringToOb > :
0562         mfc_map_functions
0563     {
0564         template< class X >
0565         struct meta
0566         {
0567             typedef ::CString key_t;
0568             typedef ::CObject *mapped_t;
0569 
0570             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0571             typedef mutable_iterator const_iterator;
0572         };
0573     };
0574 
0575 
0576     template< >
0577     struct customization< ::CMapStringToPtr > :
0578         mfc_map_functions
0579     {
0580         template< class X >
0581         struct meta
0582         {
0583             typedef ::CString key_t;
0584             typedef void *mapped_t;
0585 
0586             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0587             typedef mutable_iterator const_iterator;
0588         };
0589     };
0590 
0591 
0592     template< >
0593     struct customization< ::CMapStringToString > :
0594     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0595         mfc_cpair_map_functions
0596     #else
0597         mfc_map_functions
0598     #endif
0599     {
0600         template< class X >
0601         struct meta
0602         {
0603     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0604             typedef typename X::CPair pair_t;
0605 
0606             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
0607             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
0608     #else
0609             typedef ::CString key_t;
0610             typedef ::CString mapped_t;
0611 
0612             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0613             typedef mutable_iterator const_iterator;
0614     #endif
0615         };
0616     };
0617 
0618 
0619     template< >
0620     struct customization< ::CMapWordToOb > :
0621         mfc_map_functions
0622     {
0623         template< class X >
0624         struct meta
0625         {
0626             typedef WORD key_t;
0627             typedef ::CObject *mapped_t;
0628 
0629             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0630             typedef mutable_iterator const_iterator;
0631         };
0632     };
0633 
0634 
0635     template< >
0636     struct customization< ::CMapWordToPtr > :
0637         mfc_map_functions
0638     {
0639         template< class X >
0640         struct meta
0641         {
0642             typedef WORD key_t;
0643             typedef void *mapped_t;
0644 
0645             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0646             typedef mutable_iterator const_iterator;
0647         };
0648     };
0649 
0650 
0651     // templates
0652     //
0653 
0654     template< class Type, class ArgType >
0655     struct customization< ::CArray<Type, ArgType> > :
0656         array_functions
0657     {
0658         template< class X >
0659         struct meta
0660         {
0661             typedef Type val_t;
0662 
0663             typedef val_t *mutable_iterator;
0664             typedef val_t const *const_iterator;
0665         };
0666     };
0667 
0668 
0669     template< class Type, class ArgType >
0670     struct customization< ::CList<Type, ArgType> > :
0671         list_functions
0672     {
0673         template< class X >
0674         struct meta
0675         {
0676             typedef Type val_t;
0677 
0678             typedef list_iterator<X, val_t> mutable_iterator;
0679     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0680             typedef list_iterator<X const, val_t const> const_iterator;
0681     #else
0682             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
0683     #endif
0684         };
0685     };
0686 
0687 
0688     template< class Key, class ArgKey, class Mapped, class ArgMapped >
0689     struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
0690     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0691         mfc_cpair_map_functions
0692     #else
0693         mfc_map_functions
0694     #endif
0695     {
0696         template< class X >
0697         struct meta
0698         {
0699     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0700             typedef typename X::CPair pair_t;
0701 
0702             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
0703             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
0704     #else
0705             typedef Key key_t;
0706             typedef Mapped mapped_t;
0707 
0708             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0709             typedef mutable_iterator const_iterator;
0710     #endif            
0711         };
0712     };
0713 
0714 
0715     template< class BaseClass, class PtrType >
0716     struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
0717     {
0718         template< class X >
0719         struct fun
0720         {
0721             typedef typename remove_pointer<PtrType>::type val_t;
0722 
0723             typedef typename mpl::if_< is_const<X>,
0724                 val_t const,
0725                 val_t
0726             >::type val_t_;
0727 
0728             typedef val_t_ * const result_type;
0729 
0730             template< class PtrType_ >
0731             result_type operator()(PtrType_ p) const
0732             {
0733                 return static_cast<result_type>(p);
0734             }
0735         };
0736 
0737         template< class X >
0738         struct meta
0739         {
0740             typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
0741             typedef typename range_const_iterator<BaseClass>::type citer_t;
0742 
0743             typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
0744             typedef transform_iterator<fun<X const>, citer_t> const_iterator;
0745         };
0746 
0747         template< class Iterator, class X >
0748         Iterator begin(X& x)
0749         {
0750             return Iterator(boost::begin<BaseClass>(x), fun<X>());
0751         }
0752 
0753         template< class Iterator, class X >
0754         Iterator end(X& x)
0755         {
0756             return Iterator(boost::end<BaseClass>(x), fun<X>());
0757         }
0758     };
0759 
0760 
0761     template< class BaseClass, class PtrType >
0762     struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
0763         list_functions
0764     {
0765         template< class X >
0766         struct meta
0767         {
0768             typedef typename remove_pointer<PtrType>::type val_t;
0769 
0770             // not l-value
0771             typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
0772             typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
0773         };
0774     };
0775 
0776 
0777     template< class BaseClass, class KeyPtrType, class MappedPtrType >
0778     struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
0779         mfc_map_functions
0780     {
0781         template< class X >
0782         struct meta
0783         {
0784             typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
0785             typedef mutable_iterator const_iterator;
0786         };
0787     };
0788 
0789 
0790     // strings
0791     //
0792 
0793 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0794 
0795     template< >
0796     struct customization< ::CString >
0797     {
0798         template< class X >
0799         struct meta
0800         {
0801             // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
0802             typedef TCHAR *mutable_iterator;
0803             typedef TCHAR const *const_iterator;
0804         };
0805 
0806         template< class Iterator, class X >
0807         typename mutable_<Iterator, X>::type begin(X& x)
0808         {
0809             return x.GetBuffer(0);
0810         }
0811 
0812         template< class Iterator, class X >
0813         Iterator begin(X const& x)
0814         {
0815             return x;
0816         }
0817 
0818         template< class Iterator, class X >
0819         Iterator end(X& x)
0820         {
0821             return begin<Iterator>(x) + x.GetLength();
0822         }
0823     };
0824 
0825 #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0826 
0827 
0828 } } // namespace boost::range_detail_microsoft
0829 
0830 
0831 
0832 
0833 // range customizations
0834 //
0835 
0836 
0837 // arrays
0838 //
0839 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0840     boost::range_detail_microsoft::using_type_as_tag,
0841     BOOST_PP_NIL, CByteArray
0842 )
0843 
0844 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0845     boost::range_detail_microsoft::using_type_as_tag,
0846     BOOST_PP_NIL, CDWordArray
0847 )
0848 
0849 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0850     boost::range_detail_microsoft::using_type_as_tag,
0851     BOOST_PP_NIL, CStringArray
0852 )
0853 
0854 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0855     boost::range_detail_microsoft::using_type_as_tag,
0856     BOOST_PP_NIL, CUIntArray
0857 )
0858 
0859 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0860     boost::range_detail_microsoft::using_type_as_tag,
0861     BOOST_PP_NIL, CWordArray
0862 )
0863 
0864 
0865 // lists
0866 //
0867 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0868     boost::range_detail_microsoft::using_type_as_tag,
0869     BOOST_PP_NIL, CObList
0870 )
0871 
0872 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0873     boost::range_detail_microsoft::using_type_as_tag,
0874     BOOST_PP_NIL, CPtrList
0875 )
0876 
0877 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0878     boost::range_detail_microsoft::using_type_as_tag,
0879     BOOST_PP_NIL, CStringList
0880 )
0881 
0882 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0883     boost::range_detail_microsoft::using_type_as_tag,
0884     BOOST_PP_NIL, CObArray
0885 )
0886 
0887 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0888     boost::range_detail_microsoft::using_type_as_tag,
0889     BOOST_PP_NIL, CPtrArray
0890 )
0891 
0892 
0893 // maps
0894 //
0895 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0896     boost::range_detail_microsoft::using_type_as_tag,
0897     BOOST_PP_NIL, CMapPtrToWord
0898 )
0899 
0900 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0901     boost::range_detail_microsoft::using_type_as_tag,
0902     BOOST_PP_NIL, CMapPtrToPtr
0903 )
0904 
0905 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0906     boost::range_detail_microsoft::using_type_as_tag,
0907     BOOST_PP_NIL, CMapStringToOb
0908 )
0909 
0910 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0911     boost::range_detail_microsoft::using_type_as_tag,
0912     BOOST_PP_NIL, CMapStringToPtr
0913 )
0914 
0915 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0916     boost::range_detail_microsoft::using_type_as_tag,
0917     BOOST_PP_NIL, CMapStringToString
0918 )
0919 
0920 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0921     boost::range_detail_microsoft::using_type_as_tag,
0922     BOOST_PP_NIL, CMapWordToOb
0923 )
0924 
0925 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0926     boost::range_detail_microsoft::using_type_as_tag,
0927     BOOST_PP_NIL, CMapWordToPtr
0928 )
0929 
0930 
0931 // templates
0932 //
0933 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0934     boost::range_detail_microsoft::using_type_as_tag,
0935     BOOST_PP_NIL, CArray, 2
0936 )
0937 
0938 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0939     boost::range_detail_microsoft::using_type_as_tag,
0940     BOOST_PP_NIL, CList, 2
0941 )
0942 
0943 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0944     boost::range_detail_microsoft::using_type_as_tag,
0945     BOOST_PP_NIL, CMap, 4
0946 )
0947 
0948 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0949     boost::range_detail_microsoft::using_type_as_tag,
0950     BOOST_PP_NIL, CTypedPtrArray, 2
0951 )
0952 
0953 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0954     boost::range_detail_microsoft::using_type_as_tag,
0955     BOOST_PP_NIL, CTypedPtrList, 2
0956 )
0957 
0958 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0959     boost::range_detail_microsoft::using_type_as_tag,
0960     BOOST_PP_NIL, CTypedPtrMap, 3
0961 )
0962 
0963 
0964 // strings
0965 //
0966 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0967 
0968     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0969         boost::range_detail_microsoft::using_type_as_tag,
0970         BOOST_PP_NIL, CString
0971     )
0972 
0973 #endif
0974 
0975 
0976 
0977 
0978 #endif