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

cpp: refactored the library layout, everything from the impl directory was moved to the bits directory for the sake of consistency, updated copyright notices and include guards

File:
1 edited

Legend:

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

    r4f461384 rb57a3ee  
    3030#define LIBCPP_BITS_ITERATOR
    3131
    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
     39namespace std
    3540{
    3641    /**
    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    };
    4173
    4274    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    };
    4683
    4784    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    }
    511110
    521111    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    }
    541116
    551117    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    }
    591162
    601163    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    }
    641186
    651187    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    }
    671192}
    681193
Note: See TracChangeset for help on using the changeset viewer.