Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:18

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     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0296             typedef list_iterator<X const, ::CObject const *> const_iterator;
0297     #else
0298             typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
0299     #endif
0300         };
0301     };
0302 
0303 
0304     template< >
0305     struct customization< ::CPtrList > :
0306         list_functions
0307     {
0308         template< class X >
0309         struct meta
0310         {
0311             typedef list_iterator<X, void *> mutable_iterator;
0312     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0313             typedef list_iterator<X const, void const *> const_iterator;
0314     #else
0315             typedef list_iterator<X const, void const * const, void const * const> const_iterator;
0316     #endif
0317         };
0318     };
0319 
0320 
0321     template< >
0322     struct customization< ::CStringList > :
0323         list_functions
0324     {
0325         template< class X >
0326         struct meta
0327         {
0328             typedef ::CString val_t;
0329 
0330             typedef list_iterator<X, val_t> mutable_iterator;
0331     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0332             typedef list_iterator<X const, val_t const> const_iterator;
0333     #else
0334             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
0335     #endif
0336         };
0337     };
0338 
0339 
0340     // mfc_map_iterator
0341     //
0342 
0343     template< class MapT, class KeyT, class MappedT >
0344     struct mfc_map_iterator;
0345 
0346     template< class MapT, class KeyT, class MappedT >
0347     struct mfc_map_iterator_super
0348     {
0349         typedef iterator_facade<
0350             mfc_map_iterator<MapT, KeyT, MappedT>,
0351             std::pair<KeyT, MappedT>,
0352             forward_traversal_tag,
0353             std::pair<KeyT, MappedT> const
0354         > type;
0355     };
0356 
0357     template< class MapT, class KeyT, class MappedT >
0358     struct mfc_map_iterator :
0359         mfc_map_iterator_super<MapT, KeyT, MappedT>::type
0360     {
0361     private:
0362         typedef mfc_map_iterator self_t;
0363         typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
0364         typedef typename super_t::reference ref_t;
0365 
0366     public:
0367         explicit mfc_map_iterator()
0368         { }
0369 
0370         explicit mfc_map_iterator(MapT const& map, POSITION pos) :
0371             m_pmap(boost::addressof(map)), m_posNext(pos)
0372         {
0373             increment();
0374         }
0375 
0376         explicit mfc_map_iterator(MapT const& map) :
0377             m_pmap(&map), m_pos(0) // end iterator
0378         { }
0379 
0380     template< class, class, class > friend struct mfc_map_iterator;
0381         template< class MapT_, class KeyT_, class MappedT_>
0382         mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
0383             m_pmap(other.m_pmap),
0384             m_pos(other.m_pos), m_posNext(other.m_posNext),
0385             m_key(other.m_key), m_mapped(other.m_mapped)
0386         { }
0387 
0388     private:
0389         MapT const *m_pmap;
0390         POSITION m_pos, m_posNext;
0391         KeyT m_key; MappedT m_mapped;
0392 
0393     friend class iterator_core_access;
0394         ref_t dereference() const
0395         {
0396             BOOST_ASSERT(m_pos != 0 && "out of range");
0397             return std::make_pair(m_key, m_mapped);
0398         }
0399 
0400         void increment()
0401         {
0402             BOOST_ASSERT(m_pos != 0 && "out of range");
0403 
0404             if (m_posNext == 0) {
0405                 m_pos = 0;
0406                 return;
0407             }
0408 
0409             m_pos = m_posNext;
0410             m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
0411         }
0412 
0413         bool equal(self_t const& other) const
0414         {
0415             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
0416             return m_pos == other.m_pos;
0417         }
0418     };
0419 
0420     struct mfc_map_functions
0421     {
0422         template< class Iterator, class X >
0423         Iterator begin(X& x)
0424         {
0425             return Iterator(x, x.GetStartPosition());
0426         }
0427 
0428         template< class Iterator, class X >
0429         Iterator end(X& x)
0430         {
0431             return Iterator(x);
0432         }
0433     };
0434 
0435 
0436 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0437 
0438 
0439     // mfc_cpair_map_iterator
0440     //
0441     // used by ::CMap and ::CMapStringToString
0442     //
0443 
0444     template< class MapT, class PairT >
0445     struct mfc_cpair_map_iterator;
0446 
0447     template< class MapT, class PairT >
0448     struct mfc_pget_map_iterator_super
0449     {
0450         typedef iterator_facade<
0451             mfc_cpair_map_iterator<MapT, PairT>,
0452             PairT,
0453             forward_traversal_tag
0454         > type;
0455     };
0456 
0457     template< class MapT, class PairT >
0458     struct mfc_cpair_map_iterator :
0459         mfc_pget_map_iterator_super<MapT, PairT>::type
0460     {
0461     private:
0462         typedef mfc_cpair_map_iterator self_t;
0463         typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
0464         typedef typename super_t::reference ref_t;
0465 
0466     public:
0467         explicit mfc_cpair_map_iterator()
0468         { }
0469 
0470         explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
0471             m_pmap(boost::addressof(map)), m_pp(pp)
0472         { }
0473 
0474     template< class, class > friend struct mfc_cpair_map_iterator;
0475         template< class MapT_, class PairT_>
0476         mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
0477             m_pmap(other.m_pmap), m_pp(other.m_pp)
0478         { }
0479 
0480     private:
0481         MapT  *m_pmap;
0482         PairT *m_pp;
0483 
0484     friend class iterator_core_access;
0485         ref_t dereference() const
0486         {
0487             BOOST_ASSERT(m_pp != 0 && "out of range");
0488             return *m_pp;
0489         }
0490 
0491         void increment()
0492         {
0493             BOOST_ASSERT(m_pp != 0 && "out of range");
0494             m_pp = m_pmap->PGetNextAssoc(m_pp);
0495         }
0496 
0497         bool equal(self_t const& other) const
0498         {
0499             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
0500             return m_pp == other.m_pp;
0501         }
0502     };
0503 
0504     struct mfc_cpair_map_functions
0505     {
0506         template< class Iterator, class X >
0507         Iterator begin(X& x)
0508         {
0509             // Workaround:
0510             // Assertion fails if empty.
0511             // MFC document is wrong.
0512     #if !defined(NDEBUG)
0513             if (x.GetCount() == 0) 
0514                 return Iterator(x, 0);
0515     #endif
0516 
0517             return Iterator(x, x.PGetFirstAssoc());
0518         }
0519 
0520         template< class Iterator, class X >
0521         Iterator end(X& x)
0522         {
0523             return Iterator(x, 0);
0524         }
0525     };
0526 
0527 
0528 #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
0529 
0530 
0531     // maps
0532     //
0533 
0534     template< >
0535     struct customization< ::CMapPtrToWord > :
0536         mfc_map_functions
0537     {
0538         template< class X >
0539         struct meta
0540         {
0541             typedef void *key_t;
0542             typedef WORD mapped_t;
0543 
0544             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0545             typedef mutable_iterator const_iterator;
0546         };
0547     };
0548 
0549 
0550     template< >
0551     struct customization< ::CMapPtrToPtr > :
0552         mfc_map_functions
0553     {
0554         template< class X >
0555         struct meta
0556         {
0557             typedef void *key_t;
0558             typedef void *mapped_t;
0559 
0560             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0561             typedef mutable_iterator const_iterator;
0562         };
0563     };
0564 
0565 
0566     template< >
0567     struct customization< ::CMapStringToOb > :
0568         mfc_map_functions
0569     {
0570         template< class X >
0571         struct meta
0572         {
0573             typedef ::CString key_t;
0574             typedef ::CObject *mapped_t;
0575 
0576             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0577             typedef mutable_iterator const_iterator;
0578         };
0579     };
0580 
0581 
0582     template< >
0583     struct customization< ::CMapStringToPtr > :
0584         mfc_map_functions
0585     {
0586         template< class X >
0587         struct meta
0588         {
0589             typedef ::CString key_t;
0590             typedef void *mapped_t;
0591 
0592             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0593             typedef mutable_iterator const_iterator;
0594         };
0595     };
0596 
0597 
0598     template< >
0599     struct customization< ::CMapStringToString > :
0600     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0601         mfc_cpair_map_functions
0602     #else
0603         mfc_map_functions
0604     #endif
0605     {
0606         template< class X >
0607         struct meta
0608         {
0609     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0610             typedef typename X::CPair pair_t;
0611 
0612             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
0613             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
0614     #else
0615             typedef ::CString key_t;
0616             typedef ::CString mapped_t;
0617 
0618             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0619             typedef mutable_iterator const_iterator;
0620     #endif
0621         };
0622     };
0623 
0624 
0625     template< >
0626     struct customization< ::CMapWordToOb > :
0627         mfc_map_functions
0628     {
0629         template< class X >
0630         struct meta
0631         {
0632             typedef WORD key_t;
0633             typedef ::CObject *mapped_t;
0634 
0635             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0636             typedef mutable_iterator const_iterator;
0637         };
0638     };
0639 
0640 
0641     template< >
0642     struct customization< ::CMapWordToPtr > :
0643         mfc_map_functions
0644     {
0645         template< class X >
0646         struct meta
0647         {
0648             typedef WORD key_t;
0649             typedef void *mapped_t;
0650 
0651             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0652             typedef mutable_iterator const_iterator;
0653         };
0654     };
0655 
0656 
0657     // templates
0658     //
0659 
0660     template< class Type, class ArgType >
0661     struct customization< ::CArray<Type, ArgType> > :
0662         array_functions
0663     {
0664         template< class X >
0665         struct meta
0666         {
0667             typedef Type val_t;
0668 
0669             typedef val_t *mutable_iterator;
0670             typedef val_t const *const_iterator;
0671         };
0672     };
0673 
0674 
0675     template< class Type, class ArgType >
0676     struct customization< ::CList<Type, ArgType> > :
0677         list_functions
0678     {
0679         template< class X >
0680         struct meta
0681         {
0682             typedef Type val_t;
0683 
0684             typedef list_iterator<X, val_t> mutable_iterator;
0685     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
0686             typedef list_iterator<X const, val_t const> const_iterator;
0687     #else
0688             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
0689     #endif
0690         };
0691     };
0692 
0693 
0694     template< class Key, class ArgKey, class Mapped, class ArgMapped >
0695     struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
0696     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0697         mfc_cpair_map_functions
0698     #else
0699         mfc_map_functions
0700     #endif
0701     {
0702         template< class X >
0703         struct meta
0704         {
0705     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
0706             typedef typename X::CPair pair_t;
0707 
0708             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
0709             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
0710     #else
0711             typedef Key key_t;
0712             typedef Mapped mapped_t;
0713 
0714             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
0715             typedef mutable_iterator const_iterator;
0716     #endif            
0717         };
0718     };
0719 
0720 
0721     template< class BaseClass, class PtrType >
0722     struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
0723     {
0724         template< class X >
0725         struct fun
0726         {
0727             typedef typename remove_pointer<PtrType>::type val_t;
0728 
0729             typedef typename mpl::if_< is_const<X>,
0730                 val_t const,
0731                 val_t
0732             >::type val_t_;
0733 
0734             typedef val_t_ * const result_type;
0735 
0736             template< class PtrType_ >
0737             result_type operator()(PtrType_ p) const
0738             {
0739                 return static_cast<result_type>(p);
0740             }
0741         };
0742 
0743         template< class X >
0744         struct meta
0745         {
0746             typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
0747             typedef typename range_const_iterator<BaseClass>::type citer_t;
0748 
0749             typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
0750             typedef transform_iterator<fun<X const>, citer_t> const_iterator;
0751         };
0752 
0753         template< class Iterator, class X >
0754         Iterator begin(X& x)
0755         {
0756             return Iterator(boost::begin<BaseClass>(x), fun<X>());
0757         }
0758 
0759         template< class Iterator, class X >
0760         Iterator end(X& x)
0761         {
0762             return Iterator(boost::end<BaseClass>(x), fun<X>());
0763         }
0764     };
0765 
0766 
0767     template< class BaseClass, class PtrType >
0768     struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
0769         list_functions
0770     {
0771         template< class X >
0772         struct meta
0773         {
0774             typedef typename remove_pointer<PtrType>::type val_t;
0775 
0776             // not l-value
0777             typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
0778             typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
0779         };
0780     };
0781 
0782 
0783     template< class BaseClass, class KeyPtrType, class MappedPtrType >
0784     struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
0785         mfc_map_functions
0786     {
0787         template< class X >
0788         struct meta
0789         {
0790             typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
0791             typedef mutable_iterator const_iterator;
0792         };
0793     };
0794 
0795 
0796     // strings
0797     //
0798 
0799 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0800 
0801     template< >
0802     struct customization< ::CString >
0803     {
0804         template< class X >
0805         struct meta
0806         {
0807             // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
0808             typedef TCHAR *mutable_iterator;
0809             typedef TCHAR const *const_iterator;
0810         };
0811 
0812         template< class Iterator, class X >
0813         typename mutable_<Iterator, X>::type begin(X& x)
0814         {
0815             return x.GetBuffer(0);
0816         }
0817 
0818         template< class Iterator, class X >
0819         Iterator begin(X const& x)
0820         {
0821             return x;
0822         }
0823 
0824         template< class Iterator, class X >
0825         Iterator end(X& x)
0826         {
0827             return begin<Iterator>(x) + x.GetLength();
0828         }
0829     };
0830 
0831 #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0832 
0833 
0834 } } // namespace boost::range_detail_microsoft
0835 
0836 
0837 
0838 
0839 // range customizations
0840 //
0841 
0842 
0843 // arrays
0844 //
0845 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0846     boost::range_detail_microsoft::using_type_as_tag,
0847     BOOST_PP_NIL, CByteArray
0848 )
0849 
0850 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0851     boost::range_detail_microsoft::using_type_as_tag,
0852     BOOST_PP_NIL, CDWordArray
0853 )
0854 
0855 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0856     boost::range_detail_microsoft::using_type_as_tag,
0857     BOOST_PP_NIL, CStringArray
0858 )
0859 
0860 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0861     boost::range_detail_microsoft::using_type_as_tag,
0862     BOOST_PP_NIL, CUIntArray
0863 )
0864 
0865 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0866     boost::range_detail_microsoft::using_type_as_tag,
0867     BOOST_PP_NIL, CWordArray
0868 )
0869 
0870 
0871 // lists
0872 //
0873 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0874     boost::range_detail_microsoft::using_type_as_tag,
0875     BOOST_PP_NIL, CObList
0876 )
0877 
0878 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0879     boost::range_detail_microsoft::using_type_as_tag,
0880     BOOST_PP_NIL, CPtrList
0881 )
0882 
0883 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0884     boost::range_detail_microsoft::using_type_as_tag,
0885     BOOST_PP_NIL, CStringList
0886 )
0887 
0888 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0889     boost::range_detail_microsoft::using_type_as_tag,
0890     BOOST_PP_NIL, CObArray
0891 )
0892 
0893 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0894     boost::range_detail_microsoft::using_type_as_tag,
0895     BOOST_PP_NIL, CPtrArray
0896 )
0897 
0898 
0899 // maps
0900 //
0901 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0902     boost::range_detail_microsoft::using_type_as_tag,
0903     BOOST_PP_NIL, CMapPtrToWord
0904 )
0905 
0906 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0907     boost::range_detail_microsoft::using_type_as_tag,
0908     BOOST_PP_NIL, CMapPtrToPtr
0909 )
0910 
0911 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0912     boost::range_detail_microsoft::using_type_as_tag,
0913     BOOST_PP_NIL, CMapStringToOb
0914 )
0915 
0916 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0917     boost::range_detail_microsoft::using_type_as_tag,
0918     BOOST_PP_NIL, CMapStringToPtr
0919 )
0920 
0921 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0922     boost::range_detail_microsoft::using_type_as_tag,
0923     BOOST_PP_NIL, CMapStringToString
0924 )
0925 
0926 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0927     boost::range_detail_microsoft::using_type_as_tag,
0928     BOOST_PP_NIL, CMapWordToOb
0929 )
0930 
0931 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0932     boost::range_detail_microsoft::using_type_as_tag,
0933     BOOST_PP_NIL, CMapWordToPtr
0934 )
0935 
0936 
0937 // templates
0938 //
0939 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0940     boost::range_detail_microsoft::using_type_as_tag,
0941     BOOST_PP_NIL, CArray, 2
0942 )
0943 
0944 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0945     boost::range_detail_microsoft::using_type_as_tag,
0946     BOOST_PP_NIL, CList, 2
0947 )
0948 
0949 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0950     boost::range_detail_microsoft::using_type_as_tag,
0951     BOOST_PP_NIL, CMap, 4
0952 )
0953 
0954 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0955     boost::range_detail_microsoft::using_type_as_tag,
0956     BOOST_PP_NIL, CTypedPtrArray, 2
0957 )
0958 
0959 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0960     boost::range_detail_microsoft::using_type_as_tag,
0961     BOOST_PP_NIL, CTypedPtrList, 2
0962 )
0963 
0964 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
0965     boost::range_detail_microsoft::using_type_as_tag,
0966     BOOST_PP_NIL, CTypedPtrMap, 3
0967 )
0968 
0969 
0970 // strings
0971 //
0972 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
0973 
0974     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
0975         boost::range_detail_microsoft::using_type_as_tag,
0976         BOOST_PP_NIL, CString
0977     )
0978 
0979 #endif
0980 
0981 
0982 
0983 
0984 #endif