1 #ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP
2 #define BOOST_RANGE_DETAIL_MICROSOFT_HPP
3 
4 // Boost.Range MFC/ATL Extension
5 //
6 // Copyright Shunsuke Sogame 2005-2006.
7 // Distributed under the Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 
12 
13 
14 // config
15 //
16 
17 
18 #include <boost/range/iterator.hpp>
19 
20 
21 #define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1
22 
23 
24 #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
25     #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
26     #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
27     #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
28 #else
29     #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
30     #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
31     #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
32 #endif
33 
34 
35 
36 
37 // yet another customization way
38 //
39 
40 
41 #include <boost/iterator/iterator_traits.hpp> // iterator_difference
42 #include <boost/mpl/identity.hpp>
43 #include <boost/mpl/if.hpp>
44 #include <boost/preprocessor/cat.hpp>
45 #include <boost/preprocessor/control/iif.hpp>
46 #include <boost/preprocessor/comma_if.hpp>
47 #include <boost/preprocessor/detail/is_unary.hpp>
48 #include <boost/preprocessor/list/for_each.hpp>
49 #include <boost/preprocessor/repetition/enum_params.hpp>
50 #include <boost/preprocessor/repetition/repeat.hpp>
51 #include <boost/preprocessor/seq/for_each_i.hpp>
52 #include <boost/preprocessor/seq/size.hpp>
53 #include <boost/preprocessor/tuple/eat.hpp>
54 #include <boost/range/const_iterator.hpp>
55 #include <boost/range/size_type.hpp>
56 #include <boost/type_traits/is_const.hpp>
57 #include <boost/type_traits/is_same.hpp>
58 #include <boost/type_traits/remove_cv.hpp>
59 #include <boost/utility/addressof.hpp>
60 #include <boost/utility/enable_if.hpp> // disable_if
61 #include <boost/next_prior.hpp>
62 
63 #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
64     #include <boost/range/mutable_iterator.hpp>
65 #else
66     #include <iterator> // distance
67     #include <boost/range/begin.hpp>
68     #include <boost/range/end.hpp>
69     #include <boost/range/iterator.hpp>
70 #endif
71 
72 
73 namespace boost { namespace range_detail_microsoft {
74 
75 
76     // customization point
77     //
78 
79     template< class Tag >
80     struct customization;
81 
82 
83     template< class T >
84     struct customization_tag;
85 
86 
87     struct using_type_as_tag
88     { };
89 
90 
91     // Topic:
92     // In fact, it is unnecessary for VC++.
93     // VC++'s behavior seems conforming, while GCC fails without this.
94     template< class Iterator, class T >
95     struct mutable_ :
96         disable_if< is_const<T>, Iterator >
97     { };
98 
99 
100     // helpers
101     //
102 
103     template< class Tag, class T >
104     struct customization_tag_of
105     {
106         typedef typename mpl::if_< is_same<using_type_as_tag, Tag>,
107             T,
108             Tag
109         >::type type;
110     };
111 
112 
113     template< class T >
114     struct customization_of
115     {
116         typedef typename remove_cv<T>::type bare_t;
117         typedef typename customization_tag<bare_t>::type tag_t;
118         typedef customization<tag_t> type;
119     };
120 
121 
122     template< class T >
123     struct mutable_iterator_of
124     {
125         typedef typename remove_cv<T>::type bare_t;
126         typedef typename customization_of<bare_t>::type cust_t;
127         typedef typename cust_t::template meta<bare_t>::mutable_iterator type;
128     };
129 
130 
131     template< class T >
132     struct const_iterator_of
133     {
134         typedef typename remove_cv<T>::type bare_t;
135         typedef typename customization_of<bare_t>::type cust_t;
136         typedef typename cust_t::template meta<bare_t>::const_iterator type;
137     };
138 
139 
140     template< class T >
141     struct size_type_of
142     {
143         typedef typename range_detail_microsoft::mutable_iterator_of<T>::type miter_t;
144         typedef typename iterator_difference<miter_t>::type type;
145     };
146 
147 
148     template< class T > inline
149     typename mutable_iterator_of<T>::type
begin_of(T & x)150     begin_of(T& x)
151     {
152         typedef typename customization_of<T>::type cust_t;
153         return cust_t().template begin<typename mutable_iterator_of<T>::type>(x);
154     }
155 
156 
157     template< class T > inline
158     typename const_iterator_of<T>::type
begin_of(T const & x)159     begin_of(T const& x)
160     {
161         typedef typename customization_of<T>::type cust_t;
162         return cust_t().template begin<typename const_iterator_of<T>::type>(x);
163     }
164 
165 
166     template< class T > inline
167     typename mutable_iterator_of<T>::type
end_of(T & x)168     end_of(T& x)
169     {
170         typedef typename customization_of<T>::type cust_t;
171         return cust_t().template end<typename mutable_iterator_of<T>::type>(x);
172     }
173 
174 
175     template< class T > inline
176     typename const_iterator_of<T>::type
end_of(T const & x)177     end_of(T const& x)
178     {
179         typedef typename customization_of<T>::type cust_t;
180         return cust_t().template end<typename const_iterator_of<T>::type>(x);
181     }
182 
183 
184 #if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
185 
186     template< class T > inline
187     typename size_type_of<T>::type
size_of(T const & x)188     size_of(T const& x)
189     {
190         return std::distance(boost::begin(x), boost::end(x));
191     }
192 
193 #endif
194 
195 
196     template< class Range >
197     struct compatible_mutable_iterator :
198         BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>
199     { };
200 
201 
202 } } // namespace boost::range_detail_microsoft
203 
204 
205 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
206     BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \
207 /**/
208 
209     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \
210         namespace elem { \
211     /**/
212 
213 
214 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
215     BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \
216 /**/
217 
218     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \
219         } \
220     /**/
221 
222 
223 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \
224     :: elem \
225 /**/
226 
227 
228 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \
229     namespace boost { namespace range_detail_microsoft { \
230         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
231     } } \
232     \
233     namespace boost { \
234         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
235         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
236         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
237     } \
238     \
239     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
240         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
241         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
242         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
243         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
244         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
245     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
246 /**/
247 
248 
249     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \
250         BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \
251     /**/
252 
253 
254     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \
255         template< > \
256         struct customization_tag< Fullname > : \
257             customization_tag_of< Tag, Fullname > \
258         { }; \
259     /**/
260 
261 
262     // metafunctions
263     //
264 
265     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \
266         template< > \
267         struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
268             range_detail_microsoft::mutable_iterator_of< Fullname > \
269         { }; \
270     /**/
271 
272 
273     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \
274         template< > \
275         struct range_const_iterator< Fullname > : \
276             range_detail_microsoft::const_iterator_of< Fullname > \
277         { }; \
278     /**/
279 
280 
281     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \
282         template< > \
283         struct range_size< Fullname > : \
284             range_detail_microsoft::size_type_of< Fullname > \
285         { }; \
286     /**/
287 
288 
289     // functions
290     //
291 
292     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \
293         inline \
294         boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
295         BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
296         { \
297             return boost::range_detail_microsoft::begin_of(x); \
298         } \
299     /**/
300 
301 
302     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \
303         inline \
304         boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
305         BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
306         { \
307             return boost::range_detail_microsoft::begin_of(x); \
308         } \
309     /**/
310 
311 
312     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \
313         inline \
314         boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
315         BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
316         { \
317             return boost::range_detail_microsoft::end_of(x); \
318         } \
319     /**/
320 
321 
322     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \
323         inline \
324         boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
325         BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
326         { \
327             return boost::range_detail_microsoft::end_of(x); \
328         } \
329     /**/
330 
331 
332     #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
333 
334         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
335         /**/
336 
337     #else
338 
339         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
340             inline \
341             boost::range_detail_microsoft::size_type_of< Fullname >::type \
342             boost_range_size(Fullname const& x) \
343             { \
344                 return boost::range_detail_microsoft::size_of(x); \
345             } \
346         /**/
347 
348     #endif
349 
350 
351 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \
352     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \
353         Tag, NamespaceList, Name, \
354         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
355     ) \
356 /**/
357 
358     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
359         BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \
360             ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \
361             BOOST_PP_REPEAT \
362         )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \
363     /**/
364 
365         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \
366             (class) \
367         /**/
368 
369 
370 #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \
371     namespace boost { namespace range_detail_microsoft { \
372             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \
373             Tag, \
374             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
375             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
376         ) \
377     } } \
378     \
379     namespace boost { \
380         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \
381             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
382             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
383         ) \
384         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \
385             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
386             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
387         ) \
388         \
389         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \
390             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
391             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
392         ) \
393     } \
394     \
395     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
396         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \
397             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
398             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
399         ) \
400         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \
401             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
402             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
403         ) \
404         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \
405             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
406             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
407         ) \
408         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \
409             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
410             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
411         ) \
412         BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \
413             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
414             BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
415         ) \
416     BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
417 /**/
418 
419 
420     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \
421         BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \
422     /**/
423 
424         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \
425             BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \
426         /**/
427 
428 
429     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
430         BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \
431         :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \
432     /**/
433 
434 
435     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \
436         template< Params > \
437         struct customization_tag< Fullname > : \
438             customization_tag_of< Tag, Fullname > \
439         { }; \
440     /**/
441 
442 
443     // metafunctions
444     //
445 
446     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \
447         template< Params > \
448         struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
449             range_detail_microsoft::mutable_iterator_of< Fullname > \
450         { }; \
451     /**/
452 
453 
454     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \
455         template< Params > \
456         struct range_const_iterator< Fullname > : \
457             range_detail_microsoft::const_iterator_of< Fullname > \
458         { }; \
459     /**/
460 
461 
462     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \
463         template< Params > \
464         struct range_size< Fullname > : \
465             range_detail_microsoft::size_type_of< Fullname > \
466         { }; \
467     /**/
468 
469 
470     // functions
471     //
472 
473     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \
474         template< Params > inline \
475         typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
476         BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
477         { \
478             return boost::range_detail_microsoft::begin_of(x); \
479         } \
480     /**/
481 
482 
483     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \
484         template< Params > inline \
485         typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
486         BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
487         { \
488             return boost::range_detail_microsoft::begin_of(x); \
489         } \
490     /**/
491 
492 
493     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \
494         template< Params > inline \
495         typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
496         BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
497         { \
498             return boost::range_detail_microsoft::end_of(x); \
499         } \
500     /**/
501 
502 
503     #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \
504         template< Params > inline \
505         typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
506         BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
507         { \
508             return boost::range_detail_microsoft::end_of(x); \
509         } \
510     /**/
511 
512 
513     #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
514 
515         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
516         /**/
517 
518     #else
519 
520         #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
521             template< Params > inline \
522             typename boost::range_detail_microsoft::size_type_of< Fullname >::type \
523             boost_range_size(Fullname const& x) \
524             { \
525                 return boost::range_detail_microsoft::size_of(x); \
526             } \
527         /**/
528 
529     #endif
530 
531 
532 
533 
534 // list_iterator and helpers
535 //
536 
537 
538 #include <boost/assert.hpp>
539 #include <boost/iterator/iterator_categories.hpp>
540 #include <boost/iterator/iterator_facade.hpp>
541 #include <boost/mpl/if.hpp>
542 #include <boost/type_traits/is_same.hpp>
543 
544 
545 // POSITION's header is undocumented, so is NULL.
546 //
547 struct __POSITION; // incomplete, but used as just a pointer.
548 typedef __POSITION *POSITION;
549 
550 
551 namespace boost { namespace range_detail_microsoft {
552 
553 
554     template<
555         class ListT,
556         class Value,
557         class Reference,
558         class Traversal
559     >
560     struct list_iterator;
561 
562 
563     template<
564         class ListT,
565         class Value,
566         class Reference,
567         class Traversal
568     >
569     struct list_iterator_super
570     {
571         typedef typename mpl::if_< is_same<use_default, Reference>,
572             Value&,
573             Reference
574         >::type ref_t;
575 
576         typedef typename mpl::if_< is_same<use_default, Traversal>,
577             bidirectional_traversal_tag,
578             Traversal
579         >::type trv_t;
580 
581         typedef iterator_facade<
582             list_iterator<ListT, Value, Reference, Traversal>,
583             Value,
584             trv_t,
585             ref_t
586         > type;
587     };
588 
589 
590     template<
591         class ListT,
592         class Value,
593         class Reference = use_default,
594         class Traversal = use_default
595     >
596     struct list_iterator :
597         list_iterator_super<ListT, Value, Reference, Traversal>::type
598     {
599     private:
600         typedef list_iterator self_t;
601         typedef typename list_iterator_super<ListT, Value, Reference, Traversal>::type super_t;
602         typedef typename super_t::reference ref_t;
603 
604     public:
list_iteratorboost::range_detail_microsoft::list_iterator605         explicit list_iterator()
606         { }
607 
list_iteratorboost::range_detail_microsoft::list_iterator608         explicit list_iterator(ListT& lst, POSITION pos) :
609             m_plst(boost::addressof(lst)), m_pos(pos)
610         { }
611 
612     template< class, class, class, class > friend struct list_iterator;
613         template< class ListT_, class Value_, class Reference_, class Traversal_>
list_iteratorboost::range_detail_microsoft::list_iterator614         list_iterator(list_iterator<ListT_, Value_, Reference_, Traversal_> const& other) :
615             m_plst(other.m_plst), m_pos(other.m_pos)
616         { }
617 
618     private:
619         ListT *m_plst;
620         POSITION m_pos;
621 
622     friend class iterator_core_access;
dereferenceboost::range_detail_microsoft::list_iterator623         ref_t dereference() const
624         {
625             BOOST_ASSERT(m_pos != 0 && "out of range");
626             return m_plst->GetAt(m_pos);
627         }
628 
629         // A    B    C    D    x
630         // Head           Tail NULL(0)
631         //
incrementboost::range_detail_microsoft::list_iterator632         void increment()
633         {
634             BOOST_ASSERT(m_pos != 0 && "out of range");
635             m_plst->GetNext(m_pos);
636         }
637 
decrementboost::range_detail_microsoft::list_iterator638         void decrement()
639         {
640             if (m_pos == 0) {
641                 m_pos = m_plst->GetTailPosition();
642                 return;
643             }
644 
645             m_plst->GetPrev(m_pos);
646         }
647 
equalboost::range_detail_microsoft::list_iterator648         bool equal(self_t const& other) const
649         {
650             BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible");
651             return m_pos == other.m_pos;
652         }
653     };
654 
655 
656     // customization helpers
657     //
658 
659     struct array_functions
660     {
661         template< class Iterator, class X >
662         Iterator begin(X& x)
663         {
664             return x.GetData();
665         }
666 
667         template< class Iterator, class X >
668         Iterator end(X& x)
669         {
670             return begin<Iterator>(x) + x.GetSize();
671         }
672     };
673 
674 
675     struct list_functions
676     {
677         template< class Iterator, class X >
678         Iterator begin(X& x)
679         {
680             return Iterator(x, x.GetHeadPosition());
681         }
682 
683         template< class Iterator, class X >
684         Iterator end(X& x)
685         {
686             return Iterator(x, POSITION(0));
687         }
688     };
689 
690 
691 } } // namespace boost::range_detail_microsoft
692 
693 
694 
695 
696 // test
697 //
698 
699 
700 #if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
701 
702 
703 #include <algorithm>
704 #include <iterator>
705 #include <vector>
706 #include <boost/concept_check.hpp>
707 #include <boost/next_prior.hpp>
708 #include <boost/range/begin.hpp>
709 #include <boost/range/concepts.hpp>
710 #include <boost/range/const_iterator.hpp>
711 #include <boost/range/difference_type.hpp>
712 #include <boost/range/distance.hpp>
713 #include <boost/range/empty.hpp>
714 #include <boost/range/iterator_range.hpp>
715 #include <boost/range/mutable_iterator.hpp>
716 #include <boost/range/rbegin.hpp>
717 #include <boost/range/rend.hpp>
718 #include <boost/range/value_type.hpp>
719 #include <boost/type_traits/is_same.hpp>
720 
721 
722 namespace boost { namespace range_detail_microsoft {
723 
724 
725     template< class Range1, class Range2 >
test_equals(Range1 const & rng1,Range2 const & rng2)726     bool test_equals(Range1 const& rng1, Range2 const& rng2)
727     {
728         return
729             boost::distance(rng1) == boost::distance(rng2) &&
730             std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2))
731         ;
732     }
733 
734 
735     template< class AssocContainer, class PairT >
test_find_key_and_mapped(AssocContainer const & ac,PairT const & pa)736     bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa)
737     {
738         typedef typename boost::range_const_iterator<AssocContainer>::type iter_t;
739         for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) {
740             if (it->first == pa.first && it->second == pa.second)
741                 return true;
742         }
743 
744         return false;
745     }
746 
747 
748     // test functions
749     //
750 
751     template< class Range >
test_emptiness(Range &)752     bool test_emptiness(Range& )
753     {
754         bool result = true;
755 
756         Range emptyRng;
757         result = result && boost::empty(emptyRng);
758 
759         return result;
760     }
761 
762 
763     template< class Range >
test_trivial(Range & rng)764     bool test_trivial(Range& rng)
765     {
766         bool result = true;
767 
768         // convertibility check
769         typedef typename range_const_iterator<Range>::type citer_t;
770         citer_t cit = boost::begin(rng);
771         (void)cit; // unused
772 
773         // mutability check
774         typedef typename range_value<Range>::type val_t;
775         val_t v = *boost::begin(rng);
776         *boost::begin(rng) = v;
777         result = result && *boost::begin(rng) == v;
778 
779         return result;
780     }
781 
782 
783     template< class Range >
test_forward(Range & rng)784     bool test_forward(Range& rng)
785     {
786         boost::function_requires< ForwardRangeConcept<Range> >();
787 
788         bool result = (test_trivial)(rng);
789 
790         typedef typename range_value<Range>::type val_t;
791 
792         std::vector<val_t> saved;
793         std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
794         std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved));
795 
796         std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng));
797 
798         return result && (test_equals)(saved, rng);
799     };
800 
801 
802     template< class Range >
test_bidirectional(Range & rng)803     bool test_bidirectional(Range& rng)
804     {
805         boost::function_requires< BidirectionalRangeConcept<Range> >();
806 
807         bool result = (test_forward)(rng);
808 
809         typedef typename range_value<Range>::type val_t;
810 
811         std::vector<val_t> saved;
812         std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
813 
814         result = result && (test_equals)(
815             boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)),
816             boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng))
817         );
818 
819         return result;
820     }
821 
822 
823     template< class Range >
test_random_access(Range & rng)824     bool test_random_access(Range& rng)
825     {
826         boost::function_requires< RandomAccessRangeConcept<Range> >();
827 
828         bool result = (test_bidirectional)(rng);
829 
830         typedef typename range_value<Range>::type val_t;
831 
832         std::vector<val_t> saved;
833         std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
834         std::sort(boost::begin(saved), boost::end(saved));
835 
836         std::random_shuffle(boost::begin(rng), boost::end(rng));
837         std::sort(boost::begin(rng), boost::end(rng));
838         result = result && (test_equals)(rng, saved);
839 
840         std::random_shuffle(boost::begin(rng), boost::end(rng));
841         std::stable_sort(boost::begin(rng), boost::end(rng));
842         result = result && (test_equals)(rng, saved);
843 
844         std::random_shuffle(boost::begin(rng), boost::end(rng));
845         std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng));
846         result = result && (test_equals)(rng, saved);
847 
848         return result;
849     }
850 
851 
852     // initializer
853     //
854 
855     template< class ArrayT, class SampleRange >
test_init_array(ArrayT & arr,SampleRange const & sample)856     bool test_init_array(ArrayT& arr, SampleRange const& sample)
857     {
858         typedef typename range_const_iterator<SampleRange>::type iter_t;
859         typedef typename range_value<SampleRange>::type val_t;
860 
861         for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
862             val_t v = *it; // works around ATL3 CSimpleArray
863             arr.Add(v);
864         }
865 
866         return (test_equals)(arr, sample);
867     }
868 
869 
870     template< class ListT, class SampleRange >
test_init_list(ListT & lst,SampleRange const & sample)871     bool test_init_list(ListT& lst, SampleRange const& sample)
872     {
873         typedef typename range_const_iterator<SampleRange>::type iter_t;
874 
875         for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
876             lst.AddTail(*it);
877         }
878 
879         return (test_equals)(lst, sample);
880     }
881 
882 
883     template< class StringT, class SampleRange >
test_init_string(StringT & str,SampleRange const & sample)884     bool test_init_string(StringT& str, SampleRange const& sample)
885     {
886         typedef typename range_const_iterator<SampleRange>::type iter_t;
887         typedef typename range_value<SampleRange>::type val_t;
888 
889         for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
890             str += *it;
891         }
892 
893         return (test_equals)(str, sample);
894     }
895 
896 
897     template< class MapT, class SampleMap >
test_init_map(MapT & map,SampleMap const & sample)898     bool test_init_map(MapT& map, SampleMap const& sample)
899     {
900         typedef typename range_const_iterator<SampleMap>::type iter_t;
901 
902         for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
903             map.SetAt(it->first, it->second);
904         }
905 
906         return boost::distance(map) == boost::distance(sample);
907     }
908 
909 
910     // metafunction test
911     //
912 
913     template< class Range, class Iter >
914     struct test_mutable_iter :
915         boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>::type, Iter >
916     { };
917 
918 
919     template< class Range, class Iter >
920     struct test_const_iter :
921         boost::is_same< typename boost::range_const_iterator<Range>::type, Iter >
922     { };
923 
924 
925 } } // namespace boost::range_detail_microsoft
926 
927 
928 #endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
929 
930 
931 
932 #endif
933