1 #ifndef BOOST_RANGE_ATL_HPP
2 #define BOOST_RANGE_ATL_HPP
3 
4 
5 
6 
7 // Boost.Range ATL 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 <atldef.h> // _ATL_VER
22 
23 
24 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
25     #if (_ATL_VER < 0x0700)
26         #define BOOST_RANGE_ATL_NO_COLLECTIONS
27     #endif
28 #endif
29 
30 
31 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
32     #if (_ATL_VER < 0x0700) // dubious
33         #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX
34     #endif
35 #endif
36 
37 
38 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
39     #if (_MSC_VER < 1310)   // from <boost/regex/mfc.hpp>, but dubious
40         #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING
41     #endif
42 #endif
43 
44 
45 
46 
47 // forward declarations
48 //
49 
50 
51 #include <basetyps.h> // IID
52 
53 
54 namespace ATL {
55 
56 
57 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
58 
59 
60     // arrays
61     //
62     template< class E, class ETraits >
63     class CAtlArray;
64 
65     template< class E >
66     class CAutoPtrArray;
67 
68     template< class I, const IID *piid >
69     class CInterfaceArray;
70 
71 
72     // lists
73     //
74     template< class E, class ETraits >
75     class CAtlList;
76 
77     template< class E >
78     class CAutoPtrList;
79 
80     template< class E, class Allocator >
81     class CHeapPtrList;
82 
83     template< class I, const IID *piid >
84     class CInterfaceList;
85 
86 
87     // maps
88     //
89     template< class K, class V, class KTraits, class VTraits >
90     class CAtlMap;
91 
92     template< class K, class V, class KTraits, class VTraits >
93     class CRBTree;
94 
95     template< class K, class V, class KTraits, class VTraits >
96     class CRBMap;
97 
98     template< class K, class V, class KTraits, class VTraits >
99     class CRBMultiMap;
100 
101 
102     // strings
103     //
104 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
105     template< class BaseType, bool t_bMFCDLL >
106     class CSimpleStringT;
107 #else
108     template< class BaseType >
109     class CSimpleStringT;
110 #endif
111 
112     template< class BaseType, class StringTraits >
113     class CStringT;
114 
115     template< class StringType, int t_nChars >
116     class CFixedStringT;
117 
118     template< class BaseType, const int t_nSize >
119     class CStaticString;
120 
121 
122 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
123 
124 
125     // simples
126     //
127 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
128 
129     template< class T, class TEqual >
130     class CSimpleArray;
131 
132     template< class TKey, class TVal, class TEqual >
133     class CSimpleMap;
134 
135 #else
136 
137     template< class T >
138     class CSimpleArray;
139 
140     template< class T >
141     class CSimpleValArray;
142 
143     template< class TKey, class TVal >
144     class CSimpleMap;
145 
146 #endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
147 
148 
149     // pointers
150     //
151     template< class E >
152     class CAutoPtr;
153 
154     template< class T >
155     class CComPtr;
156 
157     template< class T, const IID *piid >
158     class CComQIPtr;
159 
160     template< class E, class Allocator >
161     class CHeapPtr;
162 
163     template< class T >
164     class CAdapt;
165 
166 
167 } // namespace ATL
168 
169 
170 
171 
172 // indirect_iterator customizations
173 //
174 
175 
176 #include <boost/mpl/identity.hpp>
177 #include <boost/pointee.hpp>
178 
179 
180 namespace boost {
181 
182 
183     template< class E >
184     struct pointee< ATL::CAutoPtr<E> > :
185         mpl::identity<E>
186     { };
187 
188     template< class T >
189     struct pointee< ATL::CComPtr<T> > :
190         mpl::identity<T>
191     { };
192 
193     template< class T, const IID *piid >
194     struct pointee< ATL::CComQIPtr<T, piid> > :
195         mpl::identity<T>
196     { };
197 
198     template< class E, class Allocator >
199     struct pointee< ATL::CHeapPtr<E, Allocator> > :
200         mpl::identity<E>
201     { };
202 
203     template< class T >
204     struct pointee< ATL::CAdapt<T> > :
205         pointee<T>
206     { };
207 
208 
209 } // namespace boost
210 
211 
212 
213 
214 // extended customizations
215 //
216 
217 
218 #include <boost/iterator/indirect_iterator.hpp>
219 #include <boost/iterator/zip_iterator.hpp>
220 #include <boost/range/detail/microsoft.hpp>
221 #include <boost/tuple/tuple.hpp>
222 #include <atlbase.h> // CComBSTR
223 
224 
225 namespace boost { namespace range_detail_microsoft {
226 
227 
228 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
229 
230 
231     // arrays
232     //
233 
234     struct atl_array_functions :
235         array_functions
236     {
237         template< class Iterator, class X >
238         Iterator end(X& x) // redefine
239         {
240             return x.GetData() + x.GetCount(); // no 'GetSize()'
241         }
242     };
243 
244 
245     template< class E, class ETraits >
246     struct customization< ATL::CAtlArray<E, ETraits> > :
247         atl_array_functions
248     {
249         template< class X >
250         struct meta
251         {
252             typedef E val_t;
253 
254             typedef val_t *mutable_iterator;
255             typedef val_t const *const_iterator;
256         };
257     };
258 
259 
260     template< class E >
261     struct customization< ATL::CAutoPtrArray<E> > :
262         atl_array_functions
263     {
264         template< class X >
265         struct meta
266         {
267             // ATL::CAutoPtr/CHeapPtr is no assignable.
268             typedef ATL::CAutoPtr<E> val_t;
269             typedef val_t *miter_t;
270             typedef val_t const *citer_t;
271 
272             typedef indirect_iterator<miter_t> mutable_iterator;
273             typedef indirect_iterator<citer_t> const_iterator;
274         };
275     };
276 
277 
278     template< class I, const IID *piid >
279     struct customization< ATL::CInterfaceArray<I, piid> > :
280         atl_array_functions
281     {
282         template< class X >
283         struct meta
284         {
285             typedef ATL::CComQIPtr<I, piid> val_t;
286 
287             typedef val_t *mutable_iterator;
288             typedef val_t const *const_iterator;
289         };
290     };
291 
292 
293     template< class E, class ETraits >
294     struct customization< ATL::CAtlList<E, ETraits> > :
295         list_functions
296     {
297         template< class X >
298         struct meta
299         {
300             typedef E val_t;
301 
302             typedef list_iterator<X, val_t> mutable_iterator;
303             typedef list_iterator<X const, val_t const> const_iterator;
304         };
305     };
306 
307 
308     struct indirected_list_functions
309     {
310         template< class Iterator, class X >
311         Iterator begin(X& x)
312         {
313             typedef typename Iterator::base_type base_t; // == list_iterator
314             return Iterator(base_t(x, x.GetHeadPosition()));
315         }
316 
317         template< class Iterator, class X >
318         Iterator end(X& x)
319         {
320             typedef typename Iterator::base_type base_t;
321             return Iterator(base_t(x, POSITION(0)));
322         }
323     };
324 
325 
326     template< class E >
327     struct customization< ATL::CAutoPtrList<E> > :
328         indirected_list_functions
329     {
330         template< class X >
331         struct meta
332         {
333             typedef ATL::CAutoPtr<E> val_t;
334             typedef list_iterator<X, val_t> miter_t;
335             typedef list_iterator<X const, val_t const> citer_t;
336 
337             typedef indirect_iterator<miter_t> mutable_iterator;
338             typedef indirect_iterator<citer_t> const_iterator;
339         };
340     };
341 
342 
343     template< class E, class Allocator >
344     struct customization< ATL::CHeapPtrList<E, Allocator> > :
345         indirected_list_functions
346     {
347         template< class X >
348         struct meta
349         {
350             typedef ATL::CHeapPtr<E, Allocator> val_t;
351             typedef list_iterator<X, val_t> miter_t;
352             typedef list_iterator<X const, val_t const> citer_t;
353 
354             typedef indirect_iterator<miter_t> mutable_iterator;
355             typedef indirect_iterator<citer_t> const_iterator;
356         };
357     };
358 
359 
360     template< class I, const IID *piid >
361     struct customization< ATL::CInterfaceList<I, piid> > :
362         list_functions
363     {
364         template< class X >
365         struct meta
366         {
367             typedef ATL::CComQIPtr<I, piid> val_t;
368 
369             typedef list_iterator<X, val_t> mutable_iterator;
370             typedef list_iterator<X const, val_t const> const_iterator;
371         };
372     };
373 
374 
375     // maps
376     //
377 
378     struct atl_rb_tree_tag
379     { };
380 
381     template< >
382     struct customization< atl_rb_tree_tag > :
383         indirected_list_functions
384     {
385         template< class X >
386         struct meta
387         {
388             typedef typename X::CPair val_t;
389 
390             typedef list_iterator<X, val_t *, val_t *> miter_t;
391             typedef list_iterator<X const, val_t const *, val_t const *> citer_t;
392 
393             typedef indirect_iterator<miter_t> mutable_iterator;
394             typedef indirect_iterator<citer_t> const_iterator;
395         };
396     };
397 
398 
399     template< class K, class V, class KTraits, class VTraits >
400     struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > :
401         customization< atl_rb_tree_tag >
402     {
403         template< class Iterator, class X >
404         Iterator begin(X& x) // redefine
405         {
406             typedef typename Iterator::base_type base_t; // == list_iterator
407             return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition'
408         }
409     };
410 
411 
412     // strings
413     //
414 
415     struct atl_string_tag
416     { };
417 
418     template< >
419     struct customization< atl_string_tag >
420     {
421         template< class X >
422         struct meta
423         {
424             typedef typename X::PXSTR mutable_iterator;
425             typedef typename X::PCXSTR const_iterator;
426         };
427 
428         template< class Iterator, class X >
beginboost::range_detail_microsoft::customization429         typename mutable_<Iterator, X>::type begin(X& x)
430         {
431             return x.GetBuffer(0);
432         }
433 
434         template< class Iterator, class X >
435         Iterator begin(X const& x)
436         {
437             return x.GetString();
438         }
439 
440         template< class Iterator, class X >
441         Iterator end(X& x)
442         {
443             return begin<Iterator>(x) + x.GetLength();
444         }
445     };
446 
447 
448     template< class BaseType, const int t_nSize >
449     struct customization< ATL::CStaticString<BaseType, t_nSize> >
450     {
451         template< class X >
452         struct meta
453         {
454             typedef BaseType const *mutable_iterator;
455             typedef mutable_iterator const_iterator;
456         };
457 
458         template< class Iterator, class X >
459         Iterator begin(X const& x)
460         {
461             return x;
462         }
463 
464         template< class Iterator, class X >
465         Iterator end(X const& x)
466         {
467             return begin<Iterator>(x) + X::GetLength();
468         }
469     };
470 
471 
472 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
473 
474 
475     template< >
476     struct customization< ATL::CComBSTR >
477     {
478         template< class X >
479         struct meta
480         {
481             typedef OLECHAR *mutable_iterator;
482             typedef OLECHAR const *const_iterator;
483         };
484 
485         template< class Iterator, class X >
486         Iterator begin(X& x)
487         {
488             return x.operator BSTR();
489         }
490 
491         template< class Iterator, class X >
492         Iterator end(X& x)
493         {
494             return begin<Iterator>(x) + x.Length();
495         }
496     };
497 
498 
499     // simples
500     //
501 
502 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
503     template< class T, class TEqual >
504     struct customization< ATL::CSimpleArray<T, TEqual> > :
505 #else
506     template< class T >
507     struct customization< ATL::CSimpleArray<T> > :
508 #endif
509         array_functions
510     {
511         template< class X >
512         struct meta
513         {
514             typedef T val_t;
515 
516             typedef val_t *mutable_iterator;
517             typedef val_t const *const_iterator;
518         };
519     };
520 
521 
522 #if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
523 
524     template< class T >
525     struct customization< ATL::CSimpleValArray<T> > :
526         array_functions
527     {
528         template< class X >
529         struct meta
530         {
531             typedef T val_t;
532 
533             typedef val_t *mutable_iterator;
534             typedef val_t const *const_iterator;
535         };
536     };
537 
538 #endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
539 
540 
541 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
542     template< class TKey, class TVal, class TEqual >
543     struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> >
544 #else
545     template< class TKey, class TVal >
546     struct customization< ATL::CSimpleMap<TKey, TVal> >
547 #endif
548     {
549         template< class X >
550         struct meta
551         {
552             typedef TKey k_val_t;
553             typedef k_val_t *k_miter_t;
554             typedef k_val_t const *k_citer_t;
555 
556             typedef TVal v_val_t;
557             typedef v_val_t *v_miter_t;
558             typedef v_val_t const *v_citer_t;
559 
560             // Topic:
561             // 'std::pair' can't contain references
562             // because of reference to reference problem.
563 
564             typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator;
565             typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator;
566         };
567 
568         template< class Iterator, class X >
569         Iterator begin(X& x)
570         {
571             return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal));
572         }
573 
574         template< class Iterator, class X >
575         Iterator end(X& x)
576         {
577             return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize()));
578         }
579     };
580 
581 
582 } } // namespace boost::range_detail_microsoft
583 
584 
585 
586 
587 // range customizations
588 //
589 
590 
591 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
592 
593 
594     // arrays
595     //
596     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
597         boost::range_detail_microsoft::using_type_as_tag,
598         (ATL, BOOST_PP_NIL), CAtlArray, 2
599     )
600 
601     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
602         boost::range_detail_microsoft::using_type_as_tag,
603         (ATL, BOOST_PP_NIL), CAutoPtrArray, 1
604     )
605 
606     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
607         boost::range_detail_microsoft::using_type_as_tag,
608         (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *)
609     )
610 
611 
612     // lists
613     //
614     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
615         boost::range_detail_microsoft::using_type_as_tag,
616         (ATL, BOOST_PP_NIL), CAtlList, 2
617     )
618 
619     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
620         boost::range_detail_microsoft::using_type_as_tag,
621         (ATL, BOOST_PP_NIL), CAutoPtrList, 1
622     )
623 
624     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
625         boost::range_detail_microsoft::using_type_as_tag,
626         (ATL, BOOST_PP_NIL), CHeapPtrList, 2
627     )
628 
629     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
630         boost::range_detail_microsoft::using_type_as_tag,
631         (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *)
632     )
633 
634 
635     //maps
636     //
637     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
638         boost::range_detail_microsoft::using_type_as_tag,
639         (ATL, BOOST_PP_NIL), CAtlMap, 4
640     )
641 
642     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
643         boost::range_detail_microsoft::atl_rb_tree_tag,
644         (ATL, BOOST_PP_NIL), CRBTree, 4
645     )
646 
647     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
648         boost::range_detail_microsoft::atl_rb_tree_tag,
649         (ATL, BOOST_PP_NIL), CRBMap, 4
650     )
651 
652     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
653         boost::range_detail_microsoft::atl_rb_tree_tag,
654         (ATL, BOOST_PP_NIL), CRBMultiMap, 4
655     )
656 
657 
658     // strings
659     //
660     #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
661         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
662             boost::range_detail_microsoft::atl_string_tag,
663             (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool)
664         )
665     #else
666         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
667             boost::range_detail_microsoft::atl_string_tag,
668             (ATL, BOOST_PP_NIL), CSimpleStringT, 1
669         )
670     #endif
671 
672     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
673         boost::range_detail_microsoft::atl_string_tag,
674         (ATL, BOOST_PP_NIL), CStringT, 2
675     )
676 
677     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
678         boost::range_detail_microsoft::atl_string_tag,
679         (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int)
680     )
681 
682     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
683         boost::range_detail_microsoft::using_type_as_tag,
684         (ATL, BOOST_PP_NIL), CStaticString, (class)(const int)
685     )
686 
687 
688 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
689 
690 
691 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
692     boost::range_detail_microsoft::using_type_as_tag,
693     (ATL, BOOST_PP_NIL), CComBSTR
694 )
695 
696 
697 // simples
698 //
699 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
700 
701     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
702         boost::range_detail_microsoft::using_type_as_tag,
703         (ATL, BOOST_PP_NIL), CSimpleArray, 2
704     )
705 
706     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
707         boost::range_detail_microsoft::using_type_as_tag,
708         (ATL, BOOST_PP_NIL), CSimpleMap, 3
709     )
710 
711 #else
712 
713     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
714         boost::range_detail_microsoft::using_type_as_tag,
715         (ATL, BOOST_PP_NIL), CSimpleArray, 1
716     )
717 
718     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
719         boost::range_detail_microsoft::using_type_as_tag,
720         (ATL, BOOST_PP_NIL), CSimpleMap, 2
721     )
722 
723     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
724         boost::range_detail_microsoft::using_type_as_tag,
725         (ATL, BOOST_PP_NIL), CSimpleValArray, 1
726     )
727 
728 #endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
729 
730 
731 
732 
733 #endif
734