]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | |
11fdf7f2 | 61 | #include <boost/next_prior.hpp> |
7c673cae FG |
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 | |
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 | |
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 | |
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 | |
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 | |
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: | |
605 | explicit list_iterator() | |
606 | { } | |
607 | ||
608 | 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_> | |
614 | 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; | |
623 | 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 | // | |
632 | void increment() | |
633 | { | |
634 | BOOST_ASSERT(m_pos != 0 && "out of range"); | |
635 | m_plst->GetNext(m_pos); | |
636 | } | |
637 | ||
638 | 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 | ||
648 | 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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 > | |
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 |