Changeset 9317f45 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:19Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
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)
Message:

cpp: finished iterators

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/iterator.hpp

    ra57a79c r9317f45  
    3131
    3232#include <cstdlib>
     33#include <initializer_list>
     34#include <iosfwd>
    3335#include <memory>
    3436#include <type_traits>
     
    658660        return move_iterator<Iterator>(it);
    659661    }
     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    }
    6601140}
    6611141
Note: See TracChangeset for help on using the changeset viewer.