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