985 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			985 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #ifndef BOOST_RANGE_MFC_HPP | ||
|  | #define BOOST_RANGE_MFC_HPP | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // Boost.Range MFC Extension | ||
|  | // | ||
|  | // Copyright Shunsuke Sogame 2005-2006. | ||
|  | // Distributed under the Boost Software License, Version 1.0.  | ||
|  | // (See accompanying file LICENSE_1_0.txt or copy at  | ||
|  | // http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // config | ||
|  | // | ||
|  | 
 | ||
|  | 
 | ||
|  | #include <afx.h> // _MFC_VER | ||
|  | 
 | ||
|  | 
 | ||
|  | #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  |     #if (_MFC_VER < 0x0700) // dubious | ||
|  |         #define BOOST_RANGE_MFC_NO_CPAIR | ||
|  |     #endif | ||
|  | #endif | ||
|  | 
 | ||
|  | 
 | ||
|  | #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) | ||
|  |     #if (_MFC_VER < 0x0700) // dubious | ||
|  |         #define BOOST_RANGE_MFC_HAS_LEGACY_STRING | ||
|  |     #endif | ||
|  | #endif | ||
|  | 
 | ||
|  | 
 | ||
|  | // A const collection of old MFC doesn't return const reference. | ||
|  | // | ||
|  | #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) | ||
|  |     #if (_MFC_VER < 0x0700) // dubious | ||
|  |         #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF | ||
|  |     #endif | ||
|  | #endif | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // forward declarations | ||
|  | // | ||
|  | 
 | ||
|  | 
 | ||
|  | template< class Type, class ArgType > | ||
|  | class CArray; | ||
|  | 
 | ||
|  | template< class Type, class ArgType > | ||
|  | class CList; | ||
|  | 
 | ||
|  | template< class Key, class ArgKey, class Mapped, class ArgMapped > | ||
|  | class CMap; | ||
|  | 
 | ||
|  | template< class BaseClass, class PtrType > | ||
|  | class CTypedPtrArray; | ||
|  | 
 | ||
|  | template< class BaseClass, class PtrType > | ||
|  | class CTypedPtrList; | ||
|  | 
 | ||
|  | template< class BaseClass, class KeyPtrType, class MappedPtrType > | ||
|  | class CTypedPtrMap; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // extended customizations | ||
|  | // | ||
|  | 
 | ||
|  | 
 | ||
|  | #include <cstddef> // ptrdiff_t | ||
|  | #include <utility> // pair | ||
|  | #include <boost/assert.hpp> | ||
|  | #include <boost/mpl/if.hpp> | ||
|  | #include <boost/range/atl.hpp> | ||
|  | #include <boost/range/begin.hpp> | ||
|  | #include <boost/range/const_iterator.hpp> | ||
|  | #include <boost/range/detail/microsoft.hpp> | ||
|  | #include <boost/range/end.hpp> | ||
|  | #include <boost/iterator/iterator_adaptor.hpp> | ||
|  | #include <boost/iterator/iterator_categories.hpp> | ||
|  | #include <boost/iterator/iterator_facade.hpp> | ||
|  | #include <boost/iterator/transform_iterator.hpp> | ||
|  | #include <boost/type_traits/is_const.hpp> | ||
|  | #include <boost/type_traits/remove_pointer.hpp> | ||
|  | #include <boost/utility/addressof.hpp> | ||
|  | #include <afx.h> // legacy CString | ||
|  | #include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX | ||
|  | #include <tchar.h> | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace boost { namespace range_detail_microsoft { | ||
|  | 
 | ||
|  | 
 | ||
|  |     // mfc_ptr_array_iterator | ||
|  |     // | ||
|  |     // 'void **' is not convertible to 'void const **', | ||
|  |     // so we define... | ||
|  |     // | ||
|  | 
 | ||
|  |     template< class ArrayT, class PtrType > | ||
|  |     struct mfc_ptr_array_iterator; | ||
|  | 
 | ||
