1 #ifndef BOOST_RANGE_MFC_HPP
2 #define BOOST_RANGE_MFC_HPP
7 // Boost.Range MFC Extension
9 // Copyright Shunsuke Sogame 2005-2006.
10 // Distributed under the Boost Software License, Version 1.0.
11 // (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
21 #include <afx.h> // _MFC_VER
24 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
25 #if (_MFC_VER < 0x0700) // dubious
26 #define BOOST_RANGE_MFC_NO_CPAIR
31 #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
32 #if (_MFC_VER < 0x0700) // dubious
33 #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
38 // A const collection of old MFC doesn't return const reference.
40 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
41 #if (_MFC_VER < 0x0700) // dubious
42 #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
49 // forward declarations
53 template< class Type, class ArgType >
56 template< class Type, class ArgType >
59 template< class Key, class ArgKey, class Mapped, class ArgMapped >
62 template< class BaseClass, class PtrType >
65 template< class BaseClass, class PtrType >
68 template< class BaseClass, class KeyPtrType, class MappedPtrType >
74 // extended customizations
78 #include <cstddef> // ptrdiff_t
79 #include <utility> // pair
80 #include <boost/assert.hpp>
81 #include <boost/mpl/if.hpp>
82 #include <boost/range/atl.hpp>
83 #include <boost/range/begin.hpp>
84 #include <boost/range/const_iterator.hpp>
85 #include <boost/range/detail/microsoft.hpp>
86 #include <boost/range/end.hpp>
87 #include <boost/iterator/iterator_adaptor.hpp>
88 #include <boost/iterator/iterator_categories.hpp>
89 #include <boost/iterator/iterator_facade.hpp>
90 #include <boost/iterator/transform_iterator.hpp>
91 #include <boost/type_traits/is_const.hpp>
92 #include <boost/type_traits/remove_pointer.hpp>
93 #include <boost/utility/addressof.hpp>
94 #include <afx.h> // legacy CString
95 #include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
99 namespace boost { namespace range_detail_microsoft {
102 // mfc_ptr_array_iterator
104 // 'void **' is not convertible to 'void const **',
108 template< class ArrayT, class PtrType >
109 struct mfc_ptr_array_iterator;
111 template< class ArrayT, class PtrType >
112 struct mfc_ptr_array_iterator_super
114 typedef iterator_adaptor<
115 mfc_ptr_array_iterator<ArrayT, PtrType>,
116 std::ptrdiff_t, // Base!
118 random_access_traversal_tag,
120 std::ptrdiff_t // Difference
124 template< class ArrayT, class PtrType >
125 struct mfc_ptr_array_iterator :
126 mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
129 typedef mfc_ptr_array_iterator self_t;
130 typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
131 typedef typename super_t::reference ref_t;
134 explicit mfc_ptr_array_iterator()
137 explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
138 super_t(index), m_parr(boost::addressof(arr))
141 template< class, class > friend struct mfc_ptr_array_iterator;
142 template< class ArrayT_, class PtrType_ >
143 mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
144 super_t(other.base()), m_parr(other.m_parr)
150 friend class iterator_core_access;
151 ref_t dereference() const
153 BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
154 return *( m_parr->GetData() + this->base() );
157 bool equal(self_t const& other) const
159 BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
160 return this->base() == other.base();
164 struct mfc_ptr_array_functions
166 template< class Iterator, class X >
169 return Iterator(x, 0);
172 template< class Iterator, class X >
175 return Iterator(x, x.GetSize());
184 struct customization< ::CByteArray > :
192 typedef val_t *mutable_iterator;
193 typedef val_t const *const_iterator;
199 struct customization< ::CDWordArray > :
207 typedef val_t *mutable_iterator;
208 typedef val_t const *const_iterator;
214 struct customization< ::CObArray > :
215 mfc_ptr_array_functions
220 typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
221 typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
227 struct customization< ::CPtrArray > :
228 mfc_ptr_array_functions
233 typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
234 typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
240 struct customization< ::CStringArray > :
246 typedef ::CString val_t;
248 typedef val_t *mutable_iterator;
249 typedef val_t const *const_iterator;
255 struct customization< ::CUIntArray > :
263 typedef val_t *mutable_iterator;
264 typedef val_t const *const_iterator;
270 struct customization< ::CWordArray > :
278 typedef val_t *mutable_iterator;
279 typedef val_t const *const_iterator;
288 struct customization< ::CObList > :
294 typedef list_iterator<X, ::CObject *> mutable_iterator;
295 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
296 typedef list_iterator<X const, ::CObject const *> const_iterator;
298 typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
305 struct customization< ::CPtrList > :
311 typedef list_iterator<X, void *> mutable_iterator;
312 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
313 typedef list_iterator<X const, void const *> const_iterator;
315 typedef list_iterator<X const, void const * const, void const * const> const_iterator;
322 struct customization< ::CStringList > :
328 typedef ::CString val_t;
330 typedef list_iterator<X, val_t> mutable_iterator;
331 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
332 typedef list_iterator<X const, val_t const> const_iterator;
334 typedef list_iterator<X const, val_t const, val_t const> const_iterator;
343 template< class MapT, class KeyT, class MappedT >
344 struct mfc_map_iterator;
346 template< class MapT, class KeyT, class MappedT >
347 struct mfc_map_iterator_super
349 typedef iterator_facade<
350 mfc_map_iterator<MapT, KeyT, MappedT>,
351 std::pair<KeyT, MappedT>,
352 forward_traversal_tag,
353 std::pair<KeyT, MappedT> const
357 template< class MapT, class KeyT, class MappedT >
358 struct mfc_map_iterator :
359 mfc_map_iterator_super<MapT, KeyT, MappedT>::type
362 typedef mfc_map_iterator self_t;
363 typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
364 typedef typename super_t::reference ref_t;
367 explicit mfc_map_iterator()
370 explicit mfc_map_iterator(MapT const& map, POSITION pos) :
371 m_pmap(boost::addressof(map)), m_posNext(pos)
376 explicit mfc_map_iterator(MapT const& map) :
377 m_pmap(&map), m_pos(0) // end iterator
380 template< class, class, class > friend struct mfc_map_iterator;
381 template< class MapT_, class KeyT_, class MappedT_>
382 mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
383 m_pmap(other.m_pmap),
384 m_pos(other.m_pos), m_posNext(other.m_posNext),
385 m_key(other.m_key), m_mapped(other.m_mapped)
390 POSITION m_pos, m_posNext;
391 KeyT m_key; MappedT m_mapped;
393 friend class iterator_core_access;
394 ref_t dereference() const
396 BOOST_ASSERT(m_pos != 0 && "out of range");
397 return std::make_pair(m_key, m_mapped);
402 BOOST_ASSERT(m_pos != 0 && "out of range");
404 if (m_posNext == 0) {
410 m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
413 bool equal(self_t const& other) const
415 BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
416 return m_pos == other.m_pos;
420 struct mfc_map_functions
422 template< class Iterator, class X >
425 return Iterator(x, x.GetStartPosition());
428 template< class Iterator, class X >
436 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
439 // mfc_cpair_map_iterator
441 // used by ::CMap and ::CMapStringToString
444 template< class MapT, class PairT >
445 struct mfc_cpair_map_iterator;
447 template< class MapT, class PairT >
448 struct mfc_pget_map_iterator_super
450 typedef iterator_facade<
451 mfc_cpair_map_iterator<MapT, PairT>,
453 forward_traversal_tag
457 template< class MapT, class PairT >
458 struct mfc_cpair_map_iterator :
459 mfc_pget_map_iterator_super<MapT, PairT>::type
462 typedef mfc_cpair_map_iterator self_t;
463 typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
464 typedef typename super_t::reference ref_t;
467 explicit mfc_cpair_map_iterator()
470 explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
471 m_pmap(boost::addressof(map)), m_pp(pp)
474 template< class, class > friend struct mfc_cpair_map_iterator;
475 template< class MapT_, class PairT_>
476 mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
477 m_pmap(other.m_pmap), m_pp(other.m_pp)
484 friend class iterator_core_access;
485 ref_t dereference() const
487 BOOST_ASSERT(m_pp != 0 && "out of range");
493 BOOST_ASSERT(m_pp != 0 && "out of range");
494 m_pp = m_pmap->PGetNextAssoc(m_pp);
497 bool equal(self_t const& other) const
499 BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
500 return m_pp == other.m_pp;
504 struct mfc_cpair_map_functions
506 template< class Iterator, class X >
510 // Assertion fails if empty.
511 // MFC document is wrong.
513 if (x.GetCount() == 0)
514 return Iterator(x, 0);
517 return Iterator(x, x.PGetFirstAssoc());
520 template< class Iterator, class X >
523 return Iterator(x, 0);
528 #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
535 struct customization< ::CMapPtrToWord > :
542 typedef WORD mapped_t;
544 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
545 typedef mutable_iterator const_iterator;
551 struct customization< ::CMapPtrToPtr > :
558 typedef void *mapped_t;
560 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
561 typedef mutable_iterator const_iterator;
567 struct customization< ::CMapStringToOb > :
573 typedef ::CString key_t;
574 typedef ::CObject *mapped_t;
576 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
577 typedef mutable_iterator const_iterator;
583 struct customization< ::CMapStringToPtr > :
589 typedef ::CString key_t;
590 typedef void *mapped_t;
592 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
593 typedef mutable_iterator const_iterator;
599 struct customization< ::CMapStringToString > :
600 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
601 mfc_cpair_map_functions
609 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
610 typedef typename X::CPair pair_t;
612 typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
613 typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
615 typedef ::CString key_t;
616 typedef ::CString mapped_t;
618 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
619 typedef mutable_iterator const_iterator;
626 struct customization< ::CMapWordToOb > :
633 typedef ::CObject *mapped_t;
635 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
636 typedef mutable_iterator const_iterator;
642 struct customization< ::CMapWordToPtr > :
649 typedef void *mapped_t;
651 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
652 typedef mutable_iterator const_iterator;
660 template< class Type, class ArgType >
661 struct customization< ::CArray<Type, ArgType> > :
669 typedef val_t *mutable_iterator;
670 typedef val_t const *const_iterator;
675 template< class Type, class ArgType >
676 struct customization< ::CList<Type, ArgType> > :
684 typedef list_iterator<X, val_t> mutable_iterator;
685 #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
686 typedef list_iterator<X const, val_t const> const_iterator;
688 typedef list_iterator<X const, val_t const, val_t const> const_iterator;
694 template< class Key, class ArgKey, class Mapped, class ArgMapped >
695 struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
696 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
697 mfc_cpair_map_functions
705 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
706 typedef typename X::CPair pair_t;
708 typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
709 typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
712 typedef Mapped mapped_t;
714 typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
715 typedef mutable_iterator const_iterator;
721 template< class BaseClass, class PtrType >
722 struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
727 typedef typename remove_pointer<PtrType>::type val_t;
729 typedef typename mpl::if_< is_const<X>,
734 typedef val_t_ * const result_type;
736 template< class PtrType_ >
737 result_type operator()(PtrType_ p) const
739 return static_cast<result_type>(p);
746 typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
747 typedef typename range_const_iterator<BaseClass>::type citer_t;
749 typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
750 typedef transform_iterator<fun<X const>, citer_t> const_iterator;
753 template< class Iterator, class X >
756 return Iterator(boost::begin<BaseClass>(x), fun<X>());
759 template< class Iterator, class X >
762 return Iterator(boost::end<BaseClass>(x), fun<X>());
767 template< class BaseClass, class PtrType >
768 struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
774 typedef typename remove_pointer<PtrType>::type val_t;
777 typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
778 typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
783 template< class BaseClass, class KeyPtrType, class MappedPtrType >
784 struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
790 typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
791 typedef mutable_iterator const_iterator;
799 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
802 struct customization< ::CString >
807 // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
808 typedef TCHAR *mutable_iterator;
809 typedef TCHAR const *const_iterator;
812 template< class Iterator, class X >
813 typename mutable_<Iterator, X>::type begin(X& x)
815 return x.GetBuffer(0);
818 template< class Iterator, class X >
819 Iterator begin(X const& x)
824 template< class Iterator, class X >
827 return begin<Iterator>(x) + x.GetLength();
831 #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
834 } } // namespace boost::range_detail_microsoft
839 // range customizations
845 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
846 boost::range_detail_microsoft::using_type_as_tag,
847 BOOST_PP_NIL, CByteArray
850 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
851 boost::range_detail_microsoft::using_type_as_tag,
852 BOOST_PP_NIL, CDWordArray
855 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
856 boost::range_detail_microsoft::using_type_as_tag,
857 BOOST_PP_NIL, CStringArray
860 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
861 boost::range_detail_microsoft::using_type_as_tag,
862 BOOST_PP_NIL, CUIntArray
865 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
866 boost::range_detail_microsoft::using_type_as_tag,
867 BOOST_PP_NIL, CWordArray
873 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
874 boost::range_detail_microsoft::using_type_as_tag,
875 BOOST_PP_NIL, CObList
878 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
879 boost::range_detail_microsoft::using_type_as_tag,
880 BOOST_PP_NIL, CPtrList
883 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
884 boost::range_detail_microsoft::using_type_as_tag,
885 BOOST_PP_NIL, CStringList
888 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
889 boost::range_detail_microsoft::using_type_as_tag,
890 BOOST_PP_NIL, CObArray
893 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
894 boost::range_detail_microsoft::using_type_as_tag,
895 BOOST_PP_NIL, CPtrArray
901 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
902 boost::range_detail_microsoft::using_type_as_tag,
903 BOOST_PP_NIL, CMapPtrToWord
906 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
907 boost::range_detail_microsoft::using_type_as_tag,
908 BOOST_PP_NIL, CMapPtrToPtr
911 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
912 boost::range_detail_microsoft::using_type_as_tag,
913 BOOST_PP_NIL, CMapStringToOb
916 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
917 boost::range_detail_microsoft::using_type_as_tag,
918 BOOST_PP_NIL, CMapStringToPtr
921 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
922 boost::range_detail_microsoft::using_type_as_tag,
923 BOOST_PP_NIL, CMapStringToString
926 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
927 boost::range_detail_microsoft::using_type_as_tag,
928 BOOST_PP_NIL, CMapWordToOb
931 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
932 boost::range_detail_microsoft::using_type_as_tag,
933 BOOST_PP_NIL, CMapWordToPtr
939 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
940 boost::range_detail_microsoft::using_type_as_tag,
941 BOOST_PP_NIL, CArray, 2
944 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
945 boost::range_detail_microsoft::using_type_as_tag,
946 BOOST_PP_NIL, CList, 2
949 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
950 boost::range_detail_microsoft::using_type_as_tag,
951 BOOST_PP_NIL, CMap, 4
954 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
955 boost::range_detail_microsoft::using_type_as_tag,
956 BOOST_PP_NIL, CTypedPtrArray, 2
959 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
960 boost::range_detail_microsoft::using_type_as_tag,
961 BOOST_PP_NIL, CTypedPtrList, 2
964 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
965 boost::range_detail_microsoft::using_type_as_tag,
966 BOOST_PP_NIL, CTypedPtrMap, 3
972 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
974 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
975 boost::range_detail_microsoft::using_type_as_tag,
976 BOOST_PP_NIL, CString