1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Chapter 22. Policy-Based Data Structures</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"/><meta name="keywords" content=" 	ISO C++ , 	policy , 	container , 	data , 	structure , 	associated , 	tree , 	trie , 	hash , 	metaprogramming "/><meta name="keywords" content=" ISO C++ , library "/><meta name="keywords" content=" ISO C++ , runtime , library "/><link rel="home" href="../index.html" title="The GNU C++ Library"/><link rel="up" href="extensions.html" title="Part III. Extensions"/><link rel="prev" href="bk01pt03ch21s02.html" title="Implementation"/><link rel="next" href="policy_data_structures_using.html" title="Using"/></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 22. Policy-Based Data Structures</th></tr><tr><td align="left"><a accesskey="p" href="bk01pt03ch21s02.html">Prev</a> </td><th width="60%" align="center">Part III.
6 </th><td align="right"> <a accesskey="n" href="policy_data_structures_using.html">Next</a></td></tr></table><hr/></div><div class="chapter" title="Chapter 22. Policy-Based Data Structures"><div class="titlepage"><div><div><h2 class="title"><a id="manual.ext.containers.pbds"/>Chapter 22. Policy-Based Data Structures</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl><dt><span class="section"><a href="policy_data_structures.html#pbds.intro">Intro</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.issues">Performance Issues</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.issues.associative">Associative</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.issues.priority_queue">Priority Que</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.motivation">Goals</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.motivation.associative">Associative</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures.html#motivation.associative.policy">Policy Choices</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#motivation.associative.underlying">Underlying Data Structures</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#motivation.associative.iterators">Iterators</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#motivation.associative.functions">Functional</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures.html#pbds.intro.motivation.priority_queue">Priority Queues</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures.html#motivation.priority_queue.policy">Policy Choices</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#motivation.priority_queue.underlying">Underlying Data Structures</a></span></dt><dt><span class="section"><a href="policy_data_structures.html#motivation.priority_queue.binary_heap">Binary Heaps</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="policy_data_structures_using.html">Using</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.organization">Organization</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.tutorial">Tutorial</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.tutorial.basic">Basic Use</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.tutorial.configuring">
7 Configuring via Template Parameters
8 </a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.tutorial.traits">
9 Querying Container Attributes
10 </a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.tutorial.point_range_iteration">
11 Point and Range Iteration
12 </a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples">Examples</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.basic">Intermediate Use</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.query">Querying with <code class="classname">container_traits</code> </a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.container">By Container Method</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.container.hash">Hash-Based</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.container.branch">Branch-Based</a></span></dt><dt><span class="section"><a href="policy_data_structures_using.html#pbds.using.examples.container.priority_queue">Priority Queues</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html">Design</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts">Concepts</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts.null_type">Null Policy Classes</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts.associative_semantics">Map and Set Semantics</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#concepts.associative_semantics.set_vs_map">
13 Distinguishing Between Maps and Sets
14 </a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#concepts.associative_semantics.multi">Alternatives to <code class="classname">std::multiset</code> and <code class="classname">std::multimap</code></a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts.iterator_semantics">Iterator Semantics</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#concepts.iterator_semantics.point_and_range">Point and Range Iterators</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#concepts.iterator_semantics.both">Distinguishing Point and Range Iterators</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts.invalidation">Invalidation Guarantees</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.concepts.genericity">Genericity</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#concepts.genericity.tag">Tag</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#concepts.genericity.traits">Traits</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container">By Container</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container.hash">hash</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#container.hash.interface">Interface</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#container.hash.details">Details</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container.tree">tree</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#container.tree.interface">Interface</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#container.tree.details">Details</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container.trie">Trie</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#container.trie.interface">Interface</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#container.trie.details">Details</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container.list">List</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#container.list.interface">Interface</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#container.list.details">Details</a></span></dt></dl></dd><dt><span class="section"><a href="policy_data_structures_design.html#pbds.design.container.priority_queue">Priority Queue</a></span></dt><dd><dl><dt><span class="section"><a href="policy_data_structures_design.html#container.priority_queue.interface">Interface</a></span></dt><dt><span class="section"><a href="policy_data_structures_design.html#container.priority_queue.details">Details</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="policy_based_data_structures_test.html">Testing</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#pbds.test.regression">Regression</a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#pbds.test.performance">Performance</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash">Hash-Based</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.text_find">
15 Text <code class="function">find</code>
16 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.int_find">
17 Integer <code class="function">find</code>
18 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.int_subscript_find">
19 Integer Subscript <code class="function">find</code>
20 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.int_subscript_insert">
21 Integer Subscript <code class="function">insert</code>
22 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.zlob_int_find">
23 Integer <code class="function">find</code> with Skewed-Distribution
24 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.hash.erase_mem">
26 </a></span></dt></dl></dd><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch">Branch-Based</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch.text_insert">
27 Text <code class="function">insert</code>
28 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch.text_find">
29 Text <code class="function">find</code>
30 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch.text_lor_find">
31 Text <code class="function">find</code> with Locality-of-Reference
32 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch.split_join">
33 <code class="function">split</code> and <code class="function">join</code>
34 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.branch.order_statistics">
36 </a></span></dt></dl></dd><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap">Multimap</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_find_small">
37 Text <code class="function">find</code> with Small Secondary-to-Primary Key Ratios
38 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_find_large">
39 Text <code class="function">find</code> with Large Secondary-to-Primary Key Ratios
40 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_insert_small">
41 Text <code class="function">insert</code> with Small
42 Secondary-to-Primary Key Ratios
43 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_insert_large">
44 Text <code class="function">insert</code> with Small
45 Secondary-to-Primary Key Ratios
46 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_insert_mem_small">
47 Text <code class="function">insert</code> with Small
48 Secondary-to-Primary Key Ratios Memory Use
49 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.multimap.text_insert_mem_large">
50 Text <code class="function">insert</code> with Small
51 Secondary-to-Primary Key Ratios Memory Use
52 </a></span></dt></dl></dd><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue">Priority Queue</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_push">
53 Text <code class="function">push</code>
54 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_push_pop">
55 Text <code class="function">push</code> and <code class="function">pop</code>
56 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.int_push">
57 Integer <code class="function">push</code>
58 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.int_push_pop">
59 Integer <code class="function">push</code>
60 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_pop">
61 Text <code class="function">pop</code> Memory Use
62 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_join">
63 Text <code class="function">join</code>
64 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_modify_up">
65 Text <code class="function">modify</code> Up
66 </a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#performance.priority_queue.text_modify_down">
67 Text <code class="function">modify</code> Down
68 </a></span></dt></dl></dd><dt><span class="section"><a href="policy_based_data_structures_test.html#pbds.test.performance.observations">Observations</a></span></dt><dd><dl><dt><span class="section"><a href="policy_based_data_structures_test.html#observations.associative">Associative</a></span></dt><dt><span class="section"><a href="policy_based_data_structures_test.html#observations.priority_queue">Priority_Queue</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="section"><a href="policy_data_structures_biblio.html">Acknowledgments</a></span></dt><dt><span class="bibliography"><a href="policy_data_structures.html#pbds.biblio">
70 </a></span></dt></dl></div><div class="section" title="Intro"><div class="titlepage"><div><div><h2 class="title"><a id="pbds.intro"/>Intro</h2></div></div></div><p>
71 This is a library of policy-based elementary data structures:
72 associative containers and priority queues. It is designed for
73 high-performance, flexibility, semantic safety, and conformance to
74 the corresponding containers in <code class="literal">std</code> and
75 <code class="literal">std::tr1</code> (except for some points where it differs
78 </p><div class="section" title="Performance Issues"><div class="titlepage"><div><div><h3 class="title"><a id="pbds.intro.issues"/>Performance Issues</h3></div></div></div><p>
80 An attempt is made to categorize the wide variety of possible
81 container designs in terms of performance-impacting factors. These
82 performance factors are translated into design policies and
83 incorporated into container design.
85 There is tension between unravelling factors into a coherent set of
86 policies. Every attempt is made to make a minimal set of
87 factors. However, in many cases multiple factors make for long
88 template names. Every attempt is made to alias and use typedefs in
89 the source files, but the generated names for external symbols can
90 be large for binary files or debuggers.
92 In many cases, the longer names allow capabilities and behaviours
93 controlled by macros to also be unamibiguously emitted as distinct
96 Specific issues found while unraveling performance factors in the
97 design of associative containers and priority queues follow.
98 </p><div class="section" title="Associative"><div class="titlepage"><div><div><h4 class="title"><a id="pbds.intro.issues.associative"/>Associative</h4></div></div></div><p>
99 Associative containers depend on their composite policies to a very
100 large extent. Implicitly hard-wiring policies can hamper their
101 performance and limit their functionality. An efficient hash-based
102 container, for example, requires policies for testing key
103 equivalence, hashing keys, translating hash values into positions
104 within the hash table, and determining when and how to resize the
105 table internally. A tree-based container can efficiently support
106 order statistics, i.e. the ability to query what is the order of
107 each key within the sequence of keys in the container, but only if
108 the container is supplied with a policy to internally update
109 meta-data. There are many other such examples.
111 Ideally, all associative containers would share the same
112 interface. Unfortunately, underlying data structures and mapping
113 semantics differentiate between different containers. For example,
114 suppose one writes a generic function manipulating an associative
116 </p><pre class="programlisting">
117 template<typename Cntnr>
119 some_op_sequence(Cntnr& r_cnt)
124 Given this, then what can one assume about the instantiating
125 container? The answer varies according to its underlying data
126 structure. If the underlying data structure of
127 <code class="literal">Cntnr</code> is based on a tree or trie, then the order
128 of elements is well defined; otherwise, it is not, in general. If
129 the underlying data structure of <code class="literal">Cntnr</code> is based
130 on a collision-chaining hash table, then modifying
131 r_<code class="literal">Cntnr</code> will not invalidate its iterators' order;
132 if the underlying data structure is a probing hash table, then this
133 is not the case. If the underlying data structure is based on a tree
134 or trie, then a reference to the container can efficiently be split;
135 otherwise, it cannot, in general. If the underlying data structure
136 is a red-black tree, then splitting a reference to the container is
137 exception-free; if it is an ordered-vector tree, exceptions can be
139 </p></div><div class="section" title="Priority Que"><div class="titlepage"><div><div><h4 class="title"><a id="pbds.intro.issues.priority_queue"/>Priority Que</h4></div></div></div><p>
140 Priority queues are useful when one needs to efficiently access a
141 minimum (or maximum) value as the set of values changes.
143 Most useful data structures for priority queues have a relatively
144 simple structure, as they are geared toward relatively simple
145 requirements. Unfortunately, these structures do not support access
146 to an arbitrary value, which turns out to be necessary in many
147 algorithms. Say, decreasing an arbitrary value in a graph
148 algorithm. Therefore, some extra mechanism is necessary and must be
149 invented for accessing arbitrary values. There are at least two
150 alternatives: embedding an associative container in a priority
151 queue, or allowing cross-referencing through iterators. The first
152 solution adds significant overhead; the second solution requires a
153 precise definition of iterator invalidation. Which is the next
156 Priority queues, like hash-based containers, store values in an
157 order that is meaningless and undefined externally. For example, a
158 <code class="code">push</code> operation can internally reorganize the
159 values. Because of this characteristic, describing a priority
160 queues' iterator is difficult: on one hand, the values to which
161 iterators point can remain valid, but on the other, the logical
162 order of iterators can change unpredictably.
164 Roughly speaking, any element that is both inserted to a priority
165 queue (e.g. through <code class="code">push</code>) and removed
166 from it (e.g., through <code class="code">pop</code>), incurs a
167 logarithmic overhead (in the amortized sense). Different underlying
168 data structures place the actual cost differently: some are
169 optimized for amortized complexity, whereas others guarantee that
170 specific operations only have a constant cost. One underlying data
171 structure might be chosen if modifying a value is frequent
172 (Dijkstra's shortest-path algorithm), whereas a different one might
173 be chosen otherwise. Unfortunately, an array-based binary heap - an
174 underlying data structure that optimizes (in the amortized sense)
175 <code class="code">push</code> and <code class="code">pop</code> operations, differs from the
176 others in terms of its invalidation guarantees. Other design
177 decisions also impact the cost and placement of the overhead, at the
178 expense of more difference in the the kinds of operations that the
179 underlying data structure can support. These differences pose a
180 challenge when creating a uniform interface for priority queues.
181 </p></div></div><div class="section" title="Goals"><div class="titlepage"><div><div><h3 class="title"><a id="pbds.intro.motivation"/>Goals</h3></div></div></div><p>
182 Many fine associative-container libraries were already written,
183 most notably, the C++ standard's associative containers. Why
184 then write another library? This section shows some possible
185 advantages of this library, when considering the challenges in
186 the introduction. Many of these points stem from the fact that
187 the ISO C++ process introduced associative-containers in a
188 two-step process (first standardizing tree-based containers,
189 only then adding hash-based containers, which are fundamentally
190 different), did not standardize priority queues as containers,
191 and (in our opinion) overloads the iterator concept.
192 </p><div class="section" title="Associative"><div class="titlepage"><div><div><h4 class="title"><a id="pbds.intro.motivation.associative"/>Associative</h4></div></div></div><p>
193 </p><div class="section" title="Policy Choices"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.associative.policy"/>Policy Choices</h5></div></div></div><p>
194 Associative containers require a relatively large number of
195 policies to function efficiently in various settings. In some
196 cases this is needed for making their common operations more
197 efficient, and in other cases this allows them to support a
198 larger set of operations
199 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
200 Hash-based containers, for example, support look-up and
201 insertion methods (<code class="function">find</code> and
202 <code class="function">insert</code>). In order to locate elements
203 quickly, they are supplied a hash functor, which instruct
204 how to transform a key object into some size type; a hash
205 functor might transform <code class="constant">"hello"</code>
206 into <code class="constant">1123002298</code>. A hash table, though,
207 requires transforming each key object into some size-type
208 type in some specific domain; a hash table with a 128-long
209 table might transform <code class="constant">"hello"</code> into
210 position <code class="constant">63</code>. The policy by which the
211 hash value is transformed into a position within the table
212 can dramatically affect performance. Hash-based containers
213 also do not resize naturally (as opposed to tree-based
214 containers, for example). The appropriate resize policy is
215 unfortunately intertwined with the policy that transforms
216 hash value into a position within the table.
217 </p></li><li class="listitem"><p>
218 Tree-based containers, for example, also support look-up and
219 insertion methods, and are primarily useful when maintaining
220 order between elements is important. In some cases, though,
221 one can utilize their balancing algorithms for completely
224 Figure A shows a tree whose each node contains two entries:
225 a floating-point key, and some size-type
226 <span class="emphasis"><em>metadata</em></span> (in bold beneath it) that is
227 the number of nodes in the sub-tree. (The root has key 0.99,
228 and has 5 nodes (including itself) in its sub-tree.) A
229 container based on this data structure can obviously answer
230 efficiently whether 0.3 is in the container object, but it
231 can also answer what is the order of 0.3 among all those in
232 the container object: see <a class="xref" href="policy_data_structures.html#biblio.clrs2001" title="Introduction to Algorithms, 2nd edition">[biblio.clrs2001]</a>.
235 As another example, Figure B shows a tree whose each node
236 contains two entries: a half-open geometric line interval,
237 and a number <span class="emphasis"><em>metadata</em></span> (in bold beneath
238 it) that is the largest endpoint of all intervals in its
239 sub-tree. (The root describes the interval <code class="constant">[20,
240 36)</code>, and the largest endpoint in its sub-tree is
241 99.) A container based on this data structure can obviously
242 answer efficiently whether <code class="constant">[3, 41)</code> is
243 in the container object, but it can also answer efficiently
244 whether the container object has intervals that intersect
245 <code class="constant">[3, 41)</code>. These types of queries are
246 very useful in geometric algorithms and lease-management
249 It is important to note, however, that as the trees are
250 modified, their internal structure changes. To maintain
251 these invariants, one must supply some policy that is aware
252 of these changes. Without this, it would be better to use a
253 linked list (in itself very efficient for these purposes).
254 </p></li></ol></div><div class="figure"><a id="id573272"/><p class="title"><strong>Figure 22.1. Node Invariants</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_node_invariants.png" style="text-align: middle" alt="Node Invariants"/></div></div></div><br class="figure-break"/></div><div class="section" title="Underlying Data Structures"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.associative.underlying"/>Underlying Data Structures</h5></div></div></div><p>
255 The standard C++ library contains associative containers based on
256 red-black trees and collision-chaining hash tables. These are
257 very useful, but they are not ideal for all types of
260 The figure below shows the different underlying data structures
261 currently supported in this library.
262 </p><div class="figure"><a id="id573328"/><p class="title"><strong>Figure 22.2. Underlying Associative Data Structures</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_different_underlying_dss_1.png" style="text-align: middle" alt="Underlying Associative Data Structures"/></div></div></div><br class="figure-break"/><p>
263 A shows a collision-chaining hash-table, B shows a probing
264 hash-table, C shows a red-black tree, D shows a splay tree, E shows
265 a tree based on an ordered vector(implicit in the order of the
266 elements), F shows a PATRICIA trie, and G shows a list-based
267 container with update policies.
269 Each of these data structures has some performance benefits, in
270 terms of speed, size or both. For now, note that vector-based trees
271 and probing hash tables manipulate memory more efficiently than
272 red-black trees and collision-chaining hash tables, and that
273 list-based associative containers are very useful for constructing
276 Now consider a function manipulating a generic associative
278 </p><pre class="programlisting">
279 template<class Cntnr>
281 some_op_sequence(Cntnr &r_cnt)
286 Ideally, the underlying data structure
287 of <code class="classname">Cntnr</code> would not affect what can be
288 done with <code class="varname">r_cnt</code>. Unfortunately, this is not
291 For example, if <code class="classname">Cntnr</code>
292 is <code class="classname">std::map</code>, then the function can
294 </p><pre class="programlisting">
295 std::for_each(r_cnt.find(foo), r_cnt.find(bar), foobar)
297 in order to apply <code class="classname">foobar</code> to all
298 elements between <code class="classname">foo</code> and
299 <code class="classname">bar</code>. If
300 <code class="classname">Cntnr</code> is a hash-based container,
301 then this call's results are undefined.
303 Also, if <code class="classname">Cntnr</code> is tree-based, the type
304 and object of the comparison functor can be
305 accessed. If <code class="classname">Cntnr</code> is hash based, these
306 queries are nonsensical.
308 There are various other differences based on the container's
309 underlying data structure. For one, they can be constructed by,
310 and queried for, different policies. Furthermore:
311 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
312 Containers based on C, D, E and F store elements in a
313 meaningful order; the others store elements in a meaningless
314 (and probably time-varying) order. By implication, only
315 containers based on C, D, E and F can
316 support <code class="function">erase</code> operations taking an
317 iterator and returning an iterator to the following element
318 without performance loss.
319 </p></li><li class="listitem"><p>
320 Containers based on C, D, E, and F can be split and joined
321 efficiently, while the others cannot. Containers based on C
322 and D, furthermore, can guarantee that this is exception-free;
323 containers based on E cannot guarantee this.
324 </p></li><li class="listitem"><p>
325 Containers based on all but E can guarantee that
326 erasing an element is exception free; containers based on E
327 cannot guarantee this. Containers based on all but B and E
328 can guarantee that modifying an object of their type does
329 not invalidate iterators or references to their elements,
330 while containers based on B and E cannot. Containers based
331 on C, D, and E can furthermore make a stronger guarantee,
332 namely that modifying an object of their type does not
333 affect the order of iterators.
334 </p></li></ol></div><p>
335 A unified tag and traits system (as used for the C++ standard
336 library iterators, for example) can ease generic manipulation of
337 associative containers based on different underlying data
339 </p></div><div class="section" title="Iterators"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.associative.iterators"/>Iterators</h5></div></div></div><p>
340 Iterators are centric to the design of the standard library
341 containers, because of the container/algorithm/iterator
342 decomposition that allows an algorithm to operate on a range
343 through iterators of some sequence. Iterators, then, are useful
344 because they allow going over a
345 specific <span class="emphasis"><em>sequence</em></span>. The standard library
346 also uses iterators for accessing a
347 specific <span class="emphasis"><em>element</em></span>: when an associative
348 container returns one through <code class="function">find</code>. The
349 standard library consistently uses the same types of iterators
350 for both purposes: going over a range, and accessing a specific
351 found element. Before the introduction of hash-based containers
352 to the standard library, this made sense (with the exception of
353 priority queues, which are discussed later).
355 Using the standard associative containers together with
356 non-order-preserving associative containers (and also because of
357 priority-queues container), there is a possible need for
358 different types of iterators for self-organizing containers:
359 the iterator concept seems overloaded to mean two different
360 things (in some cases). <em><span class="remark"> XXX
361 "ds_gen.html#find_range">Design::Associative
362 Containers::Data-Structure Genericity::Point-Type and Range-Type
364 </p><div class="section" title="Using Point Iterators for Range Operations"><div class="titlepage"><div><div><h6 class="title"><a id="associative.iterators.using"/>Using Point Iterators for Range Operations</h6></div></div></div><p>
365 Suppose <code class="classname">cntnr</code> is some associative
366 container, and say <code class="varname">c</code> is an object of
367 type <code class="classname">cntnr</code>. Then what will be the outcome
369 </p><pre class="programlisting">
370 std::for_each(c.find(1), c.find(5), foo);
372 If <code class="classname">cntnr</code> is a tree-based container
373 object, then an in-order walk will
374 apply <code class="classname">foo</code> to the relevant elements,
375 as in the graphic below, label A. If <code class="varname">c</code> is
376 a hash-based container, then the order of elements between any
377 two elements is undefined (and probably time-varying); there is
378 no guarantee that the elements traversed will coincide with the
379 <span class="emphasis"><em>logical</em></span> elements between 1 and 5, as in
381 </p><div class="figure"><a id="id573591"/><p class="title"><strong>Figure 22.3. Range Iteration in Different Data Structures</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_point_iterators_range_ops_1.png" style="text-align: middle" alt="Node Invariants"/></div></div></div><br class="figure-break"/><p>
382 In our opinion, this problem is not caused just because
383 red-black trees are order preserving while
384 collision-chaining hash tables are (generally) not - it
385 is more fundamental. Most of the standard's containers
386 order sequences in a well-defined manner that is
387 determined by their <span class="emphasis"><em>interface</em></span>:
388 calling <code class="function">insert</code> on a tree-based
389 container modifies its sequence in a predictable way, as
390 does calling <code class="function">push_back</code> on a list or
391 a vector. Conversely, collision-chaining hash tables,
392 probing hash tables, priority queues, and list-based
393 containers (which are very useful for "multimaps") are
394 self-organizing data structures; the effect of each
395 operation modifies their sequences in a manner that is
396 (practically) determined by their
397 <span class="emphasis"><em>implementation</em></span>.
399 Consequently, applying an algorithm to a sequence obtained from most
400 containers may or may not make sense, but applying it to a
401 sub-sequence of a self-organizing container does not.
402 </p></div><div class="section" title="Cost to Point Iterators to Enable Range Operations"><div class="titlepage"><div><div><h6 class="title"><a id="associative.iterators.cost"/>Cost to Point Iterators to Enable Range Operations</h6></div></div></div><p>
403 Suppose <code class="varname">c</code> is some collision-chaining
404 hash-based container object, and one calls
405 </p><pre class="programlisting">c.find(3)</pre><p>
406 Then what composes the returned iterator?
408 In the graphic below, label A shows the simplest (and
409 most efficient) implementation of a collision-chaining
410 hash table. The little box marked
411 <code class="classname">point_iterator</code> shows an object
412 that contains a pointer to the element's node. Note that
413 this "iterator" has no way to move to the next element (
415 <code class="function">operator++</code>). Conversely, the little
416 box marked <code class="classname">iterator</code> stores both a
417 pointer to the element, as well as some other
418 information (the bucket number of the element). the
419 second iterator, then, is "heavier" than the first one-
420 it requires more time and space. If we were to use a
421 different container to cross-reference into this
422 hash-table using these iterators - it would take much
423 more space. As noted above, nothing much can be done by
424 incrementing these iterators, so why is this extra
427 Alternatively, one might create a collision-chaining hash-table
428 where the lists might be linked, forming a monolithic total-element
429 list, as in the graphic below, label B. Here the iterators are as
430 light as can be, but the hash-table's operations are more
432 </p><div class="figure"><a id="id573715"/><p class="title"><strong>Figure 22.4. Point Iteration in Hash Data Structures</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_point_iterators_range_ops_2.png" style="text-align: middle" alt="Point Iteration in Hash Data Structures"/></div></div></div><br class="figure-break"/><p>
433 It should be noted that containers based on collision-chaining
434 hash-tables are not the only ones with this type of behavior;
435 many other self-organizing data structures display it as well.
436 </p></div><div class="section" title="Invalidation Guarantees"><div class="titlepage"><div><div><h6 class="title"><a id="associative.iterators.invalidation"/>Invalidation Guarantees</h6></div></div></div><p>Consider the following snippet:</p><pre class="programlisting">
440 Following the call to <code class="classname">erase</code>, what is the
441 validity of <code class="classname">it</code>: can it be de-referenced?
442 can it be incremented?
444 The answer depends on the underlying data structure of the
445 container. The graphic below shows three cases: A1 and A2 show
446 a red-black tree; B1 and B2 show a probing hash-table; C1 and C2
447 show a collision-chaining hash table.
448 </p><div class="figure"><a id="id573793"/><p class="title"><strong>Figure 22.5. Effect of erase in different underlying data structures</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_invalidation_guarantee_erase.png" style="text-align: middle" alt="Effect of erase in different underlying data structures"/></div></div></div><br class="figure-break"/><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
449 Erasing 5 from A1 yields A2. Clearly, an iterator to 3 can
450 be de-referenced and incremented. The sequence of iterators
451 changed, but in a way that is well-defined by the interface.
452 </p></li><li class="listitem"><p>
453 Erasing 5 from B1 yields B2. Clearly, an iterator to 3 is
454 not valid at all - it cannot be de-referenced or
455 incremented; the order of iterators changed in a way that is
456 (practically) determined by the implementation and not by
458 </p></li><li class="listitem"><p>
459 Erasing 5 from C1 yields C2. Here the situation is more
460 complicated. On the one hand, there is no problem in
461 de-referencing <code class="classname">it</code>. On the other hand,
462 the order of iterators changed in a way that is
463 (practically) determined by the implementation and not by
465 </p></li></ol></div><p>
466 So in the standard library containers, it is not always possible
467 to express whether <code class="varname">it</code> is valid or not. This
468 is true also for <code class="function">insert</code>. Again, the
469 iterator concept seems overloaded.
470 </p></div></div><div class="section" title="Functional"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.associative.functions"/>Functional</h5></div></div></div><p>
472 The design of the functional overlay to the underlying data
473 structures differs slightly from some of the conventions used in
474 the C++ standard. A strict public interface of methods that
475 comprise only operations which depend on the class's internal
476 structure; other operations are best designed as external
477 functions. (See <a class="xref" href="policy_data_structures.html#biblio.meyers02both" title="Class Template, Member Template - or Both?">[biblio.meyers02both]</a>).With this
478 rubric, the standard associative containers lack some useful
479 methods, and provide other methods which would be better
481 </p><div class="section" title="erase"><div class="titlepage"><div><div><h6 class="title"><a id="motivation.associative.functions.erase"/><code class="function">erase</code></h6></div></div></div><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
482 Order-preserving standard associative containers provide the
484 </p><pre class="programlisting">
488 which takes an iterator, erases the corresponding
489 element, and returns an iterator to the following
490 element. Also standardd hash-based associative
491 containers provide this method. This seemingly
492 increasesgenericity between associative containers,
493 since it is possible to use
494 </p><pre class="programlisting">
495 typename C::iterator it = c.begin();
496 typename C::iterator e_it = c.end();
499 it = pred(*it)? c.erase(it) : ++it;
501 in order to erase from a container object <code class="varname">
502 c</code> all element which match a
503 predicate <code class="classname">pred</code>. However, in a
504 different sense this actually decreases genericity: an
505 integral implication of this method is that tree-based
506 associative containers' memory use is linear in the total
507 number of elements they store, while hash-based
508 containers' memory use is unbounded in the total number of
509 elements they store. Assume a hash-based container is
510 allowed to decrease its size when an element is
511 erased. Then the elements might be rehashed, which means
512 that there is no "next" element - it is simply
513 undefined. Consequently, it is possible to infer from the
514 fact that the standard library's hash-based containers
515 provide this method that they cannot downsize when
516 elements are erased. As a consequence, different code is
517 needed to manipulate different containers, assuming that
518 memory should be conserved. Therefor, this library's
519 non-order preserving associative containers omit this
521 </p></li><li class="listitem"><p>
522 All associative containers include a conditional-erase method
523 </p><pre class="programlisting">
530 which erases all elements matching a predicate. This is probably the
531 only way to ensure linear-time multiple-item erase which can
532 actually downsize a container.
533 </p></li><li class="listitem"><p>
534 The standard associative containers provide methods for
535 multiple-item erase of the form
536 </p><pre class="programlisting">
540 erasing a range of elements given by a pair of
541 iterators. For tree-based or trie-based containers, this can
542 implemented more efficiently as a (small) sequence of split
543 and join operations. For other, unordered, containers, this
544 method isn't much better than an external loop. Moreover,
545 if <code class="varname">c</code> is a hash-based container,
547 </p><pre class="programlisting">
548 c.erase(c.find(2), c.find(5))
550 is almost certain to do something
551 different than erasing all elements whose keys are between 2
552 and 5, and is likely to produce other undefined behavior.
553 </p></li></ol></div></div><div class="section" title="split and join"><div class="titlepage"><div><div><h6 class="title"><a id="motivation.associative.functions.split"/>
554 <code class="function">split</code> and <code class="function">join</code>
555 </h6></div></div></div><p>
556 It is well-known that tree-based and trie-based container
557 objects can be efficiently split or joined (See
558 <a class="xref" href="policy_data_structures.html#biblio.clrs2001" title="Introduction to Algorithms, 2nd edition">[biblio.clrs2001]</a>). Externally splitting or
559 joining trees is super-linear, and, furthermore, can throw
560 exceptions. Split and join methods, consequently, seem good
561 choices for tree-based container methods, especially, since as
562 noted just before, they are efficient replacements for erasing
564 </p></div><div class="section" title="insert"><div class="titlepage"><div><div><h6 class="title"><a id="motivation.associative.functions.insert"/>
565 <code class="function">insert</code>
566 </h6></div></div></div><p>
567 The standard associative containers provide methods of the form
568 </p><pre class="programlisting">
569 template<class It>
573 for inserting a range of elements given by a pair of
574 iterators. At best, this can be implemented as an external loop,
575 or, even more efficiently, as a join operation (for the case of
576 tree-based or trie-based containers). Moreover, these methods seem
577 similar to constructors taking a range given by a pair of
578 iterators; the constructors, however, are transactional, whereas
579 the insert methods are not; this is possibly confusing.
580 </p></div><div class="section" title="operator== and operator<="><div class="titlepage"><div><div><h6 class="title"><a id="motivation.associative.functions.compare"/>
581 <code class="function">operator==</code> and <code class="function">operator<=</code>
582 </h6></div></div></div><p>
583 Associative containers are parametrized by policies allowing to
584 test key equivalence: a hash-based container can do this through
585 its equivalence functor, and a tree-based container can do this
586 through its comparison functor. In addition, some standard
587 associative containers have global function operators, like
588 <code class="function">operator==</code> and <code class="function">operator<=</code>,
589 that allow comparing entire associative containers.
591 In our opinion, these functions are better left out. To begin
592 with, they do not significantly improve over an external
593 loop. More importantly, however, they are possibly misleading -
594 <code class="function">operator==</code>, for example, usually checks for
595 equivalence, or interchangeability, but the associative
596 container cannot check for values' equivalence, only keys'
597 equivalence; also, are two containers considered equivalent if
598 they store the same values in different order? this is an
600 </p></div></div></div><div class="section" title="Priority Queues"><div class="titlepage"><div><div><h4 class="title"><a id="pbds.intro.motivation.priority_queue"/>Priority Queues</h4></div></div></div><div class="section" title="Policy Choices"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.priority_queue.policy"/>Policy Choices</h5></div></div></div><p>
601 Priority queues are containers that allow efficiently inserting
602 values and accessing the maximal value (in the sense of the
603 container's comparison functor). Their interface
604 supports <code class="function">push</code>
605 and <code class="function">pop</code>. The standard
606 container <code class="classname">std::priorityqueue</code> indeed support
607 these methods, but little else. For algorithmic and
608 software-engineering purposes, other methods are needed:
609 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
610 Many graph algorithms (see
611 <a class="xref" href="policy_data_structures.html#biblio.clrs2001" title="Introduction to Algorithms, 2nd edition">[biblio.clrs2001]</a>) require increasing a
612 value in a priority queue (again, in the sense of the
613 container's comparison functor), or joining two
614 priority-queue objects.
615 </p></li><li class="listitem"><p>The return type of <code class="classname">priority_queue</code>'s
616 <code class="function">push</code> method is a point-type iterator, which can
617 be used for modifying or erasing arbitrary values. For
618 example:</p><pre class="programlisting">
619 priority_queue<int> p;
620 priority_queue<int>::point_iterator it = p.push(3);
622 </pre><p>These types of cross-referencing operations are necessary
623 for making priority queues useful for different applications,
624 especially graph applications.</p></li><li class="listitem"><p>
625 It is sometimes necessary to erase an arbitrary value in a
626 priority queue. For example, consider
627 the <code class="function">select</code> function for monitoring
629 </p><pre class="programlisting">
631 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
632 struct timeval *timeout);
634 then, as the select documentation states:
636 <span class="quote">“<span class="quote">
637 The nfds argument specifies the range of file
638 descriptors to be tested. The select() function tests file
639 descriptors in the range of 0 to nfds-1.</span>”</span>
641 It stands to reason, therefore, that we might wish to
642 maintain a minimal value for <code class="varname">nfds</code>, and
643 priority queues immediately come to mind. Note, though, that
644 when a socket is closed, the minimal file description might
645 change; in the absence of an efficient means to erase an
646 arbitrary value from a priority queue, we might as well
647 avoid its use altogether.
649 The standard containers typically support iterators. It is
651 for <code class="classname">std::priority_queue</code> to omit them
652 (See <a class="xref" href="policy_data_structures.html#biblio.meyers01stl" title="Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library">[biblio.meyers01stl]</a>). One might
653 ask why do priority queues need to support iterators, since
654 they are self-organizing containers with a different purpose
655 than abstracting sequences. There are several reasons:
656 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
657 Iterators (even in self-organizing containers) are
658 useful for many purposes: cross-referencing
659 containers, serialization, and debugging code that uses
661 </p></li><li class="listitem"><p>
662 The standard library's hash-based containers support
663 iterators, even though they too are self-organizing
664 containers with a different purpose than abstracting
666 </p></li><li class="listitem"><p>
667 In standard-library-like containers, it is natural to specify the
668 interface of operations for modifying a value or erasing
669 a value (discussed previously) in terms of a iterators.
670 It should be noted that the standard
671 containers also use iterators for accessing and
672 manipulating a specific value. In hash-based
673 containers, one checks the existence of a key by
674 comparing the iterator returned by <code class="function">find</code> to the
675 iterator returned by <code class="function">end</code>, and not by comparing a
676 pointer returned by <code class="function">find</code> to <span class="type">NULL</span>.
677 </p></li></ol></div></li></ol></div></div><div class="section" title="Underlying Data Structures"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.priority_queue.underlying"/>Underlying Data Structures</h5></div></div></div><p>
678 There are three main implementations of priority queues: the
679 first employs a binary heap, typically one which uses a
680 sequence; the second uses a tree (or forest of trees), which is
681 typically less structured than an associative container's tree;
682 the third simply uses an associative container. These are
683 shown in the figure below with labels A1 and A2, B, and C.
684 </p><div class="figure"><a id="id574356"/><p class="title"><strong>Figure 22.6. Underlying Priority Queue Data Structures</strong></p><div class="figure-contents"><div class="mediaobject" style="text-align: center"><img src="../images/pbds_different_underlying_dss_2.png" style="text-align: middle" alt="Underlying Priority Queue Data Structures"/></div></div></div><br class="figure-break"/><p>
685 No single implementation can completely replace any of the
686 others. Some have better <code class="function">push</code>
687 and <code class="function">pop</code> amortized performance, some have
688 better bounded (worst case) response time than others, some
689 optimize a single method at the expense of others, etc. In
690 general the "best" implementation is dictated by the specific
693 As with associative containers, the more implementations
694 co-exist, the more necessary a traits mechanism is for handling
695 generic containers safely and efficiently. This is especially
696 important for priority queues, since the invalidation guarantees
697 of one of the most useful data structures - binary heaps - is
698 markedly different than those of most of the others.
699 </p></div><div class="section" title="Binary Heaps"><div class="titlepage"><div><div><h5 class="title"><a id="motivation.priority_queue.binary_heap"/>Binary Heaps</h5></div></div></div><p>
700 Binary heaps are one of the most useful underlying
701 data structures for priority queues. They are very efficient in
702 terms of memory (since they don't require per-value structure
703 metadata), and have the best amortized <code class="function">push</code> and
704 <code class="function">pop</code> performance for primitive types like
705 <span class="type">int</span>.
707 The standard library's <code class="classname">priority_queue</code>
708 implements this data structure as an adapter over a sequence,
710 <code class="classname">std::vector</code>
711 or <code class="classname">std::deque</code>, which correspond to labels
712 A1 and A2 respectively in the graphic above.
714 This is indeed an elegant example of the adapter concept and
715 the algorithm/container/iterator decomposition. (See <a class="xref" href="policy_data_structures.html#biblio.nelson96stlpq" title="Priority Queues and the STL">[biblio.nelson96stlpq]</a>). There are
716 several reasons why a binary-heap priority queue
717 may be better implemented as a container instead of a
719 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
720 <code class="classname">std::priority_queue</code> cannot erase values
721 from its adapted sequence (irrespective of the sequence
722 type). This means that the memory use of
723 an <code class="classname">std::priority_queue</code> object is always
724 proportional to the maximal number of values it ever contained,
725 and not to the number of values that it currently
726 contains. (See <code class="filename">performance/priority_queue_text_pop_mem_usage.cc</code>.)
727 This implementation of binary heaps acts very differently than
728 other underlying data structures (See also pairing heaps).
729 </p></li><li class="listitem"><p>
730 Some combinations of adapted sequences and value types
731 are very inefficient or just don't make sense. If one uses
732 <code class="classname">std::priority_queue<std::vector<std::string>
733 > ></code>, for example, then not only will each
734 operation perform a logarithmic number of
735 <code class="classname">std::string</code> assignments, but, furthermore, any
736 operation (including <code class="function">pop</code>) can render the container
737 useless due to exceptions. Conversely, if one uses
738 <code class="classname">std::priority_queue<std::deque<int> >
739 ></code>, then each operation uses incurs a logarithmic
740 number of indirect accesses (through pointers) unnecessarily.
741 It might be better to let the container make a conservative
742 deduction whether to use the structure in the graphic above, labels A1 or A2.
743 </p></li><li class="listitem"><p>
744 There does not seem to be a systematic way to determine
745 what exactly can be done with the priority queue.
746 </p><div class="orderedlist"><ol class="orderedlist"><li class="listitem"><p>
747 If <code class="classname">p</code> is a priority queue adapting an
748 <code class="classname">std::vector</code>, then it is possible to iterate over
749 all values by using <code class="function">&p.top()</code> and
750 <code class="function">&p.top() + p.size()</code>, but this will not work
751 if <code class="varname">p</code> is adapting an <code class="classname">std::deque</code>; in any
752 case, one cannot use <code class="classname">p.begin()</code> and
753 <code class="classname">p.end()</code>. If a different sequence is adapted, it
754 is even more difficult to determine what can be
756 </p></li><li class="listitem"><p>
757 If <code class="varname">p</code> is a priority queue adapting an
758 <code class="classname">std::deque</code>, then the reference return by
759 </p><pre class="programlisting">
762 will remain valid until it is popped,
763 but if <code class="varname">p</code> adapts an <code class="classname">std::vector</code>, the
764 next <code class="function">push</code> will invalidate it. If a different
765 sequence is adapted, it is even more difficult to
766 determine what can be done.
767 </p></li></ol></div></li><li class="listitem"><p>
768 Sequence-based binary heaps can still implement
769 linear-time <code class="function">erase</code> and <code class="function">modify</code> operations.
770 This means that if one needs to erase a small
771 (say logarithmic) number of values, then one might still
772 choose this underlying data structure. Using
773 <code class="classname">std::priority_queue</code>, however, this will generally
774 change the order of growth of the entire sequence of
776 </p></li></ol></div></div></div></div></div><div class="bibliography" title="Bibliography"><div class="titlepage"><div><div><h2 class="title"><a id="pbds.biblio"/>
778 </h2></div></div></div><div class="biblioentry" title="STL Exception Handling Contract"><a id="biblio.abrahams97exception"/><p>[biblio.abrahams97exception] <span class="title"><em>
779 <a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1075.pdf">
780 STL Exception Handling Contract
782 </em>. </span><span class="date">1997. </span><span class="author"><span class="firstname">
784 </span> <span class="surname">
786 </span>. </span><span class="publisher"><span class="publishername">
788 . </span></span></p></div><div class="biblioentry" title="Modern C++ Design: Generic Programming and Design Patterns Applied"><a id="biblio.alexandrescu01modern"/><p>[biblio.alexandrescu01modern] <span class="title"><em>
789 Modern C++ Design: Generic Programming and Design Patterns Applied
790 </em>. </span><span class="date">
792 . </span><span class="author"><span class="firstname">
794 </span> <span class="surname">
796 </span>. </span><span class="publisher"><span class="publishername">
797 Addison-Wesley Publishing Company
798 . </span></span></p></div><div class="biblioentry" title="MTF, Bit, and COMB: A Guide to Deterministic and Randomized Algorithms for the List Update Problem"><a id="biblio.andrew04mtf"/><p>[biblio.andrew04mtf] <span class="title"><em>
799 MTF, Bit, and COMB: A Guide to Deterministic and Randomized
800 Algorithms for the List Update Problem
801 </em>. </span><span class="authorgroup"><span class="firstname">
803 </span> <span class="surname">
805 </span> and <span class="firstname">
807 </span> <span class="surname">
809 </span>. </span></p></div><div class="biblioentry" title="Why You Shouldn't Use set - and What You Should Use Instead"><a id="biblio.austern00noset"/><p>[biblio.austern00noset] <span class="title"><em>
810 Why You Shouldn't Use set - and What You Should Use Instead
811 </em>. </span><span class="date">
813 . </span><span class="author"><span class="firstname">
815 </span> <span class="surname">
817 </span>. </span><span class="publisher"><span class="publishername">
819 . </span></span></p></div><div class="biblioentry" title="A Proposal to Add Hashtables to the Standard Library"><a id="biblio.austern01htprop"/><p>[biblio.austern01htprop] <span class="title"><em>
820 <a class="link" href="http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2001/n1326.html">
821 A Proposal to Add Hashtables to the Standard Library
823 </em>. </span><span class="date">
825 . </span><span class="author"><span class="firstname">
827 </span> <span class="surname">
829 </span>. </span><span class="publisher"><span class="publishername">
831 . </span></span></p></div><div class="biblioentry" title="Segmented iterators and hierarchical algorithms"><a id="biblio.austern98segmentedit"/><p>[biblio.austern98segmentedit] <span class="title"><em>
832 Segmented iterators and hierarchical algorithms
833 </em>. </span><span class="date">
835 . </span><span class="author"><span class="firstname">
837 </span> <span class="surname">
839 </span>. </span><span class="publisher"><span class="publishername">
841 . </span></span></p></div><div class="biblioentry" title="Boost Timer Library"><a id="biblio.dawestimer"/><p>[biblio.dawestimer] <span class="title"><em>
842 <a class="link" href="www.boost.org/doc/libs/release/libs/timer/">
845 </em>. </span><span class="author"><span class="firstname">
847 </span> <span class="surname">
849 </span>. </span><span class="publisher"><span class="publishername">
851 . </span></span></p></div><div class="biblioentry" title="Boost Pool Library"><a id="biblio.clearypool"/><p>[biblio.clearypool] <span class="title"><em>
852 <a class="link" href="www.boost.org/doc/libs/release/libs/pool/">
855 </em>. </span><span class="author"><span class="firstname">
857 </span> <span class="surname">
859 </span>. </span><span class="publisher"><span class="publishername">
861 . </span></span></p></div><div class="biblioentry" title="Boost Type Traits Library"><a id="biblio.maddocktraits"/><p>[biblio.maddocktraits] <span class="title"><em>
862 <a class="link" href="www.boost.org/doc/libs/release/libs/type_traits/">
863 Boost Type Traits Library
865 </em>. </span><span class="authorgroup"><span class="firstname">
867 </span> <span class="surname">
869 </span> and <span class="firstname">
871 </span> <span class="surname">
873 </span>. </span><span class="publisher"><span class="publishername">
875 . </span></span></p></div><div class="biblioentry" title="Worst-case efficient priority queues"><a id="biblio.brodal96priority"/><p>[biblio.brodal96priority] <span class="title"><em>
876 <a class="link" href="http://portal.acm.org/citation.cfm?id=313883">
877 Worst-case efficient priority queues
879 </em>. </span><span class="author"><span class="firstname">
881 </span> <span class="surname">
883 </span>. </span></p></div><div class="biblioentry" title="Efficient C++ Programming Techniques"><a id="biblio.bulkamayheweff"/><p>[biblio.bulkamayheweff] <span class="title"><em>
884 Efficient C++ Programming Techniques
885 </em>. </span><span class="date">
887 . </span><span class="authorgroup"><span class="firstname">
889 </span> <span class="surname">
891 </span> and <span class="firstname">
893 </span> <span class="surname">
895 </span>. </span><span class="publisher"><span class="publishername">
896 Addison-Wesley Publishing Company
897 . </span></span></p></div><div class="biblioentry" title="Introduction to Algorithms, 2nd edition"><a id="biblio.clrs2001"/><p>[biblio.clrs2001] <span class="title"><em>
898 Introduction to Algorithms, 2nd edition
899 </em>. </span><span class="date">
901 . </span><span class="authorgroup"><span class="firstname">
903 </span> <span class="surname">
905 </span>, <span class="firstname">
907 </span> <span class="surname">
909 </span>, <span class="firstname">
911 </span> <span class="surname">
913 </span>, and <span class="firstname">
915 </span> <span class="surname">
917 </span>. </span><span class="publisher"><span class="publishername">
919 . </span></span></p></div><div class="biblioentry" title="Balls and bins: A study in negative dependence"><a id="biblio.dubhashi98neg"/><p>[biblio.dubhashi98neg] <span class="title"><em>
920 Balls and bins: A study in negative dependence
921 </em>. </span><span class="date">
923 . </span><span class="authorgroup"><span class="firstname">
925 </span> <span class="surname">
927 </span> and <span class="firstname">
929 </span> <span class="surname">
931 </span>. </span><span class="publisher"><span class="publishername">
932 Random Structures and Algorithms 13
933 . </span></span></p></div><div class="biblioentry" title="Extendible hashing - a fast access method for dynamic files"><a id="biblio.fagin79extendible"/><p>[biblio.fagin79extendible] <span class="title"><em>
934 Extendible hashing - a fast access method for dynamic files
935 </em>. </span><span class="date">
937 . </span><span class="authorgroup"><span class="firstname">
939 </span> <span class="surname">
941 </span>, <span class="firstname">
943 </span> <span class="surname">
945 </span>, <span class="firstname">
947 </span> <span class="surname">
949 </span>, and <span class="firstname">
951 </span> <span class="surname">
953 </span>. </span><span class="publisher"><span class="publishername">
954 ACM Trans. Database Syst. 4
955 . </span></span></p></div><div class="biblioentry" title="Ptset: Sets of integers implemented as Patricia trees"><a id="biblio.filliatre2000ptset"/><p>[biblio.filliatre2000ptset] <span class="title"><em>
956 <a class="link" href="http://cristal.inria.fr/~frisch/icfp06_contest/advtr/applyOmatic/ptset.ml">
957 Ptset: Sets of integers implemented as Patricia trees
959 </em>. </span><span class="date">
961 . </span><span class="author"><span class="firstname">
963 </span> <span class="surname">
965 </span>. </span></p></div><div class="biblioentry" title="The pairing heap: a new form of self-adjusting heap"><a id="biblio.fredman86pairing"/><p>[biblio.fredman86pairing] <span class="title"><em>
966 <a class="link" href="http://www.cs.cmu.edu/~sleator/papers/pairing-heaps.pdf">
967 The pairing heap: a new form of self-adjusting heap
969 </em>. </span><span class="date">
971 . </span><span class="authorgroup"><span class="firstname">
973 </span> <span class="surname">
975 </span>, <span class="firstname">
977 </span> <span class="surname">
979 </span>, <span class="firstname">
981 </span> <span class="surname">
983 </span>, and <span class="firstname">
985 </span> <span class="surname">
987 </span>. </span></p></div><div class="biblioentry" title="Design Patterns - Elements of Reusable Object-Oriented Software"><a id="biblio.gof"/><p>[biblio.gof] <span class="title"><em>
988 Design Patterns - Elements of Reusable Object-Oriented Software
989 </em>. </span><span class="date">
991 . </span><span class="authorgroup"><span class="firstname">
993 </span> <span class="surname">
995 </span>, <span class="firstname">
997 </span> <span class="surname">
999 </span>, <span class="firstname">
1001 </span> <span class="surname">
1003 </span>, and <span class="firstname">
1005 </span> <span class="surname">
1007 </span>. </span><span class="publisher"><span class="publishername">
1008 Addison-Wesley Publishing Company
1009 . </span></span></p></div><div class="biblioentry" title="Order-preserving key transformations"><a id="biblio.garg86order"/><p>[biblio.garg86order] <span class="title"><em>
1010 Order-preserving key transformations
1011 </em>. </span><span class="date">
1013 . </span><span class="authorgroup"><span class="firstname">
1015 </span> <span class="surname">
1017 </span> and <span class="firstname">
1019 </span> <span class="surname">
1021 </span>. </span><span class="publisher"><span class="publishername">
1022 Trans. Database Syst. 11
1023 . </span></span></p></div><div class="biblioentry" title="Making a real hash of things"><a id="biblio.hyslop02making"/><p>[biblio.hyslop02making] <span class="title"><em>
1024 Making a real hash of things
1025 </em>. </span><span class="date">
1027 . </span><span class="authorgroup"><span class="firstname">
1029 </span> <span class="surname">
1031 </span> and <span class="firstname">
1033 </span> <span class="surname">
1035 </span>. </span><span class="publisher"><span class="publishername">
1037 . </span></span></p></div><div class="biblioentry" title="The C++ Standard Library - A Tutorial and Reference"><a id="biblio.jossutis01stl"/><p>[biblio.jossutis01stl] <span class="title"><em>
1038 The C++ Standard Library - A Tutorial and Reference
1039 </em>. </span><span class="date">
1041 . </span><span class="author"><span class="firstname">
1043 </span> <span class="surname">
1045 </span>. </span><span class="publisher"><span class="publishername">
1046 Addison-Wesley Publishing Company
1047 . </span></span></p></div><div class="biblioentry" title="New Heap Data Structures"><a id="biblio.kt99fat_heaps"/><p>[biblio.kt99fat_heaps] <span class="title"><em>
1048 <a class="link" href="http://www.cs.princeton.edu/research/techreps/TR-597-99">
1049 New Heap Data Structures
1051 </em>. </span><span class="date">
1053 . </span><span class="authorgroup"><span class="firstname">
1055 </span> <span class="surname">
1057 </span> and <span class="firstname">
1059 </span> <span class="surname">
1061 </span>. </span></p></div><div class="biblioentry" title="Are Set Iterators Mutable or Immutable?"><a id="biblio.kleft00sets"/><p>[biblio.kleft00sets] <span class="title"><em>
1062 Are Set Iterators Mutable or Immutable?
1063 </em>. </span><span class="date">
1065 . </span><span class="authorgroup"><span class="firstname">
1067 </span> <span class="surname">
1069 </span> and <span class="firstname">
1071 </span> <span class="surname">
1073 </span>. </span><span class="publisher"><span class="publishername">
1075 . </span></span></p></div><div class="biblioentry" title="The Art of Computer Programming - Sorting and Searching"><a id="biblio.knuth98sorting"/><p>[biblio.knuth98sorting] <span class="title"><em>
1076 The Art of Computer Programming - Sorting and Searching
1077 </em>. </span><span class="date">
1079 . </span><span class="author"><span class="firstname">
1081 </span> <span class="surname">
1083 </span>. </span><span class="publisher"><span class="publishername">
1084 Addison-Wesley Publishing Company
1085 . </span></span></p></div><div class="biblioentry" title="Data abstraction and hierarchy"><a id="biblio.liskov98data"/><p>[biblio.liskov98data] <span class="title"><em>
1086 Data abstraction and hierarchy
1087 </em>. </span><span class="date">
1089 . </span><span class="author"><span class="firstname">
1091 </span> <span class="surname">
1093 </span>. </span><span class="publisher"><span class="publishername">
1095 . </span></span></p></div><div class="biblioentry" title="Linear hashing: A new tool for file and table addressing"><a id="biblio.litwin80lh"/><p>[biblio.litwin80lh] <span class="title"><em>
1096 Linear hashing: A new tool for file and table addressing
1097 </em>. </span><span class="date">
1099 . </span><span class="author"><span class="firstname">
1101 </span> <span class="surname">
1103 </span>. </span><span class="publisher"><span class="publishername">
1104 Proceedings of International Conference on Very Large Data Bases
1105 . </span></span></p></div><div class="biblioentry" title="Deamortization - Part 2: Binomial Heaps"><a id="biblio.maverik_lowerbounds"/><p>[biblio.maverik_lowerbounds] <span class="title"><em>
1106 <a class="link" href="http://magic.aladdin.cs.cmu.edu/2005/08/01/deamortization-part-2-binomial-heaps">
1107 Deamortization - Part 2: Binomial Heaps
1109 </em>. </span><span class="date">
1111 . </span><span class="author"><span class="firstname">
1113 </span> <span class="surname">
1115 </span>. </span></p></div><div class="biblioentry" title="More Effective C++: 35 New Ways to Improve Your Programs and Designs"><a id="biblio.meyers96more"/><p>[biblio.meyers96more] <span class="title"><em>
1116 More Effective C++: 35 New Ways to Improve Your Programs and Designs
1117 </em>. </span><span class="date">
1119 . </span><span class="author"><span class="firstname">
1121 </span> <span class="surname">
1123 </span>. </span><span class="publisher"><span class="publishername">
1124 Addison-Wesley Publishing Company
1125 . </span></span></p></div><div class="biblioentry" title="How Non-Member Functions Improve Encapsulation"><a id="biblio.meyers00nonmember"/><p>[biblio.meyers00nonmember] <span class="title"><em>
1126 How Non-Member Functions Improve Encapsulation
1127 </em>. </span><span class="date">
1129 . </span><span class="author"><span class="firstname">
1131 </span> <span class="surname">
1133 </span>. </span><span class="publisher"><span class="publishername">
1135 . </span></span></p></div><div class="biblioentry" title="Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library"><a id="biblio.meyers01stl"/><p>[biblio.meyers01stl] <span class="title"><em>
1136 Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
1137 </em>. </span><span class="date">
1139 . </span><span class="author"><span class="firstname">
1141 </span> <span class="surname">
1143 </span>. </span><span class="publisher"><span class="publishername">
1144 Addison-Wesley Publishing Company
1145 . </span></span></p></div><div class="biblioentry" title="Class Template, Member Template - or Both?"><a id="biblio.meyers02both"/><p>[biblio.meyers02both] <span class="title"><em>
1146 Class Template, Member Template - or Both?
1147 </em>. </span><span class="date">
1149 . </span><span class="author"><span class="firstname">
1151 </span> <span class="surname">
1153 </span>. </span><span class="publisher"><span class="publishername">
1155 . </span></span></p></div><div class="biblioentry" title="Randomized Algorithms"><a id="biblio.motwani95random"/><p>[biblio.motwani95random] <span class="title"><em>
1156 Randomized Algorithms
1157 </em>. </span><span class="date">
1159 . </span><span class="authorgroup"><span class="firstname">
1161 </span> <span class="surname">
1163 </span> and <span class="firstname">
1165 </span> <span class="surname">
1167 </span>. </span><span class="publisher"><span class="publishername">
1168 Cambridge University Press
1169 . </span></span></p></div><div class="biblioentry" title="COM: Component Model Object Technologies"><a id="biblio.mscom"/><p>[biblio.mscom] <span class="title"><em>
1170 <a class="link" href="http://www.microsoft.com/com">
1171 COM: Component Model Object Technologies
1173 </em>. </span><span class="publisher"><span class="publishername">
1175 . </span></span></p></div><div class="biblioentry" title="Rationale for Adding Hash Tables to the C++ Standard Template Library"><a id="biblio.musser95rationale"/><p>[biblio.musser95rationale] <span class="title"><em>
1176 Rationale for Adding Hash Tables to the C++ Standard Template Library
1177 </em>. </span><span class="date">
1179 . </span><span class="author"><span class="firstname">
1181 </span> <span class="surname">
1183 </span>. </span></p></div><div class="biblioentry" title="STL Tutorial and Reference Guide"><a id="biblio.musser96stltutorial"/><p>[biblio.musser96stltutorial] <span class="title"><em>
1184 STL Tutorial and Reference Guide
1185 </em>. </span><span class="date">
1187 . </span><span class="authorgroup"><span class="firstname">
1189 </span> <span class="surname">
1191 </span> and <span class="firstname">
1193 </span> <span class="surname">
1195 </span>. </span><span class="publisher"><span class="publishername">
1196 Addison-Wesley Publishing Company
1197 . </span></span></p></div><div class="biblioentry" title="Priority Queues and the STL"><a id="biblio.nelson96stlpq"/><p>[biblio.nelson96stlpq] <span class="title"><em>
1198 <a class="link" href="http://www.dogma.net/markn/articles/pq_stl/priority.htm">Priority Queues and the STL
1200 </em>. </span><span class="date">
1202 . </span><span class="author"><span class="firstname">
1204 </span> <span class="surname">
1206 </span>. </span><span class="publisher"><span class="publishername">
1208 . </span></span></p></div><div class="biblioentry" title="Fast mergeable integer maps"><a id="biblio.okasaki98mereable"/><p>[biblio.okasaki98mereable] <span class="title"><em>
1209 Fast mergeable integer maps
1210 </em>. </span><span class="date">
1212 . </span><span class="authorgroup"><span class="firstname">
1214 </span> <span class="surname">
1216 </span> and <span class="firstname">
1218 </span> <span class="surname">
1220 </span>. </span><span class="publisher"><span class="publishername">
1222 . </span></span></p></div><div class="biblioentry" title="Standard Template Library Programmer's Guide"><a id="biblio.sgi_stl"/><p>[biblio.sgi_stl] <span class="title"><em>
1223 <a class="link" href="http://www.sgi.com/tech/stl">
1224 Standard Template Library Programmer's Guide
1226 </em>. </span><span class="author"><span class="firstname">
1228 </span> <span class="surname">
1230 </span>. </span><span class="publisher"><span class="publishername">
1232 . </span></span></p></div><div class="biblioentry" title="select"><a id="biblio.select_man"/><p>[biblio.select_man] <span class="title"><em>
1233 <a class="link" href="http://www.scit.wlv.ac.uk/cgi-bin/mansec?3C+select">
1236 </em>. </span></p></div><div class="biblioentry" title="Amortized Efficiency of List Update Problems"><a id="biblio.sleator84amortized"/><p>[biblio.sleator84amortized] <span class="title"><em>
1237 Amortized Efficiency of List Update Problems
1238 </em>. </span><span class="date">
1240 . </span><span class="authorgroup"><span class="firstname">
1242 </span> <span class="surname">
1244 </span> and <span class="firstname">
1246 </span> <span class="surname">
1248 </span>. </span><span class="publisher"><span class="publishername">
1249 ACM Symposium on Theory of Computing
1250 . </span></span></p></div><div class="biblioentry" title="Self-Adjusting Binary Search Trees"><a id="biblio.sleator85self"/><p>[biblio.sleator85self] <span class="title"><em>
1251 Self-Adjusting Binary Search Trees
1252 </em>. </span><span class="date">
1254 . </span><span class="authorgroup"><span class="firstname">
1256 </span> <span class="surname">
1258 </span> and <span class="firstname">
1260 </span> <span class="surname">
1262 </span>. </span><span class="publisher"><span class="publishername">
1263 ACM Symposium on Theory of Computing
1264 . </span></span></p></div><div class="biblioentry" title="The Standard Template Library"><a id="biblio.stepanov94standard"/><p>[biblio.stepanov94standard] <span class="title"><em>
1265 The Standard Template Library
1266 </em>. </span><span class="date">
1268 . </span><span class="authorgroup"><span class="firstname">
1270 </span> <span class="surname">
1272 </span> and <span class="firstname">
1274 </span> <span class="surname">
1276 </span>. </span></p></div><div class="biblioentry" title="The C++ Programming Langugage"><a id="biblio.stroustrup97cpp"/><p>[biblio.stroustrup97cpp] <span class="title"><em>
1277 The C++ Programming Langugage
1278 </em>. </span><span class="date">
1280 . </span><span class="author"><span class="firstname">
1282 </span> <span class="surname">
1284 </span>. </span><span class="publisher"><span class="publishername">
1285 Addison-Wesley Publishing Company
1286 . </span></span></p></div><div class="biblioentry" title="C++ Templates: The Complete Guide"><a id="biblio.vandevoorde2002cpptemplates"/><p>[biblio.vandevoorde2002cpptemplates] <span class="title"><em>
1287 C++ Templates: The Complete Guide
1288 </em>. </span><span class="date">
1290 . </span><span class="authorgroup"><span class="firstname">
1292 </span> <span class="surname">
1294 </span> and <span class="firstname">
1296 </span> <span class="surname">
1298 </span>. </span><span class="publisher"><span class="publishername">
1299 Addison-Wesley Publishing Company
1300 . </span></span></p></div><div class="biblioentry" title="Thirty Years Among the Dead"><a id="biblio.wickland96thirty"/><p>[biblio.wickland96thirty] <span class="title"><em>
1301 <a class="link" href="http://myweb.wvnet.edu/~gsa00121/books/amongdead30.zip">
1302 Thirty Years Among the Dead
1304 </em>. </span><span class="date">
1306 . </span><span class="author"><span class="firstname">
1308 </span> <span class="surname">
1310 </span>. </span><span class="publisher"><span class="publishername">
1311 National Psychological Institute
1312 . </span></span></p></div></div></div><div class="navfooter"><hr/><table width="100%" summary="Navigation footer"><tr><td align="left"><a accesskey="p" href="bk01pt03ch21s02.html">Prev</a> </td><td align="center"><a accesskey="u" href="extensions.html">Up</a></td><td align="right"> <a accesskey="n" href="policy_data_structures_using.html">Next</a></td></tr><tr><td align="left" valign="top">Implementation </td><td align="center"><a accesskey="h" href="../index.html">Home</a></td><td align="right" valign="top"> Using</td></tr></table></div></body></html>