Changeset 90adbd7 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:21Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04fa158
Parents:
2d46556
git-author:
Dzejrou <dzejrou@…> (2018-04-26 15:27:45)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:21)
Message:

cpp: added unordered_multiset, thanks to the aux::hash_table refactoring, this is a pure copypasta with a substituted name

File:
1 edited

Legend:

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

    r2d46556 r90adbd7  
    465465        class Alloc = allocator<Key>
    466466    >
    467     class unordered_multiset;
     467    class unordered_multiset
     468    {
     469        public:
     470            using key_type        = Key;
     471            using value_type      = Key;
     472            using hasher          = Hash;
     473            using key_equal       = Pred;
     474            using allocator_type  = Alloc;
     475            using pointer         = typename allocator_traits<allocator_type>::pointer;
     476            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
     477            using reference       = value_type&;
     478            using const_reference = const value_type&;
     479            using size_type       = size_t;
     480            using difference_type = ptrdiff_t;
     481
     482            /**
     483             * Note: Both the iterator and const_iterator (and their local variants)
     484             *       types are constant iterators, the standard does not require them
     485             *       to be the same type, but why not? :)
     486             */
     487            using iterator             = aux::hash_table_const_iterator<
     488                value_type, const_reference, const_pointer, size_type
     489            >;
     490            using const_iterator       = iterator;
     491            using local_iterator       = aux::hash_table_const_local_iterator<
     492                value_type, const_reference, const_pointer
     493            >;
     494            using const_local_iterator = local_iterator;
     495
     496            /**
     497             * Note: We need () to delegate the constructor,
     498             *       otherwise it could be deduced as the initializer
     499             *       list constructor when size_type is convertible
     500             *       to value_type.
     501             */
     502            unordered_multiset()
     503                : unordered_multiset(default_bucket_count_)
     504            { /* DUMMY BODY */ }
     505
     506            explicit unordered_multiset(size_type bucket_count,
     507                                        const hasher& hf = hasher{},
     508                                        const key_equal& eql = key_equal{},
     509                                        const allocator_type& alloc = allocator_type{})
     510                : table_{bucket_count, hf, eql}, allocator_{alloc}
     511            { /* DUMMY BODY */ }
     512
     513            template<class InputIterator>
     514            unordered_multiset(InputIterator first, InputIterator last,
     515                               size_type bucket_count = default_bucket_count_,
     516                               const hasher& hf = hasher{},
     517                               const key_equal& eql = key_equal{},
     518                               const allocator_type& alloc = allocator_type{})
     519                : unordered_multiset{bucket_count, hf, eql, alloc}
     520            {
     521                insert(first, last);
     522            }
     523
     524            unordered_multiset(const unordered_multiset& other)
     525                : unordered_multiset{other, other.allocator_}
     526            { /* DUMMY BODY */ }
     527
     528            unordered_multiset(unordered_multiset&& other)
     529                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
     530            { /* DUMMY BODY */ }
     531
     532            explicit unordered_multiset(const allocator_type& alloc)
     533                : table_{default_bucket_count_}, allocator_{alloc}
     534            { /* DUMMY BODY */ }
     535
     536            unordered_multiset(const unordered_multiset& other, const allocator_type& alloc)
     537                : table_{other.table_}, allocator_{alloc}
     538            { /* DUMMY BODY */ }
     539
     540            unordered_multiset(unordered_multiset&& other, const allocator_type& alloc)
     541                : table_{move(other.table_)}, allocator_{alloc}
     542            { /* DUMMY BODY */ }
     543
     544            unordered_multiset(initializer_list<value_type> init,
     545                               size_type bucket_count = default_bucket_count_,
     546                               const hasher& hf = hasher{},
     547                               const key_equal& eql = key_equal{},
     548                               const allocator_type& alloc = allocator_type{})
     549                : unordered_multiset{bucket_count, hf, eql, alloc}
     550            {
     551                insert(init.begin(), init.end());
     552            }
     553
     554            unordered_multiset(size_type bucket_count, const allocator_type& alloc)
     555                : unordered_multiset{bucket_count, hasher{}, key_equal{}, alloc}
     556            { /* DUMMY BODY */ }
     557
     558            unordered_multiset(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
     559                : unordered_multiset{bucket_count, hf, key_equal{}, alloc}
     560            { /* DUMMY BODY */ }
     561
     562            template<class InputIterator>
     563            unordered_multiset(InputIterator first, InputIterator last,
     564                               size_type bucket_count, const allocator_type& alloc)
     565                : unordered_multiset{first, last, bucket_count, hasher{}, key_equal{}, alloc}
     566            { /* DUMMY BODY */ }
     567
     568            template<class InputIterator>
     569            unordered_multiset(InputIterator first, InputIterator last,
     570                               size_type bucket_count, const hasher& hf, const allocator_type& alloc)
     571                : unordered_multiset{first, last, bucket_count, hf, key_equal{}, alloc}
     572            { /* DUMMY BODY */ }
     573
     574            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
     575                               const allocator_type& alloc)
     576                : unordered_multiset{init, bucket_count, hasher{}, key_equal{}, alloc}
     577            { /* DUMMY BODY */ }
     578
     579            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
     580                               const hasher& hf, const allocator_type& alloc)
     581                : unordered_multiset{init, bucket_count, hf, key_equal{}, alloc}
     582            { /* DUMMY BODY */ }
     583
     584            ~unordered_multiset()
     585            { /* DUMMY BODY */ }
     586
     587            unordered_multiset& operator=(const unordered_multiset& other)
     588            {
     589                table_ = other.table_;
     590                allocator_ = other.allocator_;
     591
     592                return *this;
     593            }
     594
     595            unordered_multiset& operator=(unordered_multiset&& other)
     596                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
     597                         is_nothrow_move_assignable<hasher>::value &&
     598                         is_nothrow_move_assignable<key_equal>::value)
     599            {
     600                table_ = move(other.table_);
     601                allocator_ = move(other.allocator_);
     602
     603                return *this;
     604            }
     605
     606            unordered_multiset& operator=(initializer_list<value_type>& init)
     607            {
     608                table_.clear();
     609                table_.reserve(init.size());
     610
     611                insert(init.begin(), init.end());
     612
     613                return *this;
     614            }
     615
     616            allocator_type get_allocator() const noexcept
     617            {
     618                return allocator_;
     619            }
     620
     621            bool empty() const noexcept
     622            {
     623                return table_.empty();
     624            }
     625
     626            size_type size() const noexcept
     627            {
     628                return table_.size();
     629            }
     630
     631            size_type max_size() const noexcept
     632            {
     633                return table_.max_size(allocator_);
     634            }
     635
     636            iterator begin() noexcept
     637            {
     638                return table_.begin();
     639            }
     640
     641            const_iterator begin() const noexcept
     642            {
     643                return table_.begin();
     644            }
     645
     646            iterator end() noexcept
     647            {
     648                return table_.end();
     649            }
     650
     651            const_iterator end() const noexcept
     652            {
     653                return table_.end();
     654            }
     655
     656            const_iterator cbegin() const noexcept
     657            {
     658                return table_.cbegin();
     659            }
     660
     661            const_iterator cend() const noexcept
     662            {
     663                return table_.cend();
     664            }
     665
     666            template<class... Args>
     667            pair<iterator, bool> emplace(Args&&... args)
     668            {
     669                return table_.emplace(forward<Args>(args)...);
     670            }
     671
     672            template<class... Args>
     673            iterator emplace_hint(const_iterator, Args&&... args)
     674            {
     675                return emplace(forward<Args>(args)...).first;
     676            }
     677
     678            pair<iterator, bool> insert(const value_type& val)
     679            {
     680                return table_.insert(val);
     681            }
     682
     683            pair<iterator, bool> insert(value_type&& val)
     684            {
     685                return table_.insert(forward<value_type>(val));
     686            }
     687
     688            iterator insert(const_iterator, const value_type& val)
     689            {
     690                return insert(val).first;
     691            }
     692
     693            iterator insert(const_iterator, value_type&& val)
     694            {
     695                return insert(forward<value_type>(val)).first;
     696            }
     697
     698            template<class InputIterator>
     699            void insert(InputIterator first, InputIterator last)
     700            {
     701                while (first != last)
     702                    insert(*first++);
     703            }
     704
     705            void insert(initializer_list<value_type> init)
     706            {
     707                insert(init.begin(), init.end());
     708            }
     709
     710            iterator erase(const_iterator position)
     711            {
     712                return table_.erase(position);
     713            }
     714
     715            size_type erase(const key_type& key)
     716            {
     717                return table_.erase(key);
     718            }
     719
     720            iterator erase(const_iterator first, const_iterator last)
     721            {
     722                while (first != last)
     723                    first = erase(first);
     724
     725                return iterator{
     726                    table_.table(), first.idx(),
     727                    table_.bucket_count(), table_.head(first.idx())
     728                };
     729            }
     730
     731            void clear() noexcept
     732            {
     733                table_.clear();
     734            }
     735
     736            void swap(unordered_multiset& other)
     737                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
     738                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
     739                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
     740            {
     741                table_.swap(other.table_);
     742                std::swap(allocator_, other.allocator_);
     743            }
     744
     745            hasher hash_function() const
     746            {
     747                return table_.hash_function();
     748            }
     749
     750            key_equal key_eq() const
     751            {
     752                return table_.key_eq();
     753            }
     754
     755            iterator find(const key_type& key)
     756            {
     757                return table_.find(key);
     758            }
     759
     760            const_iterator find(const key_type& key) const
     761            {
     762                return table_.find(key);
     763            }
     764
     765            size_type count(const key_type& key) const
     766            {
     767                return table_.count(key);
     768            }
     769
     770            pair<iterator, iterator> equal_range(const key_type& key)
     771            {
     772                return table_.equal_range(key);
     773            }
     774
     775            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
     776            {
     777                return table_.equal_range(key);
     778            }
     779
     780            size_type bucket_count() const noexcept
     781            {
     782                return table_.bucket_count();
     783            }
     784
     785            size_type max_bucket_count() const noexcept
     786            {
     787                return table_.max_bucket_count();
     788            }
     789
     790            size_type bucket_size(size_type idx) const
     791            {
     792                return table_.bucket_size(idx);
     793            }
     794
     795            size_type bucket(const key_type& key) const
     796            {
     797                return table_.bucket(key);
     798            }
     799
     800            local_iterator begin(size_type idx)
     801            {
     802                return table_.begin(idx);
     803            }
     804
     805            const_local_iterator begin(size_type idx) const
     806            {
     807                return table_.begin(idx);
     808            }
     809
     810            local_iterator end(size_type idx)
     811            {
     812                return table_.end(idx);
     813            }
     814
     815            const_local_iterator end(size_type idx) const
     816            {
     817                return table_.end(idx);
     818            }
     819
     820            const_local_iterator cbegin(size_type idx) const
     821            {
     822                return table_.cbegin(idx);
     823            }
     824
     825            const_local_iterator cend(size_type idx) const
     826            {
     827                return table_.cend(idx);
     828            }
     829
     830            float load_factor() const noexcept
     831            {
     832                return table_.load_factor();
     833            }
     834
     835            float max_load_factor() const noexcept
     836            {
     837                return table_.max_load_factor();
     838            }
     839
     840            void max_load_factor(float factor)
     841            {
     842                table_.max_load_factor(factor);
     843            }
     844
     845            void rehash(size_type bucket_count)
     846            {
     847                table_.rehash(bucket_count);
     848            }
     849
     850            void reserve(size_type count)
     851            {
     852                table_.reserve(count);
     853            }
     854
     855        private:
     856            using table_type = aux::hash_table<
     857                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
     858                hasher, key_equal, allocator_type, size_type,
     859                iterator, const_iterator, local_iterator, const_local_iterator,
     860                aux::hash_multi_policy
     861            >;
     862            using node_type = typename table_type::node_type;
     863
     864            table_type table_;
     865            allocator_type allocator_;
     866
     867            static constexpr size_type default_bucket_count_{16};
     868
     869            template<class K, class H, class P, class A>
     870            friend bool operator==(unordered_multiset<K, H, P, A>&,
     871                                   unordered_multiset<K, H, P, A>&);
     872    };
    468873
    469874    template<class Key, class Hash, class Pred, class Alloc>
Note: See TracChangeset for help on using the changeset viewer.