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