Changeset 9317f45 in mainline
- Timestamp:
- 2018-07-05T21:41:19Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8cce80b4
- Parents:
- a57a79c
- git-author:
- Dzejrou <dzejrou@…> (2017-12-04 15:49:29)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:19)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/iterator.hpp
ra57a79c r9317f45 31 31 32 32 #include <cstdlib> 33 #include <initializer_list> 34 #include <iosfwd> 33 35 #include <memory> 34 36 #include <type_traits> … … 658 660 return move_iterator<Iterator>(it); 659 661 } 662 663 /** 664 * 24.6, stream iterators: 665 */ 666 667 /** 668 * 24.6.1, class template istream_iterator: 669 */ 670 671 template<class T, class Char = char, class Traits = char_traits<Char>, 672 class Distance = ptrdiff_t> 673 class istream_iterator 674 : public iterator<input_iterator_tag, T, Distance, const T*, const T&> 675 { 676 public: 677 using char_type = Char; 678 using traits_type = Traits; 679 using istream_type = basic_istream<char_type, traits_type>; 680 681 // TODO: if T is literal, this should be constexpr 682 istream_iterator() 683 : is_{nullptr}, value_{} 684 { /* DUMMY BODY */ } 685 686 istream_iterator(istream_type& is) 687 : is_{&is}, value_{} 688 { /* DUMMY BODY */ } 689 690 istream_iterator(const istream_iterator&) = default; 691 692 ~istream_iterator() = default; 693 694 const T& operator*() const 695 { 696 return value_; 697 } 698 699 const T* operator->() const 700 { 701 return &(operator*()); 702 } 703 704 istream_iterator& operator++() 705 { 706 if (is_) 707 (*is_) >> value_; 708 709 return *this; 710 } 711 712 istream_iterator operator++(int) 713 { 714 auto tmp{*this}; 715 716 if (is_) 717 (*is_) >> value_; 718 719 return tmp; 720 } 721 722 private: 723 basic_istream<char_type, traits_type>* is_; 724 725 T value_; 726 727 friend bool operator==<>(const istream_iterator&, 728 const istream_iterator&); 729 730 friend bool operator!=<>(const istream_iterator&, 731 const istream_iterator&); 732 }; 733 734 template<class T, class Char, class Traits, class Distance> 735 bool operator==(const istream_iterator<T, Char, Traits, Distance>& lhs, 736 const istream_iterator<T, Char, Traits, Distance>& rhs) 737 { 738 return lhs.is_ == rhs.is_; 739 } 740 741 template<class T, class Char, class Traits, class Distance> 742 bool operator!=(const istream_iterator<T, Char, Traits, Distance>& lhs, 743 const istream_iterator<T, Char, Traits, Distance>& rhs) 744 { 745 return !(lhs == rhs); 746 } 747 748 /** 749 * 24.6.2, class template ostream_iterator: 750 */ 751 752 template<class T, class Char = char, class Traits = char_traits<Char>> 753 class ostream_iterator 754 : public iterator<output_iterator_tag, void, void, void, void> 755 { 756 public: 757 using char_type = Char; 758 using traits_type = Traits; 759 using ostream_type = basic_ostream<char_type, traits_type>; 760 761 ostream_iterator(ostream_type& os) 762 : os_{&os}, delim_{nullptr} 763 { /* DUMMY BODY */ } 764 765 ostream_iterator(ostream_type& os, const char_type* delim) 766 : os_{&os}, delim_{delim} 767 { /* DUMMY BODY */ } 768 769 ostream_iterator(const ostream_iterator&) = default; 770 771 ~ostream_iterator() = default; 772 773 ostream_iterator& operator=(const T& value) 774 { 775 os_ << value; 776 if (delim_) 777 os_ << delim_; 778 779 return *this; 780 } 781 782 ostream_iterator& operator*() const 783 { 784 return *this; 785 } 786 787 ostream_iterator& operator++() 788 { 789 return *this; 790 } 791 792 ostream_iterator& operator++(int) 793 { 794 return *this; 795 } 796 797 private: 798 basic_ostream<char_type, traits_type>* os_; 799 800 const char_type* delim_; 801 }; 802 803 /** 804 * 24.6.3, class template istreambuf_iterator: 805 */ 806 807 template<class Char, class Traits> 808 class istreambuf_iterator 809 : public iterator<input_iterator_tag, Char, typename Traits::off_type, Char*, Char> 810 { 811 public: 812 using char_type = Char; 813 using traits_type = Traits; 814 using int_type = typename traits_type::int_type; 815 using streambuf_type = basic_streambuf<char_type, traits_type>; 816 using istream_type = basic_istream<char_type, traits_type>; 817 818 class proxy_type 819 { 820 public: 821 char_type operator*() 822 { 823 return char_; 824 } 825 826 private: 827 proxy_type(char_type c, streambuf_type sbuf) 828 : char_{c}, sbuf_{sbuf} 829 { /* DUMMY BODY */ } 830 831 char_type char_; 832 833 streambuf_type* sbuf_; 834 }; 835 836 constexpr istreambuf_iterator() noexcept 837 : sbuf_{nullptr} 838 { /* DUMMY BODY */ } 839 840 istreambuf_iterator(const istreambuf_iterator&) noexcept = default; 841 842 ~istreambuf_iterator() = default; 843 844 istreambuf_iterator(istream_type& is) noexcept 845 : sbuf_{is.rdbuf()} 846 { /* DUMMY BODY */ } 847 848 istreambuf_iterator(streambuf_type* sbuf) noexcept 849 : sbuf_{sbuf} 850 { /* DUMMY BODY */ } 851 852 istreambuf_iterator(const proxy_type& proxy) noexcept 853 : sbuf_{proxy.sbuf_} 854 { /* DUMMY BODY */ } 855 856 char_type operator*() const 857 { 858 if (sbuf_) 859 { 860 auto res = sbuf_->sgetc(); 861 if (res == traits_type::eof()) 862 sbuf_ = nullptr; 863 864 return res; 865 } 866 else 867 return traits_type::eof(); 868 } 869 870 istreambuf_iterator& operator++() 871 { 872 if (sbuf_) 873 sbuf_->sbumpc(); 874 875 return *this; 876 } 877 878 proxy_type operator++(int) 879 { 880 if (sbuf_) 881 return proxy_type{sbuf_->sbumpc(), sbuf_}; 882 else 883 return proxy_type{traits_type::eof(), nullptr}; 884 } 885 886 bool equal(const istreambuf_iterator& rhs) const 887 { 888 if ((sbuf_ == nullptr && rhs.sbuf_ == nullptr) || 889 (sbuf_ != nullptr && rhs.sbuf_ != nullptr)) 890 return true; 891 else 892 return false; 893 } 894 895 private: 896 streambuf_type* sbuf_; 897 }; 898 899 template<class Char, class Traits> 900 bool operator==(const istreambuf_iterator<Char, Traits>& lhs, 901 const istreambuf_iterator<Char, Traits>& rhs) 902 { 903 return lhs.equal(rhs); 904 } 905 906 template<class Char, class Traits> 907 bool operator!=(const istreambuf_iterator<Char, Traits>& lhs, 908 const istreambuf_iterator<Char, Traits>& rhs) 909 { 910 return !lhs.equal(rhs); 911 } 912 913 /** 914 * 24.6.4, class template ostreambuf_iterator: 915 */ 916 917 template<class Char, class Traits> 918 class ostreambuf_iterator 919 : public iterator<output_iterator_tag, void, void, void, void> 920 { 921 public: 922 using char_type = Char; 923 using traits_type = Traits; 924 using streambuf_type = basic_streambuf<char_type, traits_type>; 925 using ostream_type = basic_ostream<char_type, traits_type>; 926 927 ostreambuf_iterator(ostream_type& os) noexcept 928 : sbuf_{os.rdbuf()} 929 { /* DUMMY BODY */ } 930 931 ostreambuf_iterator(streambuf_type* sbuf) noexcept 932 : sbuf_{sbuf} 933 { /* DUMMY BODY */ } 934 935 ostreambuf_iterator& operator=(char_type c) 936 { 937 if (!failed() && sbuf_->sputc(c) == traits_type::eof()) 938 failed_ = true; 939 940 return *this; 941 } 942 943 ostreambuf_iterator& operator*() 944 { 945 return *this; 946 } 947 948 ostreambuf_iterator& operator++() 949 { 950 return *this; 951 } 952 953 ostreambuf_iterator& operator++(int) 954 { 955 return *this; 956 } 957 958 bool failed() const noexcept 959 { 960 return failed_; 961 } 962 963 private: 964 streambuf_type* sbuf_; 965 966 bool failed_{false}; 967 }; 968 969 /** 970 * 24.7, range access: 971 */ 972 973 template<class Container> 974 auto begin(Container& c) -> decltype(c.begin()) 975 { 976 return c.begin(); 977 } 978 979 template<class Container> 980 auto begin(const Container& c) -> decltype(c.begin()) 981 { 982 return c.begin(); 983 } 984 985 template<class Container> 986 auto end(Container& c) -> decltype(c.end()) 987 { 988 return c.end(); 989 } 990 991 template<class Container> 992 auto end(const Container& c) -> decltype(c.end()) 993 { 994 return c.end(); 995 } 996 997 template<class T, size_t N> 998 constexpr T* begin(T (&array)[N]) noexcept 999 { 1000 return array; 1001 } 1002 1003 template<class T, size_t N> 1004 constexpr T* end(T (&array)[N]) noexcept 1005 { 1006 return array + N; 1007 } 1008 1009 template<class Container> 1010 constexpr auto cbegin(const Container& c) noexcept(noexcept(std::begin(c))) 1011 -> decltype(std::begin(c)) 1012 { 1013 return std::begin(c); 1014 } 1015 1016 template<class Container> 1017 constexpr auto cend(const Container& c) noexcept(noexcept(std::end(c))) 1018 -> decltype(std::end(c)) 1019 { 1020 return std::end(c); 1021 } 1022 1023 template<class Container> 1024 auto rbegin(Container& c) -> decltype(c.rbegin()) 1025 { 1026 return c.rbegin(); 1027 } 1028 1029 template<class Container> 1030 auto rbegin(const Container& c) -> decltype(c.rbegin()) 1031 { 1032 return c.rbegin(); 1033 } 1034 1035 template<class Container> 1036 auto rend(Container& c) -> decltype(c.rend()) 1037 { 1038 return c.rend(); 1039 } 1040 1041 template<class Container> 1042 auto rend(const Container& c) -> decltype(c.rend()) 1043 { 1044 return c.rend(); 1045 } 1046 1047 template<class T, size_t N> 1048 reverse_iterator<T*> rbegin(T (&array)[N]) 1049 { 1050 return reverse_iterator<T*>{array + N}; 1051 } 1052 1053 template<class T, size_t N> 1054 reverse_iterator<T*> rend(T (&array)[N]) 1055 { 1056 return reverse_iterator<T*>{array}; 1057 } 1058 1059 template<class T> 1060 reverse_iterator<const T*> rbegin(initializer_list<T> init) 1061 { 1062 return reverse_iterator<const T*>{init.end()}; 1063 } 1064 1065 template<class T> 1066 reverse_iterator<const T*> rend(initializer_list<T> init) 1067 { 1068 return reverse_iterator<const T*>{init.begin()}; 1069 } 1070 1071 template<class Container> 1072 auto crbegin(const Container& c) -> decltype(std::rbegin(c)) 1073 { 1074 return std::rbegin(c); 1075 } 1076 1077 template<class Container> 1078 auto crend(const Container& c) -> decltype(std::rend(c)) 1079 { 1080 return std::rend(c); 1081 } 1082 1083 /** 1084 * 24.8, container access: 1085 */ 1086 1087 template<class Container> 1088 constexpr auto size(const Container& c) -> decltype(c.size()) 1089 { 1090 return c.size(); 1091 } 1092 1093 template<class T, size_t N> 1094 constexpr size_t size(T (&array)[N]) noexcept 1095 { 1096 return N; 1097 } 1098 1099 template<class Container> 1100 constexpr auto empty(const Container& c) -> decltype(c.empty()) 1101 { 1102 return c.empty(); 1103 } 1104 1105 template<class T, size_t N> 1106 constexpr bool empty(T (&array)[N]) noexcept 1107 { 1108 return false; 1109 } 1110 1111 template<class T> 1112 constexpr bool empty(initializer_list<T> init) noexcept 1113 { 1114 return init.size() == 0; 1115 } 1116 1117 template<class Container> 1118 constexpr auto data(Container& c) -> decltype(c.data()) 1119 { 1120 return c.data(); 1121 } 1122 1123 template<class Container> 1124 constexpr auto data(const Container& c) -> decltype(c.data()) 1125 { 1126 return c.data(); 1127 } 1128 1129 template<class T, size_t N> 1130 constexpr T* data(T (&array)[N]) noexcept 1131 { 1132 return array; 1133 } 1134 1135 template<class T> 1136 constexpr const T* data(initializer_list<T> init) noexcept 1137 { 1138 return init.begin(); 1139 } 660 1140 } 661 1141
Note:
See TracChangeset
for help on using the changeset viewer.