Changeset b57a3ee in mainline for uspace/lib/cpp/include/__bits/iterator.hpp
- Timestamp:
- 2018-07-05T21:41:24Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c735afb
- Parents:
- 4f461384
- git-author:
- Dzejrou <dzejrou@…> (2018-06-25 16:58:08)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:24)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/__bits/iterator.hpp
r4f461384 rb57a3ee 30 30 #define LIBCPP_BITS_ITERATOR 31 31 32 #include <__bits/aux.hpp> 33 34 namespace std::aux 32 #include <__bits/memory/addressof.hpp> 33 #include <cstdlib> 34 #include <initializer_list> 35 #include <iosfwd> 36 #include <type_traits> 37 #include <utility> 38 39 namespace std 35 40 { 36 41 /** 37 * Used for our custom iterators where we know 38 * that their references/const_references and 39 * pointers/const_pointers differ only in constness. 40 */ 42 * 24.4.3, standard iterator tags: 43 */ 44 45 struct input_iterator_tag 46 { /* DUMMY BODY */ }; 47 48 struct output_iterator_tag 49 { /* DUMMY BODY */ }; 50 51 struct forward_iterator_tag: input_iterator_tag 52 { /* DUMMY BODY */ }; 53 54 struct bidirectional_iterator_tag: forward_iterator_tag 55 { /* DUMMY BODY */ }; 56 57 struct random_access_iterator_tag: bidirectional_iterator_tag 58 { /* DUMMY BODY */ }; 59 60 /** 61 * 24.4.1, iterator traits: 62 */ 63 64 template<class Iterator> 65 struct iterator_traits 66 { 67 using difference_type = typename Iterator::difference_type; 68 using value_type = typename Iterator::value_type; 69 using iterator_category = typename Iterator::iterator_category; 70 using reference = typename Iterator::reference; 71 using pointer = typename Iterator::pointer; 72 }; 41 73 42 74 template<class T> 43 struct get_non_const_ref 44 : type_is<T> 45 { /* DUMMY BODY */ }; 75 struct iterator_traits<T*> 76 { 77 using difference_type = ptrdiff_t; 78 using value_type = T; 79 using iterator_category = random_access_iterator_tag; 80 using reference = T&; 81 using pointer = T*; 82 }; 46 83 47 84 template<class T> 48 struct get_non_const_ref<const T&> 49 : type_is<T&> 50 { /* DUMMY BODY */ }; 85 struct iterator_traits<const T*> 86 { 87 using difference_type = ptrdiff_t; 88 using value_type = T; 89 using iterator_category = random_access_iterator_tag; 90 using reference = const T&; 91 using pointer = const T*; 92 }; 93 94 /** 95 * 24.4.2, basic iterator: 96 */ 97 98 template< 99 class Category, class T, class Distance = ptrdiff_t, 100 class Pointer = T*, class Reference = T& 101 > 102 struct iterator 103 { 104 using difference_type = Distance; 105 using value_type = T; 106 using iterator_category = Category; 107 using reference = Reference; 108 using pointer = Pointer; 109 }; 110 111 /** 112 * 24.4.4, iterator operations 113 */ 114 115 template<class InputIterator, class Distance> 116 void advance(InputIterator& it, Distance n) 117 { 118 for (Distance i = Distance{}; i < n; ++i) 119 ++it; 120 } 121 122 template<class InputIterator> 123 typename iterator_traits<InputIterator>::difference_type 124 distance(InputIterator first, InputIterator last) 125 { 126 using cat_t = typename iterator_traits<InputIterator>::iterator_category; 127 using diff_t = typename iterator_traits<InputIterator>::difference_type; 128 129 if constexpr (is_same_v<cat_t, random_access_iterator_tag>) 130 return last - first; 131 else 132 { 133 diff_t diff{}; 134 while (first != last) 135 { 136 ++diff; 137 ++first; 138 } 139 140 return diff; 141 } 142 } 143 144 template<class ForwardIterator> 145 ForwardIterator 146 next(ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1) 147 { 148 advance(it, n); 149 150 return it; 151 } 152 153 template<class BidirectionalIterator> 154 BidirectionalIterator 155 prev(BidirectionalIterator it, 156 typename iterator_traits<BidirectionalIterator>::difference_type n = 1) 157 { 158 advance(it, -n); 159 160 return it; 161 } 162 163 /** 164 * 24.5.1, reverse iterator: 165 */ 166 167 template<class Iterator> 168 class reverse_iterator 169 : public iterator< 170 typename iterator_traits<Iterator>::iterator_category, 171 typename iterator_traits<Iterator>::value_type, 172 typename iterator_traits<Iterator>::difference_type, 173 typename iterator_traits<Iterator>::pointer, 174 typename iterator_traits<Iterator>::reference 175 > 176 { 177 public: 178 using iterator_type = Iterator; 179 using difference_type = typename iterator_traits<Iterator>::difference_type; 180 using reference = typename iterator_traits<Iterator>::reference; 181 using pointer = typename iterator_traits<Iterator>::pointer; 182 183 reverse_iterator() 184 : current_{} 185 { /* DUMMY BODY */ } 186 187 explicit reverse_iterator(Iterator it) 188 : current_{it} 189 { /* DUMMY BODY */ } 190 191 template<class U> 192 reverse_iterator(const reverse_iterator<U>& other) 193 : current_{other.current_} 194 { /* DUMMY BODY */ } 195 196 template<class U> 197 reverse_iterator& operator=(const reverse_iterator<U>& other) 198 { 199 current_ = other.base(); 200 201 return *this; 202 } 203 204 Iterator base() const 205 { 206 return current_; 207 } 208 209 reference operator*() const 210 { 211 auto tmp = current_; 212 213 return *(--tmp); 214 } 215 216 pointer operator->() const 217 { 218 return addressof(operator*()); 219 } 220 221 reverse_iterator& operator++() 222 { 223 --current_; 224 225 return *this; 226 } 227 228 reverse_iterator operator++(int) 229 { 230 auto tmp = *this; 231 --current_; 232 233 return tmp; 234 } 235 236 reverse_iterator& operator--() 237 { 238 ++current_; 239 240 return *this; 241 } 242 243 reverse_iterator operator--(int) 244 { 245 auto tmp = *this; 246 ++current_; 247 248 return tmp; 249 } 250 251 reverse_iterator operator+(difference_type n) const 252 { 253 return reverse_iterator{current_ - n}; 254 } 255 256 reverse_iterator& operator+=(difference_type n) 257 { 258 current_ -= n; 259 260 return *this; 261 } 262 263 reverse_iterator operator-(difference_type n) const 264 { 265 return reverse_iterator{current_ + n}; 266 } 267 268 reverse_iterator& operator-=(difference_type n) 269 { 270 current_ += n; 271 272 return *this; 273 } 274 275 auto operator[](difference_type n) const 276 { 277 return current_[-n - 1]; 278 } 279 280 protected: 281 Iterator current_; 282 }; 283 284 template<class Iterator1, class Iterator2> 285 bool operator==(const reverse_iterator<Iterator1>& lhs, 286 const reverse_iterator<Iterator2>& rhs) 287 { 288 return lhs.base() == rhs.base(); 289 } 290 291 template<class Iterator1, class Iterator2> 292 bool operator<(const reverse_iterator<Iterator1>& lhs, 293 const reverse_iterator<Iterator2>& rhs) 294 { 295 // Remember: they are reversed! 296 return lhs.base() > rhs.base(); 297 } 298 299 template<class Iterator1, class Iterator2> 300 bool operator!=(const reverse_iterator<Iterator1>& lhs, 301 const reverse_iterator<Iterator2>& rhs) 302 { 303 return lhs.base() != rhs.base(); 304 } 305 306 template<class Iterator1, class Iterator2> 307 bool operator>(const reverse_iterator<Iterator1>& lhs, 308 const reverse_iterator<Iterator2>& rhs) 309 { 310 return lhs.base() < rhs.base(); 311 } 312 313 template<class Iterator1, class Iterator2> 314 bool operator>=(const reverse_iterator<Iterator1>& lhs, 315 const reverse_iterator<Iterator2>& rhs) 316 { 317 return lhs.base() <= rhs.base(); 318 } 319 320 template<class Iterator1, class Iterator2> 321 bool operator<=(const reverse_iterator<Iterator1>& lhs, 322 const reverse_iterator<Iterator2>& rhs) 323 { 324 return lhs.base() >= rhs.base(); 325 } 326 327 template<class Iterator1, class Iterator2> 328 auto operator-(const reverse_iterator<Iterator1>& lhs, 329 const reverse_iterator<Iterator2>& rhs) 330 -> decltype(rhs.base() - lhs.base()) 331 { 332 return rhs.base() - lhs.base(); 333 } 334 335 template<class Iterator> 336 reverse_iterator<Iterator> operator+( 337 typename reverse_iterator<Iterator>::difference_type n, 338 const reverse_iterator<Iterator>& it 339 ) 340 { 341 return reverse_iterator<Iterator>{it.base() - n}; 342 } 343 344 template<class Iterator> 345 reverse_iterator<Iterator> make_reverse_iterator(Iterator it) 346 { 347 return reverse_iterator<Iterator>(it); 348 } 349 350 /** 351 * 24.5.2, insert iterators: 352 */ 353 354 /** 355 * 24.5.2.1, back insert iterator: 356 */ 357 358 template<class Container> 359 class back_insert_iterator 360 : public iterator<output_iterator_tag, void, void, void, void> 361 { 362 public: 363 using container_type = Container; 364 365 explicit back_insert_iterator(Container& cont) 366 : container{std::addressof(cont)} 367 { /* DUMMY BODY */ } 368 369 back_insert_iterator& operator=(const typename container_type::value_type& value) 370 { 371 container->push_back(value); 372 return *this; 373 } 374 375 back_insert_iterator& operator=(typename container_type::value_type&& value) 376 { 377 container->push_back(move(value)); 378 return *this; 379 } 380 381 back_insert_iterator& operator*() 382 { 383 return *this; 384 } 385 386 back_insert_iterator& operator++() 387 { 388 return *this; 389 } 390 391 back_insert_iterator operator++(int) 392 { 393 return *this; 394 } 395 396 protected: 397 Container* container; 398 }; 399 400 template<class Container> 401 back_insert_iterator<Container> back_inserter(Container& cont) 402 { 403 return back_insert_iterator<Container>(cont); 404 } 405 406 /** 407 * 24.5.2.3, front insert iterator: 408 */ 409 410 template<class Container> 411 class front_insert_iterator 412 : public iterator<output_iterator_tag, void, void, void, void> 413 { 414 public: 415 using container_type = Container; 416 417 explicit front_insert_iterator(Container& cont) 418 : container{std::addressof(cont)} 419 { /* DUMMY BODY */ } 420 421 front_insert_iterator& operator=(const typename container_type::value_type& value) 422 { 423 container->push_front(value); 424 return *this; 425 } 426 427 front_insert_iterator& operator=(typename container_type::value_type&& value) 428 { 429 container->push_front(move(value)); 430 return *this; 431 } 432 433 front_insert_iterator& operator*() 434 { 435 return *this; 436 } 437 438 front_insert_iterator& operator++() 439 { 440 return *this; 441 } 442 443 front_insert_iterator operator++(int) 444 { 445 return *this; 446 } 447 448 protected: 449 Container* container; 450 }; 451 452 template<class Container> 453 front_insert_iterator<Container> front_inserter(Container& cont) 454 { 455 return front_insert_iterator<Container>(cont); 456 } 457 458 /** 459 * 24.5.2.5, front insert iterator: 460 */ 461 462 template<class Container> 463 class insert_iterator 464 : public iterator<output_iterator_tag, void, void, void, void> 465 { 466 public: 467 using container_type = Container; 468 469 explicit insert_iterator(Container& cont, typename Container::iterator i) 470 : container{std::addressof(cont)}, iter{i} 471 { /* DUMMY BODY */ } 472 473 insert_iterator& operator=(const typename container_type::value_type& value) 474 { 475 iter = container.insert(iter, value); 476 ++iter; 477 478 return *this; 479 } 480 481 insert_iterator& operator=(typename container_type::value_type&& value) 482 { 483 iter = container.insert(iter, move(value)); 484 ++iter; 485 486 return *this; 487 } 488 489 insert_iterator& operator*() 490 { 491 return *this; 492 } 493 494 insert_iterator& operator++() 495 { 496 return *this; 497 } 498 499 insert_iterator operator++(int) 500 { 501 return *this; 502 } 503 504 protected: 505 Container* container; 506 typename Container::iterator iter; 507 }; 508 509 template<class Container> 510 insert_iterator<Container> inserter(Container& cont, typename Container::iterator i) 511 { 512 return insert_iterator<Container>(cont, i); 513 } 514 515 /** 516 * 24.5.3.1, move iterator: 517 */ 518 519 namespace aux 520 { 521 template<class Iterator, class = void> 522 struct move_it_get_reference 523 { 524 using type = typename iterator_traits<Iterator>::reference; 525 }; 526 527 template<class Iterator> 528 struct move_it_get_reference< 529 Iterator, enable_if_t< 530 is_reference<typename iterator_traits<Iterator>::reference>::value, 531 void 532 > 533 > 534 { 535 using type = remove_reference_t<typename iterator_traits<Iterator>::reference>&&; 536 }; 537 } 538 539 template<class Iterator> 540 class move_iterator 541 { 542 public: 543 using iterator_type = Iterator; 544 using pointer = iterator_type; 545 using difference_type = typename iterator_traits<iterator_type>::difference_type; 546 using value_type = typename iterator_traits<iterator_type>::value_type; 547 using iterator_category = typename iterator_traits<iterator_type>::iterator_category; 548 using reference = typename aux::move_it_get_reference<iterator_type>::type; 549 550 move_iterator() 551 : current_{} 552 { /* DUMMY BODY */ } 553 554 explicit move_iterator(iterator_type i) 555 : current_{i} 556 { /* DUMMY BODY */ } 557 558 // TODO: both require is_convertible 559 template<class U> 560 move_iterator(const move_iterator<U>& other) 561 : current_{other.current_} 562 { /* DUMMY BODY */ } 563 564 template<class U> 565 move_iterator& operator=(const move_iterator<U>& other) 566 { 567 current_ = other.current_; 568 569 return *this; 570 } 571 572 iterator_type base() const 573 { 574 return current_; 575 } 576 577 reference operator*() const 578 { 579 return static_cast<reference>(*current_); 580 } 581 582 pointer operator->() const 583 { 584 return current_; 585 } 586 587 move_iterator& operator++() 588 { 589 ++current_; 590 591 return *this; 592 } 593 594 move_iterator operator++(int) 595 { 596 auto tmp = *this; 597 ++current_; 598 599 return tmp; 600 } 601 602 move_iterator& operator--() 603 { 604 --current_; 605 606 return *this; 607 } 608 609 move_iterator operator--(int) 610 { 611 auto tmp = *this; 612 --current_; 613 614 return tmp; 615 } 616 617 move_iterator operator+(difference_type n) const 618 { 619 return move_iterator(current_ + n); 620 } 621 622 move_iterator& operator+=(difference_type n) 623 { 624 current_ += n; 625 626 return *this; 627 } 628 629 move_iterator operator-(difference_type n) const 630 { 631 return move_iterator(current_ - n); 632 } 633 634 move_iterator& operator-=(difference_type n) 635 { 636 current_ -= n; 637 638 return *this; 639 } 640 641 auto operator[](difference_type idx) const 642 { 643 return move(current_[idx]); 644 } 645 646 private: 647 iterator_type current_; 648 }; 649 650 template<class Iterator1, class Iterator2> 651 bool operator==(const move_iterator<Iterator1>& lhs, 652 const move_iterator<Iterator2>& rhs) 653 { 654 return lhs.base() == rhs.base(); 655 } 656 657 template<class Iterator1, class Iterator2> 658 bool operator!=(const move_iterator<Iterator1>& lhs, 659 const move_iterator<Iterator2>& rhs) 660 { 661 return lhs.base() != rhs.base(); 662 } 663 664 template<class Iterator1, class Iterator2> 665 bool operator<(const move_iterator<Iterator1>& lhs, 666 const move_iterator<Iterator2>& rhs) 667 { 668 return lhs.base() < rhs.base(); 669 } 670 671 template<class Iterator1, class Iterator2> 672 bool operator<=(const move_iterator<Iterator1>& lhs, 673 const move_iterator<Iterator2>& rhs) 674 { 675 return !(rhs < lhs); 676 } 677 678 template<class Iterator1, class Iterator2> 679 bool operator>(const move_iterator<Iterator1>& lhs, 680 const move_iterator<Iterator2>& rhs) 681 { 682 return rhs < lhs; 683 } 684 685 template<class Iterator1, class Iterator2> 686 bool operator>=(const move_iterator<Iterator1>& lhs, 687 const move_iterator<Iterator2>& rhs) 688 { 689 return !(lhs < rhs); 690 } 691 692 template<class Iterator1, class Iterator2> 693 auto operator-(const move_iterator<Iterator1>& lhs, 694 const move_iterator<Iterator2>& rhs) 695 -> decltype(rhs.base() - lhs.base()) 696 { 697 return lhs.base() - rhs.base(); 698 } 699 700 template<class Iterator> 701 move_iterator<Iterator> operator+( 702 typename move_iterator<Iterator>::difference_type n, 703 const move_iterator<Iterator>& it 704 ) 705 { 706 return it + n; 707 } 708 709 template<class Iterator> 710 move_iterator<Iterator> make_move_iterator(Iterator it) 711 { 712 return move_iterator<Iterator>(it); 713 } 714 715 /** 716 * 24.6, stream iterators: 717 */ 718 719 /** 720 * 24.6.1, class template istream_iterator: 721 */ 722 723 template<class T, class Char = char, class Traits = char_traits<Char>, 724 class Distance = ptrdiff_t> 725 class istream_iterator 726 : public iterator<input_iterator_tag, T, Distance, const T*, const T&> 727 { 728 public: 729 using char_type = Char; 730 using traits_type = Traits; 731 using istream_type = basic_istream<char_type, traits_type>; 732 733 // TODO: if T is literal, this should be constexpr 734 istream_iterator() 735 : is_{nullptr}, value_{} 736 { /* DUMMY BODY */ } 737 738 istream_iterator(istream_type& is) 739 : is_{&is}, value_{} 740 { /* DUMMY BODY */ } 741 742 istream_iterator(const istream_iterator&) = default; 743 744 ~istream_iterator() = default; 745 746 const T& operator*() const 747 { 748 return value_; 749 } 750 751 const T* operator->() const 752 { 753 return &(operator*()); 754 } 755 756 istream_iterator& operator++() 757 { 758 if (is_) 759 (*is_) >> value_; 760 761 return *this; 762 } 763 764 istream_iterator operator++(int) 765 { 766 auto tmp{*this}; 767 768 if (is_) 769 (*is_) >> value_; 770 771 return tmp; 772 } 773 774 private: 775 basic_istream<char_type, traits_type>* is_; 776 777 T value_; 778 779 friend bool operator==<>(const istream_iterator&, 780 const istream_iterator&); 781 782 friend bool operator!=<>(const istream_iterator&, 783 const istream_iterator&); 784 }; 785 786 template<class T, class Char, class Traits, class Distance> 787 bool operator==(const istream_iterator<T, Char, Traits, Distance>& lhs, 788 const istream_iterator<T, Char, Traits, Distance>& rhs) 789 { 790 return lhs.is_ == rhs.is_; 791 } 792 793 template<class T, class Char, class Traits, class Distance> 794 bool operator!=(const istream_iterator<T, Char, Traits, Distance>& lhs, 795 const istream_iterator<T, Char, Traits, Distance>& rhs) 796 { 797 return !(lhs == rhs); 798 } 799 800 /** 801 * 24.6.2, class template ostream_iterator: 802 */ 803 804 template<class T, class Char = char, class Traits = char_traits<Char>> 805 class ostream_iterator 806 : public iterator<output_iterator_tag, void, void, void, void> 807 { 808 public: 809 using char_type = Char; 810 using traits_type = Traits; 811 using ostream_type = basic_ostream<char_type, traits_type>; 812 813 ostream_iterator(ostream_type& os) 814 : os_{&os}, delim_{nullptr} 815 { /* DUMMY BODY */ } 816 817 ostream_iterator(ostream_type& os, const char_type* delim) 818 : os_{&os}, delim_{delim} 819 { /* DUMMY BODY */ } 820 821 ostream_iterator(const ostream_iterator&) = default; 822 823 ~ostream_iterator() = default; 824 825 ostream_iterator& operator=(const T& value) 826 { 827 os_ << value; 828 if (delim_) 829 os_ << delim_; 830 831 return *this; 832 } 833 834 ostream_iterator& operator*() const 835 { 836 return *this; 837 } 838 839 ostream_iterator& operator++() 840 { 841 return *this; 842 } 843 844 ostream_iterator& operator++(int) 845 { 846 return *this; 847 } 848 849 private: 850 basic_ostream<char_type, traits_type>* os_; 851 852 const char_type* delim_; 853 }; 854 855 /** 856 * 24.6.3, class template istreambuf_iterator: 857 */ 858 859 template<class Char, class Traits> 860 class istreambuf_iterator 861 : public iterator<input_iterator_tag, Char, typename Traits::off_type, Char*, Char> 862 { 863 public: 864 using char_type = Char; 865 using traits_type = Traits; 866 using int_type = typename traits_type::int_type; 867 using streambuf_type = basic_streambuf<char_type, traits_type>; 868 using istream_type = basic_istream<char_type, traits_type>; 869 870 class proxy_type 871 { 872 public: 873 proxy_type(int_type c, streambuf_type* sbuf) 874 : char_{c}, sbuf_{sbuf} 875 { /* DUMMY BODY */ } 876 877 char_type operator*() 878 { 879 return traits_type::to_char_type(char_); 880 } 881 882 private: 883 int_type char_; 884 885 streambuf_type* sbuf_; 886 }; 887 888 constexpr istreambuf_iterator() noexcept 889 : sbuf_{nullptr} 890 { /* DUMMY BODY */ } 891 892 istreambuf_iterator(const istreambuf_iterator&) noexcept = default; 893 894 ~istreambuf_iterator() = default; 895 896 istreambuf_iterator(istream_type& is) noexcept 897 : sbuf_{is.rdbuf()} 898 { /* DUMMY BODY */ } 899 900 istreambuf_iterator(streambuf_type* sbuf) noexcept 901 : sbuf_{sbuf} 902 { /* DUMMY BODY */ } 903 904 istreambuf_iterator(const proxy_type& proxy) noexcept 905 : sbuf_{proxy.sbuf_} 906 { /* DUMMY BODY */ } 907 908 char_type operator*() /* const */ // TODO: Should be const :/ 909 { 910 if (sbuf_) 911 { 912 auto res = sbuf_->sgetc(); 913 if (res == traits_type::eof()) 914 sbuf_ = nullptr; 915 916 return res; 917 } 918 else 919 return traits_type::eof(); 920 } 921 922 istreambuf_iterator& operator++() 923 { 924 if (sbuf_) 925 sbuf_->sbumpc(); 926 927 return *this; 928 } 929 930 proxy_type operator++(int) 931 { 932 if (sbuf_) 933 return proxy_type{sbuf_->sbumpc(), sbuf_}; 934 else 935 return proxy_type{traits_type::eof(), nullptr}; 936 } 937 938 bool equal(const istreambuf_iterator& rhs) const 939 { 940 if ((sbuf_ == nullptr && rhs.sbuf_ == nullptr) || 941 (sbuf_ != nullptr && rhs.sbuf_ != nullptr)) 942 return true; 943 else 944 return false; 945 } 946 947 private: 948 streambuf_type* sbuf_; 949 }; 950 951 template<class Char, class Traits> 952 bool operator==(const istreambuf_iterator<Char, Traits>& lhs, 953 const istreambuf_iterator<Char, Traits>& rhs) 954 { 955 return lhs.equal(rhs); 956 } 957 958 template<class Char, class Traits> 959 bool operator!=(const istreambuf_iterator<Char, Traits>& lhs, 960 const istreambuf_iterator<Char, Traits>& rhs) 961 { 962 return !lhs.equal(rhs); 963 } 964 965 /** 966 * 24.6.4, class template ostreambuf_iterator: 967 */ 968 969 template<class Char, class Traits> 970 class ostreambuf_iterator 971 : public iterator<output_iterator_tag, void, void, void, void> 972 { 973 public: 974 using char_type = Char; 975 using traits_type = Traits; 976 using streambuf_type = basic_streambuf<char_type, traits_type>; 977 using ostream_type = basic_ostream<char_type, traits_type>; 978 979 ostreambuf_iterator(ostream_type& os) noexcept 980 : sbuf_{os.rdbuf()} 981 { /* DUMMY BODY */ } 982 983 ostreambuf_iterator(streambuf_type* sbuf) noexcept 984 : sbuf_{sbuf} 985 { /* DUMMY BODY */ } 986 987 ostreambuf_iterator& operator=(char_type c) 988 { 989 if (!failed() && sbuf_->sputc(c) == traits_type::eof()) 990 failed_ = true; 991 992 return *this; 993 } 994 995 ostreambuf_iterator& operator*() 996 { 997 return *this; 998 } 999 1000 ostreambuf_iterator& operator++() 1001 { 1002 return *this; 1003 } 1004 1005 ostreambuf_iterator& operator++(int) 1006 { 1007 return *this; 1008 } 1009 1010 bool failed() const noexcept 1011 { 1012 return failed_; 1013 } 1014 1015 private: 1016 streambuf_type* sbuf_; 1017 1018 bool failed_{false}; 1019 }; 1020 1021 /** 1022 * 24.7, range access: 1023 */ 1024 1025 template<class Container> 1026 auto begin(Container& c) -> decltype(c.begin()) 1027 { 1028 return c.begin(); 1029 } 1030 1031 template<class Container> 1032 auto begin(const Container& c) -> decltype(c.begin()) 1033 { 1034 return c.begin(); 1035 } 1036 1037 template<class Container> 1038 auto end(Container& c) -> decltype(c.end()) 1039 { 1040 return c.end(); 1041 } 1042 1043 template<class Container> 1044 auto end(const Container& c) -> decltype(c.end()) 1045 { 1046 return c.end(); 1047 } 1048 1049 template<class T, size_t N> 1050 constexpr T* begin(T (&array)[N]) noexcept 1051 { 1052 return array; 1053 } 1054 1055 template<class T, size_t N> 1056 constexpr T* end(T (&array)[N]) noexcept 1057 { 1058 return array + N; 1059 } 1060 1061 template<class Container> 1062 constexpr auto cbegin(const Container& c) noexcept(noexcept(std::begin(c))) 1063 -> decltype(std::begin(c)) 1064 { 1065 return std::begin(c); 1066 } 1067 1068 template<class Container> 1069 constexpr auto cend(const Container& c) noexcept(noexcept(std::end(c))) 1070 -> decltype(std::end(c)) 1071 { 1072 return std::end(c); 1073 } 1074 1075 template<class Container> 1076 auto rbegin(Container& c) -> decltype(c.rbegin()) 1077 { 1078 return c.rbegin(); 1079 } 1080 1081 template<class Container> 1082 auto rbegin(const Container& c) -> decltype(c.rbegin()) 1083 { 1084 return c.rbegin(); 1085 } 1086 1087 template<class Container> 1088 auto rend(Container& c) -> decltype(c.rend()) 1089 { 1090 return c.rend(); 1091 } 1092 1093 template<class Container> 1094 auto rend(const Container& c) -> decltype(c.rend()) 1095 { 1096 return c.rend(); 1097 } 1098 1099 template<class T, size_t N> 1100 reverse_iterator<T*> rbegin(T (&array)[N]) 1101 { 1102 return reverse_iterator<T*>{array + N}; 1103 } 1104 1105 template<class T, size_t N> 1106 reverse_iterator<T*> rend(T (&array)[N]) 1107 { 1108 return reverse_iterator<T*>{array}; 1109 } 51 1110 52 1111 template<class T> 53 using get_non_const_ref_t = typename get_non_const_ref<T>::type; 1112 reverse_iterator<const T*> rbegin(initializer_list<T> init) 1113 { 1114 return reverse_iterator<const T*>{init.end()}; 1115 } 54 1116 55 1117 template<class T> 56 struct get_non_const_ptr 57 : type_is<T> 58 { /* DUMMY BODY */ }; 1118 reverse_iterator<const T*> rend(initializer_list<T> init) 1119 { 1120 return reverse_iterator<const T*>{init.begin()}; 1121 } 1122 1123 template<class Container> 1124 auto crbegin(const Container& c) -> decltype(std::rbegin(c)) 1125 { 1126 return std::rbegin(c); 1127 } 1128 1129 template<class Container> 1130 auto crend(const Container& c) -> decltype(std::rend(c)) 1131 { 1132 return std::rend(c); 1133 } 1134 1135 /** 1136 * 24.8, container access: 1137 */ 1138 1139 template<class Container> 1140 constexpr auto size(const Container& c) -> decltype(c.size()) 1141 { 1142 return c.size(); 1143 } 1144 1145 template<class T, size_t N> 1146 constexpr size_t size(T (&array)[N]) noexcept 1147 { 1148 return N; 1149 } 1150 1151 template<class Container> 1152 constexpr auto empty(const Container& c) -> decltype(c.empty()) 1153 { 1154 return c.empty(); 1155 } 1156 1157 template<class T, size_t N> 1158 constexpr bool empty(T (&array)[N]) noexcept 1159 { 1160 return false; 1161 } 59 1162 60 1163 template<class T> 61 struct get_non_const_ptr<const T*> 62 : type_is<T*> 63 { /* DUMMY BODY */ }; 1164 constexpr bool empty(initializer_list<T> init) noexcept 1165 { 1166 return init.size() == 0; 1167 } 1168 1169 template<class Container> 1170 constexpr auto data(Container& c) -> decltype(c.data()) 1171 { 1172 return c.data(); 1173 } 1174 1175 template<class Container> 1176 constexpr auto data(const Container& c) -> decltype(c.data()) 1177 { 1178 return c.data(); 1179 } 1180 1181 template<class T, size_t N> 1182 constexpr T* data(T (&array)[N]) noexcept 1183 { 1184 return array; 1185 } 64 1186 65 1187 template<class T> 66 using get_non_const_ptr_t = typename get_non_const_ptr<T>::type; 1188 constexpr const T* data(initializer_list<T> init) noexcept 1189 { 1190 return init.begin(); 1191 } 67 1192 } 68 1193
Note:
See TracChangeset
for help on using the changeset viewer.