|  |     template< class ArrayT, class PtrType > | ||
|  |     struct mfc_ptr_array_iterator_super | ||
|  |     { | ||
|  |         typedef iterator_adaptor< | ||
|  |             mfc_ptr_array_iterator<ArrayT, PtrType>, | ||
|  |             std::ptrdiff_t, // Base! | ||
|  |             PtrType,        // Value | ||
|  |             random_access_traversal_tag, | ||
|  |             use_default, | ||
|  |             std::ptrdiff_t  // Difference | ||
|  |         > type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template< class ArrayT, class PtrType > | ||
|  |     struct mfc_ptr_array_iterator : | ||
|  |         mfc_ptr_array_iterator_super<ArrayT, PtrType>::type | ||
|  |     { | ||
|  |     private: | ||
|  |         typedef mfc_ptr_array_iterator self_t; | ||
|  |         typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t; | ||
|  |         typedef typename super_t::reference ref_t; | ||
|  | 
 | ||
|  |     public: | ||
|  |         explicit mfc_ptr_array_iterator() | ||
|  |         { } | ||
|  | 
 | ||
|  |         explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) : | ||
|  |             super_t(index), m_parr(boost::addressof(arr)) | ||
|  |         { } | ||
|  | 
 | ||
|  |     template< class, class > friend struct mfc_ptr_array_iterator; | ||
|  |         template< class ArrayT_, class PtrType_ > | ||
|  |         mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) : | ||
|  |             super_t(other.base()), m_parr(other.m_parr) | ||
|  |         { } | ||
|  | 
 | ||
|  |     private: | ||
|  |         ArrayT *m_parr; | ||
|  | 
 | ||
|  |     friend class iterator_core_access; | ||
|  |         ref_t dereference() const | ||
|  |         { | ||
|  |             BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range"); | ||
|  |             return *( m_parr->GetData() + this->base() ); | ||
|  |         } | ||
|  | 
 | ||
|  |         bool equal(self_t const& other) const | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible"); | ||
|  |             return this->base() == other.base(); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct mfc_ptr_array_functions | ||
|  |     { | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator begin(X& x) | ||
|  |         { | ||
|  |             return Iterator(x, 0); | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator end(X& x) | ||
|  |         { | ||
|  |             return Iterator(x, x.GetSize()); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // arrays | ||
|  |     // | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CByteArray > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef BYTE val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CDWordArray > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef DWORD val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CObArray > : | ||
|  |         mfc_ptr_array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator; | ||
|  |             typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CPtrArray > : | ||
|  |         mfc_ptr_array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef mfc_ptr_array_iterator<X, void *> mutable_iterator; | ||
|  |             typedef mfc_ptr_array_iterator<X const, void const *> const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CStringArray > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef ::CString val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CUIntArray > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef UINT val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CWordArray > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef WORD val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // lists | ||
|  |     // | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CObList > : | ||
|  |         list_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef list_iterator<X, ::CObject *> mutable_iterator; | ||
|  |     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) | ||
|  |             typedef list_iterator<X const, ::CObject const *> const_iterator; | ||
|  |     #else | ||
|  |             typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator; | ||
|  |     #endif | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CPtrList > : | ||
|  |         list_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef list_iterator<X, void *> mutable_iterator; | ||
|  |     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) | ||
|  |             typedef list_iterator<X const, void const *> const_iterator; | ||
|  |     #else | ||
|  |             typedef list_iterator<X const, void const * const, void const * const> const_iterator; | ||
|  |     #endif | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CStringList > : | ||
|  |         list_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef ::CString val_t; | ||
|  | 
 | ||
|  |             typedef list_iterator<X, val_t> mutable_iterator; | ||
|  |     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) | ||
|  |             typedef list_iterator<X const, val_t const> const_iterator; | ||
|  |     #else | ||
|  |             typedef list_iterator<X const, val_t const, val_t const> const_iterator; | ||
|  |     #endif | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // mfc_map_iterator | ||
|  |     // | ||
|  | 
 | ||
|  |     template< class MapT, class KeyT, class MappedT > | ||
|  |     struct mfc_map_iterator; | ||
|  | 
 | ||
