Changeset ee906a6 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:18Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4e68727
Parents:
43ba118
git-author:
Jaroslav Jindrak <dzejrou@…> (2017-11-23 23:14:24)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:18)
Message:

cpp: added the rest of the iterator adaptors

File:
1 edited

Legend:

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

    r43ba118 ree906a6  
    3131
    3232#include <cstdlib>
     33#include <memory>
     34#include <type_traits>
    3335
    3436namespace std
     
    105107
    106108    /**
    107      * 25.5.1, reverse iterator:
     109     * 24.5.1, reverse iterator:
    108110     */
    109111
     
    217219            }
    218220
    219             // TODO: unspecified operator[difference_type] const;
    220221            auto operator[](difference_type n) const
    221222            {
     
    251252    template<class Iterator1, class Iterator2>
    252253    bool operator>(const reverse_iterator<Iterator1>& lhs,
    253                     const reverse_iterator<Iterator2>& rhs)
     254                   const reverse_iterator<Iterator2>& rhs)
    254255    {
    255256        return lhs.base() < rhs.base();
     
    272273    template<class Iterator1, class Iterator2>
    273274    auto operator-(const reverse_iterator<Iterator1>& lhs,
    274                     const reverse_iterator<Iterator2>& rhs)
     275                   const reverse_iterator<Iterator2>& rhs)
    275276        -> decltype(rhs.base() - lhs.base())
    276277    {
     
    293294    }
    294295
    295     // TODO: other kind of iterator adaptors!
     296    /**
     297     * 24.5.2, insert iterators:
     298     */
     299
     300    /**
     301     * 24.5.2.1, back insert iterator:
     302     */
     303
     304    template<class Container>
     305    class back_insert_iterator
     306        : public iterator<output_iterator_tag, void, void, void, void>
     307    {
     308        public:
     309            using container_type = Container;
     310
     311            explicit back_insert_iterator(Container& cont)
     312                : container{std::addressof(cont)}
     313            { /* DUMMY BODY */ }
     314
     315            back_insert_iterator& operator=(const typename container_type::value_type& value)
     316            {
     317                container->push_back(value);
     318                return *this;
     319            }
     320
     321            back_insert_iterator& operator=(typename container_type::value_type&& value)
     322            {
     323                container->push_back(move(value));
     324                return *this;
     325            }
     326
     327            back_insert_iterator& operator*()
     328            {
     329                return *this;
     330            }
     331
     332            back_insert_iterator& operator++()
     333            {
     334                return *this;
     335            }
     336
     337            back_insert_iterator operator++(int)
     338            {
     339                return *this;
     340            }
     341
     342        protected:
     343            Container* container;
     344    };
     345
     346    template<class Container>
     347    back_insert_iterator<Container> back_inserter(Container& cont)
     348    {
     349        return back_insert_iterator<Container>(cont);
     350    }
     351
     352    /**
     353     * 24.5.2.3, front insert iterator:
     354     */
     355
     356    template<class Container>
     357    class front_insert_iterator
     358        : public iterator<output_iterator_tag, void, void, void, void>
     359    {
     360        public:
     361            using container_type = Container;
     362
     363            explicit front_insert_iterator(Container& cont)
     364                : container{std::addressof(cont)}
     365            { /* DUMMY BODY */ }
     366
     367            front_insert_iterator& operator=(const typename container_type::value_type& value)
     368            {
     369                container->push_front(value);
     370                return *this;
     371            }
     372
     373            front_insert_iterator& operator=(typename container_type::value_type&& value)
     374            {
     375                container->push_front(move(value));
     376                return *this;
     377            }
     378
     379            front_insert_iterator& operator*()
     380            {
     381                return *this;
     382            }
     383
     384            front_insert_iterator& operator++()
     385            {
     386                return *this;
     387            }
     388
     389            front_insert_iterator operator++(int)
     390            {
     391                return *this;
     392            }
     393
     394        protected:
     395            Container* container;
     396    };
     397
     398    template<class Container>
     399    front_insert_iterator<Container> front_inserter(Container& cont)
     400    {
     401        return front_insert_iterator<Container>(cont);
     402    }
     403
     404    /**
     405     * 24.5.2.5, front insert iterator:
     406     */
     407
     408    template<class Container>
     409    class insert_iterator
     410        : public iterator<output_iterator_tag, void, void, void, void>
     411    {
     412        public:
     413            using container_type = Container;
     414
     415            explicit insert_iterator(Container& cont, typename Container::iterator i)
     416                : container{std::addressof(cont)}, iter{i}
     417            { /* DUMMY BODY */ }
     418
     419            insert_iterator& operator=(const typename container_type::value_type& value)
     420            {
     421                iter = container.insert(iter, value);
     422                ++iter;
     423
     424                return *this;
     425            }
     426
     427            insert_iterator& operator=(typename container_type::value_type&& value)
     428            {
     429                iter = container.insert(iter, move(value));
     430                ++iter;
     431
     432                return *this;
     433            }
     434
     435            insert_iterator& operator*()
     436            {
     437                return *this;
     438            }
     439
     440            insert_iterator& operator++()
     441            {
     442                return *this;
     443            }
     444
     445            insert_iterator operator++(int)
     446            {
     447                return *this;
     448            }
     449
     450        protected:
     451            Container* container;
     452            typename Container::iterator iter;
     453    };
     454
     455    template<class Container>
     456    insert_iterator<Container> inserter(Container& cont, typename Container::iterator i)
     457    {
     458        return insert_iterator<Container>(cont, i);
     459    }
     460
     461    /**
     462     * 24.5.3.1, move iterator:
     463     */
     464
     465    namespace aux
     466    {
     467        template<class Iterator, class = void>
     468        struct move_it_get_reference
     469        {
     470            using type = typename iterator_traits<Iterator>::reference;
     471        };
     472
     473        template<class Iterator>
     474        struct move_it_get_reference<
     475            Iterator, enable_if_t<
     476                is_reference<typename iterator_traits<Iterator>::reference>::value,
     477                void
     478            >
     479        >
     480        {
     481            using type = remove_reference_t<typename iterator_traits<Iterator>::reference>;
     482        };
     483    }
     484
     485    template<class Iterator>
     486    class move_iterator
     487    {
     488        public:
     489            using iterator_type     = Iterator;
     490            using pointer           = iterator_type;
     491            using difference_type   = typename iterator_traits<iterator_type>::difference_type;
     492            using value_type        = typename iterator_traits<iterator_type>::value_type;
     493            using iterator_category = typename iterator_traits<iterator_type>::iterator_category;
     494            using reference         = typename aux::move_it_get_reference<iterator_type>::type;
     495
     496            move_iterator()
     497                : current_{}
     498            { /* DUMMY BODY */ }
     499
     500            explicit move_iterator(iterator_type i)
     501                : current_{i}
     502            { /* DUMMY BODY */ }
     503
     504            // TODO: both require is_convertible
     505            template<class U>
     506            move_iterator(const move_iterator<U>& other)
     507                : current_{other.current_}
     508            { /* DUMMY BODY */ }
     509
     510            template<class U>
     511            move_iterator& operator=(const move_iterator<U>& other)
     512            {
     513                current_ = other.current_;
     514
     515                return *this;
     516            }
     517
     518            iterator_type base() const
     519            {
     520                return current_;
     521            }
     522
     523            reference operator*() const
     524            {
     525                return static_cast<reference>(*current_);
     526            }
     527
     528            pointer operator->() const
     529            {
     530                return current_;
     531            }
     532
     533            move_iterator& operator++()
     534            {
     535                ++current_;
     536
     537                return *this;
     538            }
     539
     540            move_iterator operator++(int)
     541            {
     542                auto tmp = *this;
     543                ++current_;
     544
     545                return tmp;
     546            }
     547
     548            move_iterator& operator--()
     549            {
     550                --current_;
     551
     552                return *this;
     553            }
     554
     555            move_iterator operator--(int)
     556            {
     557                auto tmp = *this;
     558                --current_;
     559
     560                return tmp;
     561            }
     562
     563            move_iterator operator+(difference_type n) const
     564            {
     565                return move_iterator(current_ + n);
     566            }
     567
     568            move_iterator& operator+=(difference_type n)
     569            {
     570                current_ += n;
     571
     572                return *this;
     573            }
     574
     575            move_iterator operator-(difference_type n) const
     576            {
     577                return move_iterator(current_ - n);
     578            }
     579
     580            move_iterator& operator-=(difference_type n)
     581            {
     582                current_ -= n;
     583
     584                return *this;
     585            }
     586
     587            auto operator[](difference_type idx) const
     588            {
     589                return move(current_[idx]);
     590            }
     591
     592        private:
     593            iterator_type current_;
     594    };
     595
     596    template<class Iterator1, class Iterator2>
     597    bool operator==(const move_iterator<Iterator1>& lhs,
     598                    const move_iterator<Iterator2>& rhs)
     599    {
     600        return lhs.base() == rhs.base();
     601    }
     602
     603    template<class Iterator1, class Iterator2>
     604    bool operator!=(const move_iterator<Iterator1>& lhs,
     605                    const move_iterator<Iterator2>& rhs)
     606    {
     607        return lhs.base() != rhs.base();
     608    }
     609
     610    template<class Iterator1, class Iterator2>
     611    bool operator<(const move_iterator<Iterator1>& lhs,
     612                   const move_iterator<Iterator2>& rhs)
     613    {
     614        return lhs.base() < rhs.base();
     615    }
     616
     617    template<class Iterator1, class Iterator2>
     618    bool operator<=(const move_iterator<Iterator1>& lhs,
     619                    const move_iterator<Iterator2>& rhs)
     620    {
     621        return !(rhs < lhs);
     622    }
     623
     624    template<class Iterator1, class Iterator2>
     625    bool operator>(const move_iterator<Iterator1>& lhs,
     626                   const move_iterator<Iterator2>& rhs)
     627    {
     628        return rhs < lhs;
     629    }
     630
     631    template<class Iterator1, class Iterator2>
     632    bool operator>=(const move_iterator<Iterator1>& lhs,
     633                    const move_iterator<Iterator2>& rhs)
     634    {
     635        return !(lhs < rhs);
     636    }
     637
     638    template<class Iterator1, class Iterator2>
     639    auto operator-(const move_iterator<Iterator1>& lhs,
     640                   const move_iterator<Iterator2>& rhs)
     641        -> decltype(rhs.base() - lhs.base())
     642    {
     643        return lhs.base() - rhs.base();
     644    }
     645
     646    template<class Iterator>
     647    move_iterator<Iterator> operator+(
     648        typename move_iterator<Iterator>::difference_type n,
     649        const move_iterator<Iterator>& it
     650    )
     651    {
     652        return it + n;
     653    }
     654
     655    template<class Iterator>
     656    move_iterator<Iterator> make_move_iterator(Iterator it)
     657    {
     658        return move_iterator<Iterator>(it);
     659    }
    296660}
    297661
Note: See TracChangeset for help on using the changeset viewer.