Skip to content

Commit 28b949b

Browse files
committed
Merge 2019-02 LWG Motion 18
P0920R2 Precalculated hash values in lookup Fixes #2709.
2 parents 927dc13 + de5f9bb commit 28b949b

File tree

2 files changed

+151
-5
lines changed

2 files changed

+151
-5
lines changed

source/containers.tex

Lines changed: 149 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,8 +2298,9 @@
22982298
\end{itemize}
22992299
where \tcode{r1} and \tcode{r2} are keys of elements in \tcode{a_tran},
23002300
\item \tcode{n} denotes a value of type \tcode{size_type},
2301-
\item \tcode{z} denotes a value of type \tcode{float}, and
2302-
\item \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}.
2301+
\item \tcode{z} denotes a value of type \tcode{float},
2302+
\item \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}, and
2303+
\item \tcode{hk} and \tcode{hke} denote values of type \tcode{size_t}.
23032304
\end{itemize}
23042305

23052306
% Local command to index names as members of all unordered containers.
@@ -2753,12 +2754,29 @@
27532754
& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}.
27542755
\\ \rowsep
27552756
%
2757+
\tcode{b.find(k, hk)}
2758+
& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{b}.
2759+
& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br
2760+
\returns An iterator pointing to an element with key equivalent to
2761+
\tcode{k}, or \tcode{b.end()} if no such element exists.
2762+
& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}.
2763+
\\ \rowsep
2764+
%
27562765
\tcode{a_tran.find(ke)}
27572766
& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{a_tran}.
27582767
& \returns An iterator pointing to an element with key equivalent to
27592768
\tcode{ke}, or \tcode{a_tran.end()} if no such element exists.
27602769
& Average case \bigoh{1},
2761-
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid wverfull
2770+
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
2771+
\\ \rowsep
2772+
%
2773+
\tcode{a_tran.find(ke, hke)}
2774+
& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{a_tran}.
2775+
& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br
2776+
\returns An iterator pointing to an element with key equivalent to
2777+
\tcode{ke}, or \tcode{a_tran.end()} if no such element exists.%
2778+
& Average case \bigoh{1},
2779+
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
27622780
\\ \rowsep
27632781
%
27642782
\indexunordmem{count}%
@@ -2768,6 +2786,13 @@
27682786
& Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}.
27692787
\\ \rowsep
27702788
%
2789+
\tcode{b.count(k, hk)}
2790+
& \tcode{size_type}
2791+
& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br
2792+
\returns The number of elements with key equivalent to \tcode{k}.%
2793+
& Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}.
2794+
\\ \rowsep
2795+
%
27712796
\tcode{a_tran.count(ke)}
27722797
& \tcode{size_type}
27732798
& \returns The number of elements with key equivalent to \tcode{ke}.%
@@ -2776,16 +2801,40 @@
27762801
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
27772802
\\ \rowsep
27782803
%
2804+
\tcode{a_tran.count(ke, hke)}
2805+
& \tcode{size_type}
2806+
& \expects \tcode{b.hash_function()(ke)} equals \tcode{hke}.\br
2807+
\returns The number of elements with key equivalent to \tcode{ke}.%
2808+
& Average case
2809+
\bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}, % avoid overfull
2810+
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
2811+
\\ \rowsep
2812+
%
27792813
\indexunordmem{contains}%
27802814
\tcode{b.contains(k)}
27812815
& \tcode{bool}
2782-
& Equivalent to \tcode{b.find(k) != b.end()}%
2816+
& \effects Equivalent to \tcode{b.find(k) != b.end()}%
2817+
& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}.
2818+
\\ \rowsep
2819+
%
2820+
\tcode{b.contains(k, hk)}
2821+
& \tcode{bool}
2822+
& \expects \tcode{b.hash_function()(ke)} equals \tcode{hke}.\br
2823+
\effects Equivalent to \tcode{b.find(k) != b.end()}%
27832824
& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}.
27842825
\\ \rowsep
27852826
%
27862827
\tcode{a_tran.contains(ke)}
27872828
& \tcode{bool}
2788-
& Equivalent to \tcode{a_tran.find(ke) != a_tran.end()}%
2829+
& \effects Equivalent to \tcode{a_tran.find(ke) != a_tran.end()}%
2830+
& Average case \bigoh{1},
2831+
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
2832+
\\ \rowsep
2833+
%
2834+
\tcode{a_tran.contains(ke, hke)}
2835+
& \tcode{bool}
2836+
& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br
2837+
\effects Equivalent to \tcode{a_tran.find(ke, hke) != a_tran.end()}%
27892838
& Average case \bigoh{1},
27902839
worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
27912840
\\ \rowsep
@@ -2801,6 +2850,17 @@
28012850
\bigoh{\tcode{b.size()}}.
28022851
\\ \rowsep
28032852
%
2853+
\tcode{b.equal_range(k, hk)}
2854+
& \tcode{pair<iterator, iterator>}; \br
2855+
\tcode{pair<const_iterator, const_iterator>} for const \tcode{b}.
2856+
& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br
2857+
\returns A range containing all elements with keys equivalent to
2858+
\tcode{k}. Returns \tcode{make_pair(b.end(), b.end())} if
2859+
no such elements exist.%
2860+
& Average case \bigoh{\tcode{b.count(k)}}. Worst case
2861+
\bigoh{\tcode{b.size()}}.
2862+
\\ \rowsep
2863+
%
28042864
\tcode{a_tran.equal_range(ke)}
28052865
& \tcode{pair<iterator, iterator>}; \br
28062866
\tcode{pair<const_iterator, const_iterator>} for const \tcode{a_tran}.
@@ -2811,6 +2871,18 @@
28112871
\bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}. % avoid overfull
28122872
Worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
28132873
\\ \rowsep
2874+
%
2875+
\tcode{a_tran.equal_range(ke, hke)}
2876+
& \tcode{pair<iterator, iterator>}; \br
2877+
\tcode{pair<const_iterator, const_iterator>} for const \tcode{a_tran}.
2878+
& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br
2879+
\returns A range containing all elements with keys equivalent to
2880+
\tcode{ke}. Returns \tcode{make_pair(a_tran.end(), a_tran.end())} if
2881+
no such elements exist.%
2882+
& Average case
2883+
\bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}. % avoid overfull
2884+
Worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull
2885+
\\ \rowsep
28142886
\indexunordmem{bucket_count}%
28152887
\tcode{b.bucket_count()}
28162888
& \tcode{size_type}
@@ -7964,22 +8036,40 @@
79648036
// map operations
79658037
iterator find(const key_type& k);
79668038
const_iterator find(const key_type& k) const;
8039+
iterator find(const key_type& k, size_t hash);
8040+
const_iterator find(const key_type& k, size_t hash) const;
79678041
template <class K>
79688042
iterator find(const K& k);
79698043
template <class K>
79708044
const_iterator find(const K& k) const;
8045+
template <class K>
8046+
iterator find(const K& k, size_t hash);
8047+
template <class K>
8048+
const_iterator find(const K& k, size_t hash) const;
79718049
size_type count(const key_type& k) const;
8050+
size_type count(const key_type& k, size_t hash) const;
79728051
template <class K>
79738052
size_type count(const K& k) const;
8053+
template <class K>
8054+
size_type count(const K& k, size_t hash) const;
79748055
bool contains(const key_type& k) const;
8056+
bool contains(const key_type& k, size_t hash) const;
79758057
template <class K>
79768058
bool contains(const K& k) const;
8059+
template <class K>
8060+
bool contains(const K& k, size_t hash) const;
79778061
pair<iterator, iterator> equal_range(const key_type& k);
79788062
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
8063+
pair<iterator, iterator> equal_range(const key_type& k, size_t hash);
8064+
pair<const_iterator, const_iterator> equal_range(const key_type& k, size_t hash) const;
79798065
template <class K>
79808066
pair<iterator, iterator> equal_range(const K& k);
79818067
template <class K>
79828068
pair<const_iterator, const_iterator> equal_range(const K& k) const;
8069+
template <class K>
8070+
pair<iterator, iterator> equal_range(const K& k, size_t hash);
8071+
template <class K>
8072+
pair<const_iterator, const_iterator> equal_range(const K& k, size_t hash) const;
79838073

