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