1 #ifndef BOOST_RANGE_MFC_HPP
2 #define BOOST_RANGE_MFC_HPP
3 
4 
5 
6 
7 // Boost.Range MFC Extension
8 //
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)
13 
14 
15 
16 
17 // config
18 //
19 
20 
21 #include <afx.h> // _MFC_VER
22 
23 
24 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
25     #if (_MFC_VER < 0x0700) // dubious
26         #define BOOST_RANGE_MFC_NO_CPAIR
27     #endif
28 #endif
29 
30 
31 #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
32     #if (_MFC_VER < 0x0700) // dubious
33         #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
34     #endif
35 #endif
36 
37 
38 // A const collection of old MFC doesn't return const reference.
39 //
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
43     #endif
44 #endif
45 
46 
47 
48 
49 // forward declarations
50 //
51 
52 
53 template< class Type, class ArgType >
54 class CArray;
55 
56 template< class Type, class ArgType >
57 class CList;
58 
59 template< class Key, class ArgKey, class Mapped, class ArgMapped >
60 class CMap;
61 
62 template< class BaseClass, class PtrType >
63 class CTypedPtrArray;
64 
65 template< class BaseClass, class PtrType >
66 class CTypedPtrList;
67 
68 template< class BaseClass, class KeyPtrType, class MappedPtrType >
69 class CTypedPtrMap;
70 
71 
72 
73 
74 // extended customizations
75 //
76 
77 
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
96 #include <tchar.h>
97 
98 
99 namespace boost { namespace range_detail_microsoft {
100 
101 
102     // mfc_ptr_array_iterator
103     //
104     // 'void **' is not convertible to 'void const **',
105     // so we define...
106     //
107 
108     template< class ArrayT, class PtrType >
109     struct mfc_ptr_array_iterator;
110 
111     template< class ArrayT, class PtrType >
112     struct mfc_ptr_array_iterator_super
113     {
114         typedef iterator_adaptor<
115             mfc_ptr_array_iterator<ArrayT, PtrType>,
116             std::ptrdiff_t, // Base!
117             PtrType,        // Value
118             random_access_traversal_tag,
119             use_default,
120             std::ptrdiff_t  // Difference
121         > type;
122     };
123 
124     template< class ArrayT, class PtrType >
125     struct mfc_ptr_array_iterator :
126         mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
127     {
128     private:
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;
132 
133     public:
mfc_ptr_array_iteratorboost::range_detail_microsoft::mfc_ptr_array_iterator134         explicit mfc_ptr_array_iterator()
135         { }
136 
mfc_ptr_array_iteratorboost::range_detail_microsoft::mfc_ptr_array_iterator137         explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
138             super_t(index), m_parr(boost::addressof(arr))
139         { }
140 
141     template< class, class > friend struct mfc_ptr_array_iterator;
142         template< class ArrayT_, class PtrType_ >
mfc_ptr_array_iteratorboost::range_detail_microsoft::mfc_ptr_array_iterator143         mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
144             super_t(other.base()), m_parr(other.m_parr)
145         { }
146 
147     private:
148         ArrayT *m_parr;
149 
150     friend class iterator_core_access;
dereferenceboost::range_detail_microsoft::mfc_ptr_array_iterator151         ref_t dereference() const
152         {
153             BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
154             return *( m_parr->GetData() + this->base() );
155         }
156 
equalboost::range_detail_microsoft::mfc_ptr_array_iterator157         bool equal(self_t const& other) const
158         {
159             BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
160             return this->base() == other.base();
161         }
162     };
163 
164     struct mfc_ptr_array_functions
165     {
166         template< class Iterator, class X >
167         Iterator begin(X& x)
168         {
169             return Iterator(x, 0);
170         }
171 
172         template< class Iterator, class X >
173         Iterator end(X& x)
174         {
175             return Iterator(x, x.GetSize());
176         }
177     };
178 
179 
180     // arrays
181     //
182 
183     template< >
184     struct customization< ::CByteArray > :
185         array_functions
186     {
187         template< class X >
188         struct meta
189         {
190             typedef BYTE val_t;
191 
192             typedef val_t *mutable_iterator;
193             typedef val_t const *const_iterator;
194         };
195     };
196 
197 
198     template< >
199     struct customization< ::CDWordArray > :
200         array_functions
201     {
202         template< class X >
203         struct meta
204         {
205             typedef DWORD val_t;
206 
207             typedef val_t *mutable_iterator;
208             typedef val_t const *const_iterator;
209         };
210     };
211 
212 
213     template< >
214     struct customization< ::CObArray > :
215         mfc_ptr_array_functions
216     {
217         template< class X >
218         struct meta
219         {
220             typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
221             typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
222         };
223     };
224 
225 
226     template< >
227     struct customization< ::CPtrArray > :
228         mfc_ptr_array_functions
229     {
230         template< class X >
231         struct meta
232         {
233             typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
234             typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
235         };
236     };
237 
238 
239     template< >
240     struct customization< ::CStringArray > :
241         array_functions
242     {
243         template< class X >
244         struct meta
245         {
246             typedef ::CString val_t;
247 
248             typedef val_t *mutable_iterator;
249             typedef val_t const *const_iterator;
250         };
251     };
252 
253 
254     template< >
255     struct customization< ::CUIntArray > :
256         array_functions
257     {
258         template< class X >
259         struct meta
260         {
261             typedef UINT val_t;
262 
263             typedef val_t *mutable_iterator;
264             typedef val_t const *const_iterator;
265         };
266     };
267 
268 
269     template< >
270     struct customization< ::CWordArray > :
271         array_functions
272     {
273         template< class X >
274         struct meta
275         {
276             typedef WORD val_t;
277 
278             typedef val_t *mutable_iterator;
279             typedef val_t const *const_iterator;
280         };
281     };
282 
283 
284     // lists
285     //
286 
287     template< >
288     struct customization< ::CObList > :
289         list_functions
290     {
291         template< class X >
292         struct meta
293         {
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;
297     #else
298             typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
299     #endif
300         };
301     };
302 
303 
304     template< >
305     struct customization< ::CPtrList > :
306         list_functions
307     {
308         template< class X >
309         struct meta
310         {
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;
314     #else
315             typedef list_iterator<X const, void const * const, void const * const> const_iterator;
316     #endif
317         };
318     };
319 
320 
321     template< >
322     struct customization< ::CStringList > :
323         list_functions
324     {
325         template< class X >
326         struct meta
327         {
328             typedef ::CString val_t;
329 
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;
333     #else
334             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
335     #endif
336         };
337     };
338 
339 
340     // mfc_map_iterator
341     //
342 
343     template< class MapT, class KeyT, class MappedT >
344     struct mfc_map_iterator;
345 
346     template< class MapT, class KeyT, class MappedT >
347     struct mfc_map_iterator_super
348     {
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
354         > type;
355     };
356 
357     template< class MapT, class KeyT, class MappedT >
358     struct mfc_map_iterator :
359         mfc_map_iterator_super<MapT, KeyT, MappedT>::type
360     {
361     private:
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;
365 
366     public:
mfc_map_iteratorboost::range_detail_microsoft::mfc_map_iterator367         explicit mfc_map_iterator()
368         { }
369 
mfc_map_iteratorboost::range_detail_microsoft::mfc_map_iterator370         explicit mfc_map_iterator(MapT const& map, POSITION pos) :
371             m_pmap(boost::addressof(map)), m_posNext(pos)
372         {
373             increment();
374         }
375 
mfc_map_iteratorboost::range_detail_microsoft::mfc_map_iterator376         explicit mfc_map_iterator(MapT const& map) :
377             m_pmap(&map), m_pos(0) // end iterator
378         { }
379 
380     template< class, class, class > friend struct mfc_map_iterator;
381         template< class MapT_, class KeyT_, class MappedT_>
mfc_map_iteratorboost::range_detail_microsoft::mfc_map_iterator382         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)
386         { }
387 
388     private:
389         MapT const *m_pmap;
390         POSITION m_pos, m_posNext;
391         KeyT m_key; MappedT m_mapped;
392 
393     friend class iterator_core_access;
dereferenceboost::range_detail_microsoft::mfc_map_iterator394         ref_t dereference() const
395         {
396             BOOST_ASSERT(m_pos != 0 && "out of range");
397             return std::make_pair(m_key, m_mapped);
398         }
399 
incrementboost::range_detail_microsoft::mfc_map_iterator400         void increment()
401         {
402             BOOST_ASSERT(m_pos != 0 && "out of range");
403 
404             if (m_posNext == 0) {
405                 m_pos = 0;
406                 return;
407             }
408 
409             m_pos = m_posNext;
410             m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
411         }
412 
equalboost::range_detail_microsoft::mfc_map_iterator413         bool equal(self_t const& other) const
414         {
415             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
416             return m_pos == other.m_pos;
417         }
418     };
419 
420     struct mfc_map_functions
421     {
422         template< class Iterator, class X >
423         Iterator begin(X& x)
424         {
425             return Iterator(x, x.GetStartPosition());
426         }
427 
428         template< class Iterator, class X >
429         Iterator end(X& x)
430         {
431             return Iterator(x);
432         }
433     };
434 
435 
436 #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
437 
438 
439     // mfc_cpair_map_iterator
440     //
441     // used by ::CMap and ::CMapStringToString
442     //
443 
444     template< class MapT, class PairT >
445     struct mfc_cpair_map_iterator;
446 
447     template< class MapT, class PairT >
448     struct mfc_pget_map_iterator_super
449     {
450         typedef iterator_facade<
451             mfc_cpair_map_iterator<MapT, PairT>,
452             PairT,
453             forward_traversal_tag
454         > type;
455     };
456 
457     template< class MapT, class PairT >
458     struct mfc_cpair_map_iterator :
459         mfc_pget_map_iterator_super<MapT, PairT>::type
460     {
461     private:
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;
465 
466     public:
mfc_cpair_map_iteratorboost::range_detail_microsoft::mfc_cpair_map_iterator467         explicit mfc_cpair_map_iterator()
468         { }
469 
mfc_cpair_map_iteratorboost::range_detail_microsoft::mfc_cpair_map_iterator470         explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
471             m_pmap(boost::addressof(map)), m_pp(pp)
472         { }
473 
474     template< class, class > friend struct mfc_cpair_map_iterator;
475         template< class MapT_, class PairT_>
mfc_cpair_map_iteratorboost::range_detail_microsoft::mfc_cpair_map_iterator476         mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
477             m_pmap(other.m_pmap), m_pp(other.m_pp)
478         { }
479 
480     private:
481         MapT  *m_pmap;
482         PairT *m_pp;
483 
484     friend class iterator_core_access;
dereferenceboost::range_detail_microsoft::mfc_cpair_map_iterator485         ref_t dereference() const
486         {
487             BOOST_ASSERT(m_pp != 0 && "out of range");
488             return *m_pp;
489         }
490 
incrementboost::range_detail_microsoft::mfc_cpair_map_iterator491         void increment()
492         {
493             BOOST_ASSERT(m_pp != 0 && "out of range");
494             m_pp = m_pmap->PGetNextAssoc(m_pp);
495         }
496 
equalboost::range_detail_microsoft::mfc_cpair_map_iterator497         bool equal(self_t const& other) const
498         {
499             BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
500             return m_pp == other.m_pp;
501         }
502     };
503 
504     struct mfc_cpair_map_functions
505     {
506         template< class Iterator, class X >
507         Iterator begin(X& x)
508         {
509             // Workaround:
510             // Assertion fails if empty.
511             // MFC document is wrong.
512     #if !defined(NDEBUG)
513             if (x.GetCount() == 0)
514                 return Iterator(x, 0);
515     #endif
516 
517             return Iterator(x, x.PGetFirstAssoc());
518         }
519 
520         template< class Iterator, class X >
521         Iterator end(X& x)
522         {
523             return Iterator(x, 0);
524         }
525     };
526 
527 
528 #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
529 
530 
531     // maps
532     //
533 
534     template< >
535     struct customization< ::CMapPtrToWord > :
536         mfc_map_functions
537     {
538         template< class X >
539         struct meta
540         {
541             typedef void *key_t;
542             typedef WORD mapped_t;
543 
544             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
545             typedef mutable_iterator const_iterator;
546         };
547     };
548 
549 
550     template< >
551     struct customization< ::CMapPtrToPtr > :
552         mfc_map_functions
553     {
554         template< class X >
555         struct meta
556         {
557             typedef void *key_t;
558             typedef void *mapped_t;
559 
560             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
561             typedef mutable_iterator const_iterator;
562         };
563     };
564 
565 
566     template< >
567     struct customization< ::CMapStringToOb > :
568         mfc_map_functions
569     {
570         template< class X >
571         struct meta
572         {
573             typedef ::CString key_t;
574             typedef ::CObject *mapped_t;
575 
576             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
577             typedef mutable_iterator const_iterator;
578         };
579     };
580 
581 
582     template< >
583     struct customization< ::CMapStringToPtr > :
584         mfc_map_functions
585     {
586         template< class X >
587         struct meta
588         {
589             typedef ::CString key_t;
590             typedef void *mapped_t;
591 
592             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
593             typedef mutable_iterator const_iterator;
594         };
595     };
596 
597 
598     template< >
599     struct customization< ::CMapStringToString > :
600     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
601         mfc_cpair_map_functions
602     #else
603         mfc_map_functions
604     #endif
605     {
606         template< class X >
607         struct meta
608         {
609     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
610             typedef typename X::CPair pair_t;
611 
612             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
613             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
614     #else
615             typedef ::CString key_t;
616             typedef ::CString mapped_t;
617 
618             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
619             typedef mutable_iterator const_iterator;
620     #endif
621         };
622     };
623 
624 
625     template< >
626     struct customization< ::CMapWordToOb > :
627         mfc_map_functions
628     {
629         template< class X >
630         struct meta
631         {
632             typedef WORD key_t;
633             typedef ::CObject *mapped_t;
634 
635             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
636             typedef mutable_iterator const_iterator;
637         };
638     };
639 
640 
641     template< >
642     struct customization< ::CMapWordToPtr > :
643         mfc_map_functions
644     {
645         template< class X >
646         struct meta
647         {
648             typedef WORD key_t;
649             typedef void *mapped_t;
650 
651             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
652             typedef mutable_iterator const_iterator;
653         };
654     };
655 
656 
657     // templates
658     //
659 
660     template< class Type, class ArgType >
661     struct customization< ::CArray<Type, ArgType> > :
662         array_functions
663     {
664         template< class X >
665         struct meta
666         {
667             typedef Type val_t;
668 
669             typedef val_t *mutable_iterator;
670             typedef val_t const *const_iterator;
671         };
672     };
673 
674 
675     template< class Type, class ArgType >
676     struct customization< ::CList<Type, ArgType> > :
677         list_functions
678     {
679         template< class X >
680         struct meta
681         {
682             typedef Type val_t;
683 
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;
687     #else
688             typedef list_iterator<X const, val_t const, val_t const> const_iterator;
689     #endif
690         };
691     };
692 
693 
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
698     #else
699         mfc_map_functions
700     #endif
701     {
702         template< class X >
703         struct meta
704         {
705     #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
706             typedef typename X::CPair pair_t;
707 
708             typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
709             typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
710     #else
711             typedef Key key_t;
712             typedef Mapped mapped_t;
713 
714             typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
715             typedef mutable_iterator const_iterator;
716     #endif
717         };
718     };
719 
720 
721     template< class BaseClass, class PtrType >
722     struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
723     {
724         template< class X >
725         struct fun
726         {
727             typedef typename remove_pointer<PtrType>::type val_t;
728 
729             typedef typename mpl::if_< is_const<X>,
730                 val_t const,
731                 val_t
732             >::type val_t_;
733 
734             typedef val_t_ * const result_type;
735 
736             template< class PtrType_ >
operator ()boost::range_detail_microsoft::customization::fun737             result_type operator()(PtrType_ p) const
738             {
739                 return static_cast<result_type>(p);
740             }
741         };
742 
743         template< class X >
744         struct meta
745         {
746             typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
747             typedef typename range_const_iterator<BaseClass>::type citer_t;
748 
749             typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
750             typedef transform_iterator<fun<X const>, citer_t> const_iterator;
751         };
752 
753         template< class Iterator, class X >
754         Iterator begin(X& x)
755         {
756             return Iterator(boost::begin<BaseClass>(x), fun<X>());
757         }
758 
759         template< class Iterator, class X >
760         Iterator end(X& x)
761         {
762             return Iterator(boost::end<BaseClass>(x), fun<X>());
763         }
764     };
765 
766 
767     template< class BaseClass, class PtrType >
768     struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
769         list_functions
770     {
771         template< class X >
772         struct meta
773         {
774             typedef typename remove_pointer<PtrType>::type val_t;
775 
776             // not l-value
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;
779         };
780     };
781 
782 
783     template< class BaseClass, class KeyPtrType, class MappedPtrType >
784     struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
785         mfc_map_functions
786     {
787         template< class X >
788         struct meta
789         {
790             typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
791             typedef mutable_iterator const_iterator;
792         };
793     };
794 
795 
796     // strings
797     //
798 
799 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
800 
801     template< >
802     struct customization< ::CString >
803     {
804         template< class X >
805         struct meta
806         {
807             // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
808             typedef TCHAR *mutable_iterator;
809             typedef TCHAR const *const_iterator;
810         };
811 
812         template< class Iterator, class X >
beginboost::range_detail_microsoft::customization813         typename mutable_<Iterator, X>::type begin(X& x)
814         {
815             return x.GetBuffer(0);
816         }
817 
818         template< class Iterator, class X >
819         Iterator begin(X const& x)
820         {
821             return x;
822         }
823 
824         template< class Iterator, class X >
825         Iterator end(X& x)
826         {
827             return begin<Iterator>(x) + x.GetLength();
828         }
829     };
830 
831 #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
832 
833 
834 } } // namespace boost::range_detail_microsoft
835 
836 
837 
838 
839 // range customizations
840 //
841 
842 
843 // arrays
844 //
845 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
846     boost::range_detail_microsoft::using_type_as_tag,
847     BOOST_PP_NIL, CByteArray
848 )
849 
850 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
851     boost::range_detail_microsoft::using_type_as_tag,
852     BOOST_PP_NIL, CDWordArray
853 )
854 
855 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
856     boost::range_detail_microsoft::using_type_as_tag,
857     BOOST_PP_NIL, CStringArray
858 )
859 
860 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
861     boost::range_detail_microsoft::using_type_as_tag,
862     BOOST_PP_NIL, CUIntArray
863 )
864 
865 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
866     boost::range_detail_microsoft::using_type_as_tag,
867     BOOST_PP_NIL, CWordArray
868 )
869 
870 
871 // lists
872 //
873 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
874     boost::range_detail_microsoft::using_type_as_tag,
875     BOOST_PP_NIL, CObList
876 )
877 
878 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
879     boost::range_detail_microsoft::using_type_as_tag,
880     BOOST_PP_NIL, CPtrList
881 )
882 
883 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
884     boost::range_detail_microsoft::using_type_as_tag,
885     BOOST_PP_NIL, CStringList
886 )
887 
888 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
889     boost::range_detail_microsoft::using_type_as_tag,
890     BOOST_PP_NIL, CObArray
891 )
892 
893 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
894     boost::range_detail_microsoft::using_type_as_tag,
895     BOOST_PP_NIL, CPtrArray
896 )
897 
898 
899 // maps
900 //
901 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
902     boost::range_detail_microsoft::using_type_as_tag,
903     BOOST_PP_NIL, CMapPtrToWord
904 )
905 
906 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
907     boost::range_detail_microsoft::using_type_as_tag,
908     BOOST_PP_NIL, CMapPtrToPtr
909 )
910 
911 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
912     boost::range_detail_microsoft::using_type_as_tag,
913     BOOST_PP_NIL, CMapStringToOb
914 )
915 
916 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
917     boost::range_detail_microsoft::using_type_as_tag,
918     BOOST_PP_NIL, CMapStringToPtr
919 )
920 
921 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
922     boost::range_detail_microsoft::using_type_as_tag,
923     BOOST_PP_NIL, CMapStringToString
924 )
925 
926 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
927     boost::range_detail_microsoft::using_type_as_tag,
928     BOOST_PP_NIL, CMapWordToOb
929 )
930 
931 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
932     boost::range_detail_microsoft::using_type_as_tag,
933     BOOST_PP_NIL, CMapWordToPtr
934 )
935 
936 
937 // templates
938 //
939 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
940     boost::range_detail_microsoft::using_type_as_tag,
941     BOOST_PP_NIL, CArray, 2
942 )
943 
944 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
945     boost::range_detail_microsoft::using_type_as_tag,
946     BOOST_PP_NIL, CList, 2
947 )
948 
949 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
950     boost::range_detail_microsoft::using_type_as_tag,
951     BOOST_PP_NIL, CMap, 4
952 )
953 
954 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
955     boost::range_detail_microsoft::using_type_as_tag,
956     BOOST_PP_NIL, CTypedPtrArray, 2
957 )
958 
959 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
960     boost::range_detail_microsoft::using_type_as_tag,
961     BOOST_PP_NIL, CTypedPtrList, 2
962 )
963 
964 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
965     boost::range_detail_microsoft::using_type_as_tag,
966     BOOST_PP_NIL, CTypedPtrMap, 3
967 )
968 
969 
970 // strings
971 //
972 #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
973 
974     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
975         boost::range_detail_microsoft::using_type_as_tag,
976         BOOST_PP_NIL, CString
977     )
978 
979 #endif
980 
981 
982 
983 
984 #endif
985