|  |     template< class MapT, class KeyT, class MappedT > | ||
|  |     struct mfc_map_iterator_super | ||
|  |     { | ||
|  |         typedef iterator_facade< | ||
|  |             mfc_map_iterator<MapT, KeyT, MappedT>, | ||
|  |             std::pair<KeyT, MappedT>, | ||
|  |             forward_traversal_tag, | ||
|  |             std::pair<KeyT, MappedT> const | ||
|  |         > type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template< class MapT, class KeyT, class MappedT > | ||
|  |     struct mfc_map_iterator : | ||
|  |         mfc_map_iterator_super<MapT, KeyT, MappedT>::type | ||
|  |     { | ||
|  |     private: | ||
|  |         typedef mfc_map_iterator self_t; | ||
|  |         typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t; | ||
|  |         typedef typename super_t::reference ref_t; | ||
|  | 
 | ||
|  |     public: | ||
|  |         explicit mfc_map_iterator() | ||
|  |         { } | ||
|  | 
 | ||
|  |         explicit mfc_map_iterator(MapT const& map, POSITION pos) : | ||
|  |             m_pmap(boost::addressof(map)), m_posNext(pos) | ||
|  |         { | ||
|  |             increment(); | ||
|  |         } | ||
|  | 
 | ||
|  |         explicit mfc_map_iterator(MapT const& map) : | ||
|  |             m_pmap(&map), m_pos(0) // end iterator | ||
|  |         { } | ||
|  | 
 | ||
|  |     template< class, class, class > friend struct mfc_map_iterator; | ||
|  |         template< class MapT_, class KeyT_, class MappedT_> | ||
|  |         mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) : | ||
|  |             m_pmap(other.m_pmap), | ||
|  |             m_pos(other.m_pos), m_posNext(other.m_posNext), | ||
|  |             m_key(other.m_key), m_mapped(other.m_mapped) | ||
|  |         { } | ||
|  | 
 | ||
|  |     private: | ||
|  |         MapT const *m_pmap; | ||
|  |         POSITION m_pos, m_posNext; | ||
|  |         KeyT m_key; MappedT m_mapped; | ||
|  | 
 | ||
|  |     friend class iterator_core_access; | ||
|  |         ref_t dereference() const | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pos != 0 && "out of range"); | ||
|  |             return std::make_pair(m_key, m_mapped); | ||
|  |         } | ||
|  | 
 | ||
|  |         void increment() | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pos != 0 && "out of range"); | ||
|  | 
 | ||
|  |             if (m_posNext == 0) { | ||
|  |                 m_pos = 0; | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             m_pos = m_posNext; | ||
|  |             m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped); | ||
|  |         } | ||
|  | 
 | ||
|  |         bool equal(self_t const& other) const | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible"); | ||
|  |             return m_pos == other.m_pos; | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct mfc_map_functions | ||
|  |     { | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator begin(X& x) | ||
|  |         { | ||
|  |             return Iterator(x, x.GetStartPosition()); | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator end(X& x) | ||
|  |         { | ||
|  |             return Iterator(x); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  | #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  | 
 | ||
|  | 
 | ||
|  |     // mfc_cpair_map_iterator | ||
|  |     // | ||
|  |     // used by ::CMap and ::CMapStringToString | ||
|  |     // | ||
|  | 
 | ||
|  |     template< class MapT, class PairT > | ||
|  |     struct mfc_cpair_map_iterator; | ||
|  | 
 | ||
|  |     template< class MapT, class PairT > | ||
|  |     struct mfc_pget_map_iterator_super | ||
|  |     { | ||
|  |         typedef iterator_facade< | ||
|  |             mfc_cpair_map_iterator<MapT, PairT>, | ||
|  |             PairT, | ||
|  |             forward_traversal_tag | ||
|  |         > type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template< class MapT, class PairT > | ||
|  |     struct mfc_cpair_map_iterator : | ||
|  |         mfc_pget_map_iterator_super<MapT, PairT>::type | ||
|  |     { | ||
|  |     private: | ||
|  |         typedef mfc_cpair_map_iterator self_t; | ||
|  |         typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t; | ||
|  |         typedef typename super_t::reference ref_t; | ||
|  | 
 | ||
|  |     public: | ||
|  |         explicit mfc_cpair_map_iterator() | ||
|  |         { } | ||
|  | 
 | ||
|  |         explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) : | ||
|  |             m_pmap(boost::addressof(map)), m_pp(pp) | ||
|  |         { } | ||
|  | 
 | ||
|  |     template< class, class > friend struct mfc_cpair_map_iterator; | ||
|  |         template< class MapT_, class PairT_> | ||
|  |         mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) : | ||
|  |             m_pmap(other.m_pmap), m_pp(other.m_pp) | ||
|  |         { } | ||
|  | 
 | ||
|  |     private: | ||
|  |         MapT  *m_pmap; | ||
|  |         PairT *m_pp; | ||
|  | 
 | ||
|  |     friend class iterator_core_access; | ||
|  |         ref_t dereference() const | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pp != 0 && "out of range"); | ||
|  |             return *m_pp; | ||
|  |         } | ||
|  | 
 | ||
|  |         void increment() | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pp != 0 && "out of range"); | ||
|  |             m_pp = m_pmap->PGetNextAssoc(m_pp); | ||
|  |         } | ||
|  | 
 | ||
