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