1 #ifndef BOOST_RANGE_ATL_HPP 2 #define BOOST_RANGE_ATL_HPP 3 4 5 6 7 // Boost.Range ATL Extension 8 // 9 // Copyright Shunsuke Sogame 2005-2006. 10 // Distributed under the Boost Software License, Version 1.0. 11 // (See accompanying file LICENSE_1_0.txt or copy at 12 // http://www.boost.org/LICENSE_1_0.txt) 13 14 15 16 17 // config 18 // 19 20 21 #include <atldef.h> // _ATL_VER 22 23 24 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 25 #if (_ATL_VER < 0x0700) 26 #define BOOST_RANGE_ATL_NO_COLLECTIONS 27 #endif 28 #endif 29 30 31 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 32 #if (_ATL_VER < 0x0700) // dubious 33 #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX 34 #endif 35 #endif 36 37 38 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) 39 #if (_MSC_VER < 1310) // from <boost/regex/mfc.hpp>, but dubious 40 #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING 41 #endif 42 #endif 43 44 45 46 47 // forward declarations 48 // 49 50 51 #include <basetyps.h> // IID 52 53 54 namespace ATL { 55 56 57 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 58 59 60 // arrays 61 // 62 template< class E, class ETraits > 63 class CAtlArray; 64 65 template< class E > 66 class CAutoPtrArray; 67 68 template< class I, const IID *piid > 69 class CInterfaceArray; 70 71 72 // lists 73 // 74 template< class E, class ETraits > 75 class CAtlList; 76 77 template< class E > 78 class CAutoPtrList; 79 80 template< class E, class Allocator > 81 class CHeapPtrList; 82 83 template< class I, const IID *piid > 84 class CInterfaceList; 85 86 87 // maps 88 // 89 template< class K, class V, class KTraits, class VTraits > 90 class CAtlMap; 91 92 template< class K, class V, class KTraits, class VTraits > 93 class CRBTree; 94 95 template< class K, class V, class KTraits, class VTraits > 96 class CRBMap; 97 98 template< class K, class V, class KTraits, class VTraits > 99 class CRBMultiMap; 100 101 102 // strings 103 // 104 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) 105 template< class BaseType, bool t_bMFCDLL > 106 class CSimpleStringT; 107 #else 108 template< class BaseType > 109 class CSimpleStringT; 110 #endif 111 112 template< class BaseType, class StringTraits > 113 class CStringT; 114 115 template< class StringType, int t_nChars > 116 class CFixedStringT; 117 118 template< class BaseType, const int t_nSize > 119 class CStaticString; 120 121 122 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 123 124 125 // simples 126 // 127 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 128 129 template< class T, class TEqual > 130 class CSimpleArray; 131 132 template< class TKey, class TVal, class TEqual > 133 class CSimpleMap; 134 135 #else 136 137 template< class T > 138 class CSimpleArray; 139 140 template< class T > 141 class CSimpleValArray; 142 143 template< class TKey, class TVal > 144 class CSimpleMap; 145 146 #endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 147 148 149 // pointers 150 // 151 template< class E > 152 class CAutoPtr; 153 154 template< class T > 155 class CComPtr; 156 157 template< class T, const IID *piid > 158 class CComQIPtr; 159 160 template< class E, class Allocator > 161 class CHeapPtr; 162 163 template< class T > 164 class CAdapt; 165 166 167 } // namespace ATL 168 169 170 171 172 // indirect_iterator customizations 173 // 174 175 176 #include <boost/mpl/identity.hpp> 177 #include <boost/pointee.hpp> 178 179 180 namespace boost { 181 182 183 template< class E > 184 struct pointee< ATL::CAutoPtr<E> > : 185 mpl::identity<E> 186 { }; 187 188 template< class T > 189 struct pointee< ATL::CComPtr<T> > : 190 mpl::identity<T> 191 { }; 192 193 template< class T, const IID *piid > 194 struct pointee< ATL::CComQIPtr<T, piid> > : 195 mpl::identity<T> 196 { }; 197 198 template< class E, class Allocator > 199 struct pointee< ATL::CHeapPtr<E, Allocator> > : 200 mpl::identity<E> 201 { }; 202 203 template< class T > 204 struct pointee< ATL::CAdapt<T> > : 205 pointee<T> 206 { }; 207 208 209 } // namespace boost 210 211 212 213 214 // extended customizations 215 // 216 217 218 #include <boost/iterator/indirect_iterator.hpp> 219 #include <boost/iterator/zip_iterator.hpp> 220 #include <boost/range/detail/microsoft.hpp> 221 #include <boost/tuple/tuple.hpp> 222 #include <atlbase.h> // CComBSTR 223 224 225 namespace boost { namespace range_detail_microsoft { 226 227 228 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 229 230 231 // arrays 232 // 233 234 struct atl_array_functions : 235 array_functions 236 { 237 template< class Iterator, class X > 238 Iterator end(X& x) // redefine 239 { 240 return x.GetData() + x.GetCount(); // no 'GetSize()' 241 } 242 }; 243 244 245 template< class E, class ETraits > 246 struct customization< ATL::CAtlArray<E, ETraits> > : 247 atl_array_functions 248 { 249 template< class X > 250 struct meta 251 { 252 typedef E val_t; 253 254 typedef val_t *mutable_iterator; 255 typedef val_t const *const_iterator; 256 }; 257 }; 258 259 260 template< class E > 261 struct customization< ATL::CAutoPtrArray<E> > : 262 atl_array_functions 263 { 264 template< class X > 265 struct meta 266 { 267 // ATL::CAutoPtr/CHeapPtr is no assignable. 268 typedef ATL::CAutoPtr<E> val_t; 269 typedef val_t *miter_t; 270 typedef val_t const *citer_t; 271 272 typedef indirect_iterator<miter_t> mutable_iterator; 273 typedef indirect_iterator<citer_t> const_iterator; 274 }; 275 }; 276 277 278 template< class I, const IID *piid > 279 struct customization< ATL::CInterfaceArray<I, piid> > : 280 atl_array_functions 281 { 282 template< class X > 283 struct meta 284 { 285 typedef ATL::CComQIPtr<I, piid> val_t; 286 287 typedef val_t *mutable_iterator; 288 typedef val_t const *const_iterator; 289 }; 290 }; 291 292 293 template< class E, class ETraits > 294 struct customization< ATL::CAtlList<E, ETraits> > : 295 list_functions 296 { 297 template< class X > 298 struct meta 299 { 300 typedef E val_t; 301 302 typedef list_iterator<X, val_t> mutable_iterator; 303 typedef list_iterator<X const, val_t const> const_iterator; 304 }; 305 }; 306 307 308 struct indirected_list_functions 309 { 310 template< class Iterator, class X > 311 Iterator begin(X& x) 312 { 313 typedef typename Iterator::base_type base_t; // == list_iterator 314 return Iterator(base_t(x, x.GetHeadPosition())); 315 } 316 317 template< class Iterator, class X > 318 Iterator end(X& x) 319 { 320 typedef typename Iterator::base_type base_t; 321 return Iterator(base_t(x, POSITION(0))); 322 } 323 }; 324 325 326 template< class E > 327 struct customization< ATL::CAutoPtrList<E> > : 328 indirected_list_functions 329 { 330 template< class X > 331 struct meta 332 { 333 typedef ATL::CAutoPtr<E> val_t; 334 typedef list_iterator<X, val_t> miter_t; 335 typedef list_iterator<X const, val_t const> citer_t; 336 337 typedef indirect_iterator<miter_t> mutable_iterator; 338 typedef indirect_iterator<citer_t> const_iterator; 339 }; 340 }; 341 342 343 template< class E, class Allocator > 344 struct customization< ATL::CHeapPtrList<E, Allocator> > : 345 indirected_list_functions 346 { 347 template< class X > 348 struct meta 349 { 350 typedef ATL::CHeapPtr<E, Allocator> val_t; 351 typedef list_iterator<X, val_t> miter_t; 352 typedef list_iterator<X const, val_t const> citer_t; 353 354 typedef indirect_iterator<miter_t> mutable_iterator; 355 typedef indirect_iterator<citer_t> const_iterator; 356 }; 357 }; 358 359 360 template< class I, const IID *piid > 361 struct customization< ATL::CInterfaceList<I, piid> > : 362 list_functions 363 { 364 template< class X > 365 struct meta 366 { 367 typedef ATL::CComQIPtr<I, piid> val_t; 368 369 typedef list_iterator<X, val_t> mutable_iterator; 370 typedef list_iterator<X const, val_t const> const_iterator; 371 }; 372 }; 373 374 375 // maps 376 // 377 378 struct atl_rb_tree_tag 379 { }; 380 381 template< > 382 struct customization< atl_rb_tree_tag > : 383 indirected_list_functions 384 { 385 template< class X > 386 struct meta 387 { 388 typedef typename X::CPair val_t; 389 390 typedef list_iterator<X, val_t *, val_t *> miter_t; 391 typedef list_iterator<X const, val_t const *, val_t const *> citer_t; 392 393 typedef indirect_iterator<miter_t> mutable_iterator; 394 typedef indirect_iterator<citer_t> const_iterator; 395 }; 396 }; 397 398 399 template< class K, class V, class KTraits, class VTraits > 400 struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > : 401 customization< atl_rb_tree_tag > 402 { 403 template< class Iterator, class X > 404 Iterator begin(X& x) // redefine 405 { 406 typedef typename Iterator::base_type base_t; // == list_iterator 407 return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition' 408 } 409 }; 410 411 412 // strings 413 // 414 415 struct atl_string_tag 416 { }; 417 418 template< > 419 struct customization< atl_string_tag > 420 { 421 template< class X > 422 struct meta 423 { 424 typedef typename X::PXSTR mutable_iterator; 425 typedef typename X::PCXSTR const_iterator; 426 }; 427 428 template< class Iterator, class X > beginboost::range_detail_microsoft::customization429 typename mutable_<Iterator, X>::type begin(X& x) 430 { 431 return x.GetBuffer(0); 432 } 433 434 template< class Iterator, class X > 435 Iterator begin(X const& x) 436 { 437 return x.GetString(); 438 } 439 440 template< class Iterator, class X > 441 Iterator end(X& x) 442 { 443 return begin<Iterator>(x) + x.GetLength(); 444 } 445 }; 446 447 448 template< class BaseType, const int t_nSize > 449 struct customization< ATL::CStaticString<BaseType, t_nSize> > 450 { 451 template< class X > 452 struct meta 453 { 454 typedef BaseType const *mutable_iterator; 455 typedef mutable_iterator const_iterator; 456 }; 457 458 template< class Iterator, class X > 459 Iterator begin(X const& x) 460 { 461 return x; 462 } 463 464 template< class Iterator, class X > 465 Iterator end(X const& x) 466 { 467 return begin<Iterator>(x) + X::GetLength(); 468 } 469 }; 470 471 472 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 473 474 475 template< > 476 struct customization< ATL::CComBSTR > 477 { 478 template< class X > 479 struct meta 480 { 481 typedef OLECHAR *mutable_iterator; 482 typedef OLECHAR const *const_iterator; 483 }; 484 485 template< class Iterator, class X > 486 Iterator begin(X& x) 487 { 488 return x.operator BSTR(); 489 } 490 491 template< class Iterator, class X > 492 Iterator end(X& x) 493 { 494 return begin<Iterator>(x) + x.Length(); 495 } 496 }; 497 498 499 // simples 500 // 501 502 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 503 template< class T, class TEqual > 504 struct customization< ATL::CSimpleArray<T, TEqual> > : 505 #else 506 template< class T > 507 struct customization< ATL::CSimpleArray<T> > : 508 #endif 509 array_functions 510 { 511 template< class X > 512 struct meta 513 { 514 typedef T val_t; 515 516 typedef val_t *mutable_iterator; 517 typedef val_t const *const_iterator; 518 }; 519 }; 520 521 522 #if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 523 524 template< class T > 525 struct customization< ATL::CSimpleValArray<T> > : 526 array_functions 527 { 528 template< class X > 529 struct meta 530 { 531 typedef T val_t; 532 533 typedef val_t *mutable_iterator; 534 typedef val_t const *const_iterator; 535 }; 536 }; 537 538 #endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 539 540 541 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 542 template< class TKey, class TVal, class TEqual > 543 struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> > 544 #else 545 template< class TKey, class TVal > 546 struct customization< ATL::CSimpleMap<TKey, TVal> > 547 #endif 548 { 549 template< class X > 550 struct meta 551 { 552 typedef TKey k_val_t; 553 typedef k_val_t *k_miter_t; 554 typedef k_val_t const *k_citer_t; 555 556 typedef TVal v_val_t; 557 typedef v_val_t *v_miter_t; 558 typedef v_val_t const *v_citer_t; 559 560 // Topic: 561 // 'std::pair' can't contain references 562 // because of reference to reference problem. 563 564 typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator; 565 typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator; 566 }; 567 568 template< class Iterator, class X > 569 Iterator begin(X& x) 570 { 571 return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal)); 572 } 573 574 template< class Iterator, class X > 575 Iterator end(X& x) 576 { 577 return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize())); 578 } 579 }; 580 581 582 } } // namespace boost::range_detail_microsoft 583 584 585 586 587 // range customizations 588 // 589 590 591 #if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 592 593 594 // arrays 595 // 596 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 597 boost::range_detail_microsoft::using_type_as_tag, 598 (ATL, BOOST_PP_NIL), CAtlArray, 2 599 ) 600 601 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 602 boost::range_detail_microsoft::using_type_as_tag, 603 (ATL, BOOST_PP_NIL), CAutoPtrArray, 1 604 ) 605 606 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 607 boost::range_detail_microsoft::using_type_as_tag, 608 (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *) 609 ) 610 611 612 // lists 613 // 614 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 615 boost::range_detail_microsoft::using_type_as_tag, 616 (ATL, BOOST_PP_NIL), CAtlList, 2 617 ) 618 619 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 620 boost::range_detail_microsoft::using_type_as_tag, 621 (ATL, BOOST_PP_NIL), CAutoPtrList, 1 622 ) 623 624 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 625 boost::range_detail_microsoft::using_type_as_tag, 626 (ATL, BOOST_PP_NIL), CHeapPtrList, 2 627 ) 628 629 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 630 boost::range_detail_microsoft::using_type_as_tag, 631 (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *) 632 ) 633 634 635 //maps 636 // 637 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 638 boost::range_detail_microsoft::using_type_as_tag, 639 (ATL, BOOST_PP_NIL), CAtlMap, 4 640 ) 641 642 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 643 boost::range_detail_microsoft::atl_rb_tree_tag, 644 (ATL, BOOST_PP_NIL), CRBTree, 4 645 ) 646 647 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 648 boost::range_detail_microsoft::atl_rb_tree_tag, 649 (ATL, BOOST_PP_NIL), CRBMap, 4 650 ) 651 652 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 653 boost::range_detail_microsoft::atl_rb_tree_tag, 654 (ATL, BOOST_PP_NIL), CRBMultiMap, 4 655 ) 656 657 658 // strings 659 // 660 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) 661 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 662 boost::range_detail_microsoft::atl_string_tag, 663 (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool) 664 ) 665 #else 666 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 667 boost::range_detail_microsoft::atl_string_tag, 668 (ATL, BOOST_PP_NIL), CSimpleStringT, 1 669 ) 670 #endif 671 672 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 673 boost::range_detail_microsoft::atl_string_tag, 674 (ATL, BOOST_PP_NIL), CStringT, 2 675 ) 676 677 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 678 boost::range_detail_microsoft::atl_string_tag, 679 (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int) 680 ) 681 682 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 683 boost::range_detail_microsoft::using_type_as_tag, 684 (ATL, BOOST_PP_NIL), CStaticString, (class)(const int) 685 ) 686 687 688 #endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) 689 690 691 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( 692 boost::range_detail_microsoft::using_type_as_tag, 693 (ATL, BOOST_PP_NIL), CComBSTR 694 ) 695 696 697 // simples 698 // 699 #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 700 701 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 702 boost::range_detail_microsoft::using_type_as_tag, 703 (ATL, BOOST_PP_NIL), CSimpleArray, 2 704 ) 705 706 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 707 boost::range_detail_microsoft::using_type_as_tag, 708 (ATL, BOOST_PP_NIL), CSimpleMap, 3 709 ) 710 711 #else 712 713 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 714 boost::range_detail_microsoft::using_type_as_tag, 715 (ATL, BOOST_PP_NIL), CSimpleArray, 1 716 ) 717 718 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 719 boost::range_detail_microsoft::using_type_as_tag, 720 (ATL, BOOST_PP_NIL), CSimpleMap, 2 721 ) 722 723 BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( 724 boost::range_detail_microsoft::using_type_as_tag, 725 (ATL, BOOST_PP_NIL), CSimpleValArray, 1 726 ) 727 728 #endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) 729 730 731 732 733 #endif 734