79848074
// \ref{unord.map.elem}, element access
79858075
mapped_type& operator[](const key_type& k);
@@ -8534,22 +8624,40 @@
85348624
// map operations
85358625
iterator find(const key_type& k);
85368626
const_iterator find(const key_type& k) const;
8627+
iterator find(const key_type& k, size_t hash);
8628+
const_iterator find(const key_type& k, size_t hash) const;
85378629
template <class K>
85388630
iterator find(const K& k);
85398631
template <class K>
85408632
const_iterator find(const K& k) const;
8633+
template <class K>
8634+
iterator find(const K& k, size_t hash);
8635+
template <class K>
8636+
const_iterator find(const K& k, size_t hash) const;
85418637
size_type count(const key_type& k) const;
8638+
size_type count(const key_type& k, size_t hash) const;
85428639
template <class K>
85438640
size_type count(const K& k) const;
8641+
template <class K>
8642+
size_type count(const K& k, size_t hash) const;
85448643
bool contains(const key_type& k) const;
8644+
bool contains(const key_type& k, size_t hash) const;
85458645
template <class K>
85468646
bool contains(const K& k) const;
8647+
template <class K>
8648+
bool contains(const K& k, size_t hash) const;
85478649
pair<iterator, iterator> equal_range(const key_type& k);
85488650
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
8651+
pair<iterator, iterator> equal_range(const key_type& k, size_t hash);
8652+
pair<const_iterator, const_iterator> equal_range(const key_type& k, size_t hash) const;
85498653
template <class K>
85508654
pair<iterator, iterator> equal_range(const K& k);
85518655
template <class K>
85528656
pair<const_iterator, const_iterator> equal_range(const K& k) const;
8657+
template <class K>
8658+
pair<iterator, iterator> equal_range(const K& k, size_t hash);
8659+
template <class K>
8660+
pair<const_iterator, const_iterator> equal_range(const K& k, size_t hash) const;
85538661

85548662
// bucket interface
85558663
size_type bucket_count() const noexcept;
@@ -8896,22 +9004,40 @@
88969004
// set operations
88979005
iterator find(const key_type& k);
88989006
const_iterator find(const key_type& k) const;
9007+
iterator find(const key_type& k, size_t hash);
9008+
const_iterator find(const key_type& k, size_t hash) const;
88999009
template <class K>
89009010
iterator find(const K& k);
89019011
template <class K>
89029012
const_iterator find(const K& k) const;
9013+
template <class K>
9014+
iterator find(const K& k, size_t hash);
9015+
template <class K>
9016+
const_iterator find(const K& k, size_t hash) const;
89039017
size_type count(const key_type& k) const;
9018+
size_type count(const key_type& k, size_t hash) const;
89049019
template <class K>
89059020
size_type count(const K& k) const;
9021+
template <class K>
9022+
size_type count(const K& k, size_t hash) const;
89069023
bool contains(const key_type& k) const;
9024+
bool contains(const key_type& k, size_t hash) const;
89079025
template <class K>
89089026
bool contains(const K& k) const;
9027+
template <class K>
9028+
bool contains(const K& k, size_t hash) const;
89099029
pair<iterator, iterator> equal_range(const key_type& k);
89109030
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
9031+
pair<iterator, iterator> equal_range(const key_type& k, size_t hash);
9032+
pair<const_iterator, const_iterator> equal_range(const key_type& k, size_t hash) const;
89119033
template <class K>
89129034
pair<iterator, iterator> equal_range(const K& k);
89139035
template <class K>
89149036
pair<const_iterator, const_iterator> equal_range(const K& k) const;
9037+
template <class K>
9038+
pair<iterator, iterator> equal_range(const K& k, size_t hash);
9039+
template <class K>
9040+
pair<const_iterator, const_iterator> equal_range(const K& k, size_t hash) const;
89159041

89169042
// bucket interface
89179043
size_type bucket_count() const noexcept;
@@ -9220,22 +9346,40 @@
92209346
// set operations
92219347
iterator find(const key_type& k);
92229348
const_iterator find(const key_type& k) const;
9349+
iterator find(const key_type& k, size_t hash);
9350+
const_iterator find(const key_type& k, size_t hash) const;
92239351
template <class K>
92249352
iterator find(const K& k);
92259353
template <class K>
92269354
const_iterator find(const K& k) const;
9355+
template <class K>
9356+
iterator find(const K& k, size_t hash);
9357+
template <class K>
9358+
const_iterator find(const K& k, size_t hash) const;
92279359
size_type count(const key_type& k) const;
9360+
size_type count(const key_type& k, size_t hash) const;
92289361
template <class K>
92299362
size_type count(const K& k) const;
9363+
template <class K>
9364+
size_type count(const K& k, size_t hash) const;
92309365
bool contains(const key_type& k) const;
9366+
bool contains(const key_type& k, size_t hash) const;
92319367
template <class K>
92329368
bool contains(const K& k) const;
9369+
template <class K>
9370+
bool contains(const K& k, size_t hash) const;
92339371
pair<iterator, iterator> equal_range(const key_type& k);
92349372
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
9373+
pair<iterator, iterator> equal_range(const key_type& k, size_t hash);
9374+
pair<const_iterator, const_iterator> equal_range(const key_type& k, size_t hash) const;
92359375
template <class K>
92369376
pair<iterator, iterator> equal_range(const K& k);
92379377
template <class K>
92389378
pair<const_iterator, const_iterator> equal_range(const K& k) const;
9379+
template <class K>
9380+
pair<iterator, iterator> equal_range(const K& k, size_t hash);
9381+
template <class K>
9382+
pair<const_iterator, const_iterator> equal_range(const K& k, size_t hash) const;
92399383

92409384
// bucket interface
92419385
size_type bucket_count() const noexcept;

source/support.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@
598598
\tcode{<map>} \tcode{<set>} \\ \rowsep
599599
\defnlibxname{cpp_lib_generic_unordered_lookup} & \tcode{201811L} &
600600
\tcode{<unordered_map>} \tcode{<unordered_set>} \\ \rowsep
601+
\defnlibxname{cpp_lib_generic_unordered_hash_lookup} & \tcode{201902L} &
602+
\tcode{<unordered_map>} \tcode{<unordered_set>} \\ \rowsep
601603
\defnlibxname{cpp_lib_hardware_interference_size} & \tcode{201703L} &
602604
\tcode{<new>} \\ \rowsep
603605
\defnlibxname{cpp_lib_has_unique_object_representations} & \tcode{201606L} &

0 commit comments

Comments
 (0)