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 > beginboost::range_detail_microsoft::array_functions662 Iterator begin(X& x) 663 { 664 return x.GetData(); 665 } 666 667 template< class Iterator, class X > endboost::range_detail_microsoft::array_functions668 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 > beginboost::range_detail_microsoft::list_functions678 Iterator begin(X& x) 679 { 680 return Iterator(x, x.GetHeadPosition()); 681 } 682 683 template< class Iterator, class X > endboost::range_detail_microsoft::list_functions684 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