|  |         bool equal(self_t const& other) const | ||
|  |         { | ||
|  |             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible"); | ||
|  |             return m_pp == other.m_pp; | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct mfc_cpair_map_functions | ||
|  |     { | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator begin(X& x) | ||
|  |         { | ||
|  |             // Workaround: | ||
|  |             // Assertion fails if empty. | ||
|  |             // MFC document is wrong. | ||
|  |     #if !defined(NDEBUG) | ||
|  |             if (x.GetCount() == 0)  | ||
|  |                 return Iterator(x, 0); | ||
|  |     #endif | ||
|  | 
 | ||
|  |             return Iterator(x, x.PGetFirstAssoc()); | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator end(X& x) | ||
|  |         { | ||
|  |             return Iterator(x, 0); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  | 
 | ||
|  | 
 | ||
|  |     // maps | ||
|  |     // | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapPtrToWord > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef void *key_t; | ||
|  |             typedef WORD mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapPtrToPtr > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef void *key_t; | ||
|  |             typedef void *mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapStringToOb > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef ::CString key_t; | ||
|  |             typedef ::CObject *mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapStringToPtr > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef ::CString key_t; | ||
|  |             typedef void *mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapStringToString > : | ||
|  |     #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  |         mfc_cpair_map_functions | ||
|  |     #else | ||
|  |         mfc_map_functions | ||
|  |     #endif | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |     #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  |             typedef typename X::CPair pair_t; | ||
|  | 
 | ||
|  |             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator; | ||
|  |             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator; | ||
|  |     #else | ||
|  |             typedef ::CString key_t; | ||
|  |             typedef ::CString mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |     #endif | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapWordToOb > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef WORD key_t; | ||
|  |             typedef ::CObject *mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CMapWordToPtr > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef WORD key_t; | ||
|  |             typedef void *mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // templates | ||
|  |     // | ||
|  | 
 | ||
|  |     template< class Type, class ArgType > | ||
|  |     struct customization< ::CArray<Type, ArgType> > : | ||
|  |         array_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef Type val_t; | ||
|  | 
 | ||
|  |             typedef val_t *mutable_iterator; | ||
|  |             typedef val_t const *const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class Type, class ArgType > | ||
|  |     struct customization< ::CList<Type, ArgType> > : | ||
|  |         list_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef Type val_t; | ||
|  | 
 | ||
|  |             typedef list_iterator<X, val_t> mutable_iterator; | ||
|  |     #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) | ||
|  |             typedef list_iterator<X const, val_t const> const_iterator; | ||
|  |     #else | ||
|  |             typedef list_iterator<X const, val_t const, val_t const> const_iterator; | ||
|  |     #endif | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class Key, class ArgKey, class Mapped, class ArgMapped > | ||
|  |     struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > : | ||
|  |     #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  |         mfc_cpair_map_functions | ||
|  |     #else | ||
|  |         mfc_map_functions | ||
|  |     #endif | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |     #if !defined(BOOST_RANGE_MFC_NO_CPAIR) | ||
|  |             typedef typename X::CPair pair_t; | ||
|  | 
 | ||
|  |             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator; | ||
|  |             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator; | ||
|  |     #else | ||
|  |             typedef Key key_t; | ||
|  |             typedef Mapped mapped_t; | ||
|  | 
 | ||
|  |             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |     #endif             | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class BaseClass, class PtrType > | ||
|  |     struct customization< ::CTypedPtrArray<BaseClass, PtrType> > | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct fun | ||
|  |         { | ||
|  |             typedef typename remove_pointer<PtrType>::type val_t; | ||
|  | 
 | ||
|  |             typedef typename mpl::if_< is_const<X>, | ||
|  |                 val_t const, | ||
|  |                 val_t | ||
|  |             >::type val_t_; | ||
|  | 
 | ||
|  |             typedef val_t_ * const result_type; | ||
|  | 
 | ||
|  |             template< class PtrType_ > | ||
|  |             result_type operator()(PtrType_ p) const | ||
|  |             { | ||
|  |                 return static_cast<result_type>(p); | ||
|  |             } | ||
|  |         }; | ||
|  | 
 | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef typename compatible_mutable_iterator<BaseClass>::type miter_t; | ||
|  |             typedef typename range_const_iterator<BaseClass>::type citer_t; | ||
|  | 
 | ||
|  |             typedef transform_iterator<fun<X>, miter_t> mutable_iterator; | ||
|  |             typedef transform_iterator<fun<X const>, citer_t> const_iterator; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator begin(X& x) | ||
|  |         { | ||
|  |             return Iterator(boost::begin<BaseClass>(x), fun<X>()); | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator end(X& x) | ||
|  |         { | ||
|  |             return Iterator(boost::end<BaseClass>(x), fun<X>()); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class BaseClass, class PtrType > | ||
|  |     struct customization< ::CTypedPtrList<BaseClass, PtrType> > : | ||
|  |         list_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef typename remove_pointer<PtrType>::type val_t; | ||
|  | 
 | ||
|  |             // not l-value | ||
|  |             typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator; | ||
|  |             typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class BaseClass, class KeyPtrType, class MappedPtrType > | ||
|  |     struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > : | ||
|  |         mfc_map_functions | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator; | ||
|  |             typedef mutable_iterator const_iterator; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // strings | ||
|  |     // | ||
|  | 
 | ||
|  | #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) | ||
|  | 
 | ||
|  |     template< > | ||
|  |     struct customization< ::CString > | ||
|  |     { | ||
|  |         template< class X > | ||
|  |         struct meta | ||
|  |         { | ||
|  |             // LPTSTR/LPCTSTR is not always defined in <tchar.h>. | ||
|  |             typedef TCHAR *mutable_iterator; | ||
|  |             typedef TCHAR const *const_iterator; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         typename mutable_<Iterator, X>::type begin(X& x) | ||
|  |         { | ||
|  |             return x.GetBuffer(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator begin(X const& x) | ||
|  |         { | ||
|  |             return x; | ||
|  |         } | ||
|  | 
 | ||
|  |         template< class Iterator, class X > | ||
|  |         Iterator end(X& x) | ||
|  |         { | ||
|  |             return begin<Iterator>(x) + x.GetLength(); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) | ||
|  | 
 | ||
|  | 
 | ||
|  | } } // namespace boost::range_detail_microsoft | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // range customizations | ||
|  | // | ||
|  | 
 | ||
|  | 
 | ||
|  | // arrays | ||
|  | // | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CByteArray | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CDWordArray | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CStringArray | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CUIntArray | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CWordArray | ||
|  | ) | ||
|  | 
 | ||
|  | 
 | ||
|  | // lists | ||
|  | // | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CObList | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CPtrList | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CStringList | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CObArray | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CPtrArray | ||
|  | ) | ||
|  | 
 | ||
|  | 
 | ||
|  | // maps | ||
|  | // | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapPtrToWord | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapPtrToPtr | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapStringToOb | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapStringToPtr | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapStringToString | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapWordToOb | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMapWordToPtr | ||
|  | ) | ||
|  | 
 | ||
|  | 
 | ||
|  | // templates | ||
|  | // | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CArray, 2 | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CList, 2 | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CMap, 4 | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CTypedPtrArray, 2 | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CTypedPtrList, 2 | ||
|  | ) | ||
|  | 
 | ||
|  | BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | ||
|  |     boost::range_detail_microsoft::using_type_as_tag, | ||
|  |     BOOST_PP_NIL, CTypedPtrMap, 3 | ||
|  | ) | ||
|  | 
 | ||
|  | 
 | ||
|  | // strings | ||
|  | // | ||
|  | #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) | ||
|  | 
 | ||
|  |     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | ||
|  |         boost::range_detail_microsoft::using_type_as_tag, | ||
|  |         BOOST_PP_NIL, CString | ||
|  |     ) | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif |