Changeset af0fbaac in mainline


Ignore:
Timestamp:
2018-07-05T21:41:22Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cacb5d0
Parents:
4f080f2a
git-author:
Dzejrou <dzejrou@…> (2018-04-30 19:47:27)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
Message:

cpp: added multiset

File:
1 edited

Legend:

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

    r4f080f2a raf0fbaac  
    522522        return false;
    523523    }
     524    /**
     525     * 23.4.7, class template multiset:
     526     */
     527
     528    template<
     529        class Key,
     530        class Compare = less<Key>,
     531        class Alloc = allocator<Key>
     532    >
     533    class multiset
     534    {
     535        public:
     536            using key_type        = Key;
     537            using value_type      = Key;
     538            using key_compare     = Compare;
     539            using value_compare   = Compare;
     540            using allocator_type  = Alloc;
     541            using pointer         = typename allocator_traits<allocator_type>::pointer;
     542            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
     543            using reference       = value_type&;
     544            using const_reference = const value_type&;
     545            using size_type       = size_t;
     546            using difference_type = ptrdiff_t;
     547
     548            /**
     549             * Note: Both the iterator and const_iterator (and their local variants)
     550             *       types are constant iterators, the standard does not require them
     551             *       to be the same type, but why not? :)
     552             */
     553            using iterator             = aux::rbtree_const_iterator<
     554                value_type, const_reference, const_pointer, size_type
     555            >;
     556            using const_iterator       = iterator;
     557
     558            using reverse_iterator       = std::reverse_iterator<iterator>;
     559            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
     560
     561            multiset()
     562                : multiset{key_compare{}}
     563            { /* DUMMY BODY */ }
     564
     565            explicit multiset(const key_compare& comp,
     566                              const allocator_type& alloc = allocator_type{})
     567                : tree_{comp}, allocator_{alloc}
     568            { /* DUMMY BODY */ }
     569
     570            template<class InputIterator>
     571            multiset(InputIterator first, InputIterator last,
     572                     const key_compare& comp = key_compare{},
     573                     const allocator_type& alloc = allocator_type{})
     574                : multiset{comp, alloc}
     575            {
     576                insert(first, last);
     577            }
     578
     579            multiset(const multiset& other)
     580                : multiset{other, other.allocator_}
     581            { /* DUMMY BODY */ }
     582
     583            multiset(multiset&& other)
     584                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
     585            { /* DUMMY BODY */ }
     586
     587            explicit multiset(const allocator_type& alloc)
     588                : tree_{}, allocator_{alloc}
     589            { /* DUMMY BODY */ }
     590
     591            multiset(const multiset& other, const allocator_type& alloc)
     592                : tree_{other.tree_}, allocator_{alloc}
     593            { /* DUMMY BODY */ }
     594
     595            multiset(multiset&& other, const allocator_type& alloc)
     596                : tree_{move(other.tree_)}, allocator_{alloc}
     597            { /* DUMMY BODY */ }
     598
     599            multiset(initializer_list<value_type> init,
     600                     const key_compare& comp = key_compare{},
     601                     const allocator_type& alloc = allocator_type{})
     602                : multiset{comp, alloc}
     603            {
     604                insert(init.begin(), init.end());
     605            }
     606
     607            template<class InputIterator>
     608            multiset(InputIterator first, InputIterator last,
     609                     const allocator_type& alloc)
     610                : multiset{first, last, key_compare{}, alloc}
     611            { /* DUMMY BODY */ }
     612
     613            multiset(initializer_list<value_type> init,
     614                     const allocator_type& alloc)
     615                : multiset{init, key_compare{}, alloc}
     616            { /* DUMMY BODY */ }
     617
     618            ~multiset()
     619            { /* DUMMY BODY */ }
     620
     621            multiset& operator=(const multiset& other)
     622            {
     623                tree_ = other.tree_;
     624                allocator_ = other.allocator_;
     625
     626                return *this;
     627            }
     628
     629            multiset& operator=(multiset&& other)
     630                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
     631                         is_nothrow_move_assignable<key_compare>::value)
     632            {
     633                tree_ = move(other.tree_);
     634                allocator_ = move(other.allocator_);
     635
     636                return *this;
     637            }
     638
     639            multiset& operator=(initializer_list<value_type>& init)
     640            {
     641                tree_.clear();
     642
     643                insert(init.begin(), init.end());
     644
     645                return *this;
     646            }
     647
     648            allocator_type get_allocator() const noexcept
     649            {
     650                return allocator_;
     651            }
     652
     653            iterator begin() noexcept
     654            {
     655                return tree_.begin();
     656            }
     657
     658            const_iterator begin() const noexcept
     659            {
     660                return tree_.begin();
     661            }
     662
     663            iterator end() noexcept
     664            {
     665                return tree_.end();
     666            }
     667
     668            const_iterator end() const noexcept
     669            {
     670                return tree_.end();
     671            }
     672
     673            reverse_iterator rbegin() noexcept
     674            {
     675                return tree_.rbegin();
     676            }
     677
     678            const_reverse_iterator rbegin() const noexcept
     679            {
     680                return tree_.rbegin();
     681            }
     682
     683            reverse_iterator rend() noexcept
     684            {
     685                return tree_.rend();
     686            }
     687
     688            const_reverse_iterator rend() const noexcept
     689            {
     690                return tree_.rend();
     691            }
     692
     693            const_iterator cbegin() const noexcept
     694            {
     695                return tree_.cbegin();
     696            }
     697
     698            const_iterator cend() const noexcept
     699            {
     700                return tree_.cend();
     701            }
     702
     703            const_reverse_iterator crbegin() const noexcept
     704            {
     705                return tree_.crbegin();
     706            }
     707
     708            const_reverse_iterator crend() const noexcept
     709            {
     710                return tree_.crend();
     711            }
     712
     713            bool empty() const noexcept
     714            {
     715                return tree_.empty();
     716            }
     717
     718            size_type size() const noexcept
     719            {
     720                return tree_.size();
     721            }
     722
     723            size_type max_size() const noexcept
     724            {
     725                return tree_.max_size(allocator_);
     726            }
     727
     728            template<class... Args>
     729            iterator emplace(Args&&... args)
     730            {
     731                return tree_.emplace(forward<Args>(args)...);
     732            }
     733
     734            template<class... Args>
     735            iterator emplace_hint(const_iterator, Args&&... args)
     736            {
     737                return emplace(forward<Args>(args)...);
     738            }
     739
     740            iterator insert(const value_type& val)
     741            {
     742                return tree_.insert(val);
     743            }
     744
     745            iterator insert(value_type&& val)
     746            {
     747                return tree_.insert(forward<value_type>(val));
     748            }
     749
     750            iterator insert(const_iterator, const value_type& val)
     751            {
     752                return insert(val);
     753            }
     754
     755            iterator insert(const_iterator, value_type&& val)
     756            {
     757                return insert(forward<value_type>(val));
     758            }
     759
     760            template<class InputIterator>
     761            void insert(InputIterator first, InputIterator last)
     762            {
     763                while (first != last)
     764                    insert(*first++);
     765            }
     766
     767            void insert(initializer_list<value_type> init)
     768            {
     769                insert(init.begin(), init.end());
     770            }
     771
     772            iterator erase(const_iterator position)
     773            {
     774                return tree_.erase(position);
     775            }
     776
     777            size_type erase(const key_type& key)
     778            {
     779                return tree_.erase(key);
     780            }
     781
     782            iterator erase(const_iterator first, const_iterator last)
     783            {
     784                while (first != last)
     785                    first = erase(first);
     786
     787                return iterator{
     788                    first.node(), first.end()
     789                };
     790            }
     791
     792            void swap(multiset& other)
     793                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
     794                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
     795            {
     796                tree_.swap(other.tree_);
     797                std::swap(allocator_, other.allocator_);
     798            }
     799
     800            void clear() noexcept
     801            {
     802                tree_.clear();
     803            }
     804
     805            key_compare key_comp() const
     806            {
     807                return tree_.key_comp();
     808            }
     809
     810            value_compare value_comp() const
     811            {
     812                return tree_.value_comp();
     813            }
     814
     815            iterator find(const key_type& key)
     816            {
     817                return tree_.find(key);
     818            }
     819
     820            const_iterator find(const key_type& key) const
     821            {
     822                return tree_.find(key);
     823            }
     824
     825            template<class K>
     826            iterator find(
     827                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     828            )
     829            {
     830                return tree_.find(key);
     831            }
     832
     833            template<class K>
     834            const_iterator find(
     835                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     836            ) const
     837            {
     838                return tree_.find(key);
     839            }
     840
     841            size_type count(const key_type& key) const
     842            {
     843                return tree_.count(key);
     844            }
     845
     846            template<class K>
     847            size_type count(
     848                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     849            ) const
     850            {
     851                return tree_.count(key);
     852            }
     853
     854            iterator lower_bound(const key_type& key)
     855            {
     856                return tree_.lower_bound(key);
     857            }
     858
     859            const_iterator lower_bound(const key_type& key) const
     860            {
     861                return tree_.lower_bound(key);
     862            }
     863
     864            template<class K>
     865            iterator lower_bound(
     866                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     867            )
     868            {
     869                return tree_.lower_bound(key);
     870            }
     871
     872            template<class K>
     873            const_iterator lower_bound(
     874                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     875            ) const
     876            {
     877                return tree_.lower_bound(key);
     878            }
     879
     880            iterator upper_bound(const key_type& key)
     881            {
     882                return tree_.upper_bound(key);
     883            }
     884
     885            const_iterator upper_bound(const key_type& key) const
     886            {
     887                return tree_.upper_bound(key);
     888            }
     889
     890            template<class K>
     891            iterator upper_bound(
     892                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     893            )
     894            {
     895                return tree_.upper_bound(key);
     896            }
     897
     898            template<class K>
     899            const_iterator upper_bound(
     900                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     901            ) const
     902            {
     903                return tree_.upper_bound(key);
     904            }
     905
     906            pair<iterator, iterator> equal_range(const key_type& key)
     907            {
     908                return tree_.equal_range(key);
     909            }
     910
     911            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
     912            {
     913                return tree_.equal_range(key);
     914            }
     915
     916            template<class K>
     917            pair<iterator, iterator> equal_range(
     918                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     919            )
     920            {
     921                return tree_.equal_range(key);
     922            }
     923
     924            template<class K>
     925            pair<const_iterator, const_iterator> equal_range(
     926                enable_if_t<aux::is_transparent_v<key_compare>, const K&> key
     927            ) const
     928            {
     929                return tree_.equal_range(key);
     930            }
     931
     932        private:
     933            using tree_type = aux::rbtree<
     934                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
     935                key_compare, allocator_type, size_type,
     936                iterator, const_iterator,
     937                aux::rbtree_multi_policy
     938            >;
     939
     940            tree_type tree_;
     941            allocator_type allocator_;
     942
     943            template<class K, class C, class A>
     944            friend bool operator==(const multiset<K, C, A>&,
     945                                   const multiset<K, C, A>&);
     946    };
     947
     948    template<class Key, class Compare, class Allocator>
     949    bool operator==(const multiset<Key, Compare, Allocator>& lhs,
     950                    const multiset<Key, Compare, Allocator>& rhs)
     951    {
     952        return lhs.tree_.is_eq_to(rhs.tree_);
     953    }
     954
     955    template<class Key, class Compare, class Allocator>
     956    bool operator<(const multiset<Key, Compare, Allocator>& lhs,
     957                   const multiset<Key, Compare, Allocator>& rhs)
     958    {
     959        // TODO: need lexicographical_compare
     960        return false;
     961    }
     962
     963    template<class Key, class Compare, class Allocator>
     964    bool operator!=(const multiset<Key, Compare, Allocator>& lhs,
     965                    const multiset<Key, Compare, Allocator>& rhs)
     966    {
     967        return !(lhs == rhs);
     968    }
     969
     970    template<class Key, class Compare, class Allocator>
     971    bool operator>(const multiset<Key, Compare, Allocator>& lhs,
     972                   const multiset<Key, Compare, Allocator>& rhs)
     973    {
     974        // TODO: need lexicographical_compare
     975        return false;
     976    }
     977
     978    template<class Key, class Compare, class Allocator>
     979    bool operator>=(const multiset<Key, Compare, Allocator>& lhs,
     980                    const multiset<Key, Compare, Allocator>& rhs)
     981    {
     982        // TODO: need lexicographical_compare
     983        return false;
     984    }
     985
     986    template<class Key, class Compare, class Allocator>
     987    bool operator<=(const multiset<Key, Compare, Allocator>& lhs,
     988                    const multiset<Key, Compare, Allocator>& rhs)
     989    {
     990        // TODO: need lexicographical_compare
     991        return false;
     992    }
    524993}
Note: See TracChangeset for help on using the changeset viewer.