4037 |
25 Jan 21 |
peter |
1 |
#ifndef theplu_yat_utility_ranking |
4037 |
25 Jan 21 |
peter |
2 |
#define theplu_yat_utility_ranking |
4037 |
25 Jan 21 |
peter |
3 |
|
4037 |
25 Jan 21 |
peter |
// $Id$ |
4037 |
25 Jan 21 |
peter |
5 |
|
4037 |
25 Jan 21 |
peter |
6 |
/* |
4037 |
25 Jan 21 |
peter |
Copyright (C) 2021 Peter Johansson |
4037 |
25 Jan 21 |
peter |
8 |
|
4037 |
25 Jan 21 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
4037 |
25 Jan 21 |
peter |
10 |
|
4037 |
25 Jan 21 |
peter |
The yat library is free software; you can redistribute it and/or |
4037 |
25 Jan 21 |
peter |
modify it under the terms of the GNU General Public License as |
4037 |
25 Jan 21 |
peter |
published by the Free Software Foundation; either version 3 of the |
4037 |
25 Jan 21 |
peter |
License, or (at your option) any later version. |
4037 |
25 Jan 21 |
peter |
15 |
|
4037 |
25 Jan 21 |
peter |
The yat library is distributed in the hope that it will be useful, |
4037 |
25 Jan 21 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
4037 |
25 Jan 21 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
4037 |
25 Jan 21 |
peter |
General Public License for more details. |
4037 |
25 Jan 21 |
peter |
20 |
|
4037 |
25 Jan 21 |
peter |
You should have received a copy of the GNU General Public License |
4037 |
25 Jan 21 |
peter |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
4037 |
25 Jan 21 |
peter |
23 |
*/ |
4037 |
25 Jan 21 |
peter |
24 |
|
4064 |
05 Aug 21 |
peter |
25 |
#include "ranking/Impl.h" |
4064 |
05 Aug 21 |
peter |
26 |
#include "ranking/Iterator.h" |
4064 |
05 Aug 21 |
peter |
27 |
#include "ranking/NodeBase.h" |
4064 |
05 Aug 21 |
peter |
28 |
#include "ranking/NodeValue.h" |
4064 |
05 Aug 21 |
peter |
29 |
|
4037 |
25 Jan 21 |
peter |
30 |
#include "yat_assert.h" |
4037 |
25 Jan 21 |
peter |
31 |
|
4037 |
25 Jan 21 |
peter |
32 |
#include <cstddef> |
4037 |
25 Jan 21 |
peter |
33 |
#include <functional> |
4077 |
26 Aug 21 |
peter |
34 |
#include <iostream> |
4077 |
26 Aug 21 |
peter |
35 |
#include <iterator> |
4037 |
25 Jan 21 |
peter |
36 |
#include <memory> |
4037 |
25 Jan 21 |
peter |
37 |
|
4037 |
25 Jan 21 |
peter |
38 |
namespace theplu { |
4037 |
25 Jan 21 |
peter |
39 |
namespace yat { |
4037 |
25 Jan 21 |
peter |
40 |
namespace utility { |
4037 |
25 Jan 21 |
peter |
41 |
|
4065 |
05 Aug 21 |
peter |
42 |
/** |
4081 |
26 Aug 21 |
peter |
Class is a binary tree with the special extension that it allows |
4065 |
05 Aug 21 |
peter |
fast access to the rank of an element in the tree. |
4070 |
09 Aug 21 |
peter |
45 |
|
4070 |
09 Aug 21 |
peter |
\since New in yat 0.19 |
4065 |
05 Aug 21 |
peter |
47 |
*/ |
4037 |
25 Jan 21 |
peter |
48 |
template<typename T, class Compare = std::less<T> > |
4064 |
05 Aug 21 |
peter |
49 |
class Ranking |
4037 |
25 Jan 21 |
peter |
50 |
{ |
4037 |
25 Jan 21 |
peter |
51 |
public: |
4065 |
05 Aug 21 |
peter |
/// value type |
4037 |
25 Jan 21 |
peter |
53 |
typedef T value_type; |
4065 |
05 Aug 21 |
peter |
/// type used to compare elements |
4037 |
25 Jan 21 |
peter |
55 |
typedef Compare key_compare; |
4087 |
30 Aug 21 |
peter |
/// reference |
4087 |
30 Aug 21 |
peter |
57 |
typedef const T& reference; |
4087 |
30 Aug 21 |
peter |
/// reference |
4087 |
30 Aug 21 |
peter |
59 |
typedef const T& const_reference; |
4087 |
30 Aug 21 |
peter |
/// pointer |
4087 |
30 Aug 21 |
peter |
61 |
typedef const T* pointer; |
4087 |
30 Aug 21 |
peter |
/// const pointer |
4087 |
30 Aug 21 |
peter |
63 |
typedef const T* const_pointer; |
4065 |
05 Aug 21 |
peter |
/// size type |
4037 |
25 Jan 21 |
peter |
65 |
typedef size_t size_type; |
4065 |
05 Aug 21 |
peter |
/// iterator |
4037 |
25 Jan 21 |
peter |
67 |
typedef ranking::Iterator<T> iterator; |
4065 |
05 Aug 21 |
peter |
/// iterator |
4037 |
25 Jan 21 |
peter |
69 |
typedef ranking::Iterator<T> const_iterator; |
4065 |
05 Aug 21 |
peter |
/// reverse iterator |
4037 |
25 Jan 21 |
peter |
71 |
typedef std::reverse_iterator<iterator> reverse_iterator; |
4065 |
05 Aug 21 |
peter |
/// reverse iterator |
4037 |
25 Jan 21 |
peter |
73 |
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
4037 |
25 Jan 21 |
peter |
74 |
|
4064 |
05 Aug 21 |
peter |
75 |
/** |
4064 |
05 Aug 21 |
peter |
\brief Default constructor |
4064 |
05 Aug 21 |
peter |
77 |
*/ |
4037 |
25 Jan 21 |
peter |
78 |
Ranking(void) = default; |
4037 |
25 Jan 21 |
peter |
79 |
|
4064 |
05 Aug 21 |
peter |
80 |
/** |
4074 |
20 Aug 21 |
peter |
\brief Destructor |
4074 |
20 Aug 21 |
peter |
82 |
*/ |
4074 |
20 Aug 21 |
peter |
83 |
~Ranking(void) |
4074 |
20 Aug 21 |
peter |
84 |
{ |
4074 |
20 Aug 21 |
peter |
85 |
clear(); |
4074 |
20 Aug 21 |
peter |
86 |
} |
4074 |
20 Aug 21 |
peter |
87 |
|
4074 |
20 Aug 21 |
peter |
88 |
/** |
4064 |
05 Aug 21 |
peter |
Construct empty container with comparison function \c c. |
4064 |
05 Aug 21 |
peter |
90 |
*/ |
4064 |
05 Aug 21 |
peter |
91 |
Ranking(const Compare& c) |
4064 |
05 Aug 21 |
peter |
92 |
: compare_(c) |
4064 |
05 Aug 21 |
peter |
93 |
{ |
4064 |
05 Aug 21 |
peter |
94 |
YAT_ASSERT(validate()); |
4064 |
05 Aug 21 |
peter |
95 |
} |
4037 |
25 Jan 21 |
peter |
96 |
|
4037 |
25 Jan 21 |
peter |
97 |
|
4065 |
05 Aug 21 |
peter |
98 |
/** |
4065 |
05 Aug 21 |
peter |
\brief Copy constructor |
4065 |
05 Aug 21 |
peter |
100 |
*/ |
4069 |
06 Aug 21 |
peter |
101 |
Ranking(const Ranking& other); |
4065 |
05 Aug 21 |
peter |
102 |
|
4065 |
05 Aug 21 |
peter |
103 |
/** |
4065 |
05 Aug 21 |
peter |
\brief move constructor |
4065 |
05 Aug 21 |
peter |
105 |
*/ |
4069 |
06 Aug 21 |
peter |
106 |
Ranking(Ranking&& other); |
4065 |
05 Aug 21 |
peter |
107 |
|
4065 |
05 Aug 21 |
peter |
108 |
/** |
4065 |
05 Aug 21 |
peter |
\brief assignment operator |
4065 |
05 Aug 21 |
peter |
110 |
*/ |
4064 |
05 Aug 21 |
peter |
111 |
Ranking& operator=(const Ranking& other); |
4065 |
05 Aug 21 |
peter |
112 |
|
4065 |
05 Aug 21 |
peter |
113 |
/** |
4065 |
05 Aug 21 |
peter |
\brief move assignment |
4065 |
05 Aug 21 |
peter |
115 |
*/ |
4064 |
05 Aug 21 |
peter |
116 |
Ranking& operator=(Ranking&& other); |
4037 |
25 Jan 21 |
peter |
117 |
|
4037 |
25 Jan 21 |
peter |
118 |
|
4065 |
05 Aug 21 |
peter |
119 |
/** |
4077 |
26 Aug 21 |
peter |
\return iterator pointing to the first element, i.e., the |
4077 |
26 Aug 21 |
peter |
node with the smallest value. |
4065 |
05 Aug 21 |
peter |
122 |
*/ |
4064 |
05 Aug 21 |
peter |
123 |
iterator begin(void) |
4064 |
05 Aug 21 |
peter |
124 |
{ |
4072 |
20 Aug 21 |
peter |
125 |
return iterator(impl_.left_most()); |
4064 |
05 Aug 21 |
peter |
126 |
} |
4037 |
25 Jan 21 |
peter |
127 |
|
4037 |
25 Jan 21 |
peter |
128 |
|
4065 |
05 Aug 21 |
peter |
129 |
/** |
4065 |
05 Aug 21 |
peter |
\return iterator pointing to the first element |
4065 |
05 Aug 21 |
peter |
131 |
*/ |
4064 |
05 Aug 21 |
peter |
132 |
const_iterator begin(void) const |
4064 |
05 Aug 21 |
peter |
133 |
{ |
4064 |
05 Aug 21 |
peter |
134 |
return cbegin(); |
4064 |
05 Aug 21 |
peter |
135 |
} |
4037 |
25 Jan 21 |
peter |
136 |
|
4037 |
25 Jan 21 |
peter |
137 |
|
4065 |
05 Aug 21 |
peter |
138 |
/** |
4065 |
05 Aug 21 |
peter |
\return iterator pointing to the first element |
4065 |
05 Aug 21 |
peter |
140 |
*/ |
4064 |
05 Aug 21 |
peter |
141 |
const_iterator cbegin(void) const |
4064 |
05 Aug 21 |
peter |
142 |
{ |
4072 |
20 Aug 21 |
peter |
143 |
return const_iterator(impl_.left_most()); |
4064 |
05 Aug 21 |
peter |
144 |
} |
4037 |
25 Jan 21 |
peter |
145 |
|
4037 |
25 Jan 21 |
peter |
146 |
|
4065 |
05 Aug 21 |
peter |
147 |
/** |
4065 |
05 Aug 21 |
peter |
\return iterator pointing to one-passed-last element |
4065 |
05 Aug 21 |
peter |
149 |
*/ |
4064 |
05 Aug 21 |
peter |
150 |
iterator end(void) |
4064 |
05 Aug 21 |
peter |
151 |
{ |
4064 |
05 Aug 21 |
peter |
152 |
return iterator(&impl_.head_); |
4064 |
05 Aug 21 |
peter |
153 |
} |
4037 |
25 Jan 21 |
peter |
154 |
|
4037 |
25 Jan 21 |
peter |
155 |
|
4065 |
05 Aug 21 |
peter |
156 |
/** |
4065 |
05 Aug 21 |
peter |
\return iterator pointing to one-passed-last element |
4065 |
05 Aug 21 |
peter |
158 |
*/ |
4064 |
05 Aug 21 |
peter |
159 |
const_iterator end(void) const |
4064 |
05 Aug 21 |
peter |
160 |
{ |
4064 |
05 Aug 21 |
peter |
161 |
return cend(); |
4064 |
05 Aug 21 |
peter |
162 |
} |
4037 |
25 Jan 21 |
peter |
163 |
|
4037 |
25 Jan 21 |
peter |
164 |
|
4065 |
05 Aug 21 |
peter |
165 |
/** |
4065 |
05 Aug 21 |
peter |
\return iterator pointing to one-passed-last element |
4065 |
05 Aug 21 |
peter |
167 |
*/ |
4064 |
05 Aug 21 |
peter |
168 |
const_iterator cend(void) const |
4064 |
05 Aug 21 |
peter |
169 |
{ |
4064 |
05 Aug 21 |
peter |
170 |
return const_iterator(&impl_.head_); |
4064 |
05 Aug 21 |
peter |
171 |
} |
4037 |
25 Jan 21 |
peter |
172 |
|
4037 |
25 Jan 21 |
peter |
173 |
|
4065 |
05 Aug 21 |
peter |
174 |
/** |
4077 |
26 Aug 21 |
peter |
\return reverse iterator pointing to first element, i.e., the |
4077 |
26 Aug 21 |
peter |
node with the largest value. |
4065 |
05 Aug 21 |
peter |
177 |
*/ |
4064 |
05 Aug 21 |
peter |
178 |
reverse_iterator rbegin(void) |
4064 |
05 Aug 21 |
peter |
179 |
{ |
4064 |
05 Aug 21 |
peter |
180 |
return reverse_iterator(end()); |
4064 |
05 Aug 21 |
peter |
181 |
} |
4064 |
05 Aug 21 |
peter |
182 |
|
4064 |
05 Aug 21 |
peter |
183 |
|
4065 |
05 Aug 21 |
peter |
184 |
/** |
4065 |
05 Aug 21 |
peter |
\return reverse iterator pointing to one-passed-last element |
4065 |
05 Aug 21 |
peter |
186 |
*/ |
4064 |
05 Aug 21 |
peter |
187 |
reverse_iterator rend(void) |
4064 |
05 Aug 21 |
peter |
188 |
{ |
4064 |
05 Aug 21 |
peter |
189 |
return reverse_iterator(begin()); |
4064 |
05 Aug 21 |
peter |
190 |
} |
4064 |
05 Aug 21 |
peter |
191 |
|
4064 |
05 Aug 21 |
peter |
192 |
|
4065 |
05 Aug 21 |
peter |
193 |
/** |
4065 |
05 Aug 21 |
peter |
\return reverse iterator pointing to one-passed-last element |
4065 |
05 Aug 21 |
peter |
195 |
*/ |
4064 |
05 Aug 21 |
peter |
196 |
const_reverse_iterator rend(void) const |
4064 |
05 Aug 21 |
peter |
197 |
{ |
4064 |
05 Aug 21 |
peter |
198 |
return crend(); |
4064 |
05 Aug 21 |
peter |
199 |
} |
4064 |
05 Aug 21 |
peter |
200 |
|
4064 |
05 Aug 21 |
peter |
201 |
|
4065 |
05 Aug 21 |
peter |
202 |
/** |
4065 |
05 Aug 21 |
peter |
\return reverse iterator pointing to first element |
4065 |
05 Aug 21 |
peter |
204 |
*/ |
4064 |
05 Aug 21 |
peter |
205 |
const_reverse_iterator rbegin(void) const |
4064 |
05 Aug 21 |
peter |
206 |
{ |
4064 |
05 Aug 21 |
peter |
207 |
return crbegin(); |
4064 |
05 Aug 21 |
peter |
208 |
} |
4064 |
05 Aug 21 |
peter |
209 |
|
4064 |
05 Aug 21 |
peter |
210 |
|
4065 |
05 Aug 21 |
peter |
211 |
/** |
4065 |
05 Aug 21 |
peter |
\return reverse iterator pointing to first element |
4065 |
05 Aug 21 |
peter |
213 |
*/ |
4037 |
25 Jan 21 |
peter |
214 |
const_reverse_iterator crbegin(void) const |
4064 |
05 Aug 21 |
peter |
215 |
{ |
4064 |
05 Aug 21 |
peter |
216 |
return const_reverse_iterator(cend()); |
4064 |
05 Aug 21 |
peter |
217 |
} |
4037 |
25 Jan 21 |
peter |
218 |
|
4065 |
05 Aug 21 |
peter |
219 |
/** |
4065 |
05 Aug 21 |
peter |
\return reverse iterator pointing to the one-passed-last element |
4065 |
05 Aug 21 |
peter |
221 |
*/ |
4037 |
25 Jan 21 |
peter |
222 |
const_reverse_iterator crend(void) const |
4064 |
05 Aug 21 |
peter |
223 |
{ |
4064 |
05 Aug 21 |
peter |
224 |
return const_reverse_iterator(cbegin()); |
4064 |
05 Aug 21 |
peter |
225 |
} |
4037 |
25 Jan 21 |
peter |
226 |
|
4037 |
25 Jan 21 |
peter |
227 |
|
4065 |
05 Aug 21 |
peter |
228 |
/** |
4070 |
09 Aug 21 |
peter |
Remove all nodes |
4070 |
09 Aug 21 |
peter |
230 |
*/ |
4070 |
09 Aug 21 |
peter |
231 |
void clear(void) |
4070 |
09 Aug 21 |
peter |
232 |
{ |
4070 |
09 Aug 21 |
peter |
233 |
if (size()) { |
4072 |
20 Aug 21 |
peter |
234 |
YAT_ASSERT(root_node() != head_node()); |
4072 |
20 Aug 21 |
peter |
235 |
erase(root_node()); |
4070 |
09 Aug 21 |
peter |
236 |
} |
4070 |
09 Aug 21 |
peter |
237 |
impl_.reset(); |
4070 |
09 Aug 21 |
peter |
238 |
} |
4070 |
09 Aug 21 |
peter |
239 |
|
4070 |
09 Aug 21 |
peter |
240 |
|
4070 |
09 Aug 21 |
peter |
241 |
/** |
4065 |
05 Aug 21 |
peter |
access comparison function which is used to sort elements |
4065 |
05 Aug 21 |
peter |
243 |
*/ |
4064 |
05 Aug 21 |
peter |
244 |
const Compare& compare(void) const |
4064 |
05 Aug 21 |
peter |
245 |
{ |
4064 |
05 Aug 21 |
peter |
246 |
return compare_; |
4064 |
05 Aug 21 |
peter |
247 |
} |
4037 |
25 Jan 21 |
peter |
248 |
|
4037 |
25 Jan 21 |
peter |
249 |
|
4065 |
05 Aug 21 |
peter |
250 |
/** |
4065 |
05 Aug 21 |
peter |
\return true if (and only if) container has zero elements |
4065 |
05 Aug 21 |
peter |
252 |
*/ |
4064 |
05 Aug 21 |
peter |
253 |
bool empty(void) const |
4064 |
05 Aug 21 |
peter |
254 |
{ |
4072 |
20 Aug 21 |
peter |
255 |
return impl_.empty(); |
4064 |
05 Aug 21 |
peter |
256 |
} |
4037 |
25 Jan 21 |
peter |
257 |
|
4064 |
05 Aug 21 |
peter |
258 |
|
4065 |
05 Aug 21 |
peter |
259 |
/** |
4077 |
26 Aug 21 |
peter |
Remove node pointed to by \c position. |
4070 |
09 Aug 21 |
peter |
261 |
|
4070 |
09 Aug 21 |
peter |
\return An iterator pointing to the element that follows the |
4070 |
09 Aug 21 |
peter |
last element removed. |
4087 |
30 Aug 21 |
peter |
264 |
|
4087 |
30 Aug 21 |
peter |
Complexity: constant time. |
4070 |
09 Aug 21 |
peter |
266 |
*/ |
4070 |
09 Aug 21 |
peter |
267 |
iterator erase(const_iterator position); |
4070 |
09 Aug 21 |
peter |
268 |
|
4070 |
09 Aug 21 |
peter |
269 |
/** |
4070 |
09 Aug 21 |
peter |
Erase all elements that are equivalent with \c value |
4070 |
09 Aug 21 |
peter |
\return number of elements removed |
4087 |
30 Aug 21 |
peter |
272 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4070 |
09 Aug 21 |
peter |
274 |
*/ |
4070 |
09 Aug 21 |
peter |
275 |
size_type erase(const T& value); |
4070 |
09 Aug 21 |
peter |
276 |
|
4070 |
09 Aug 21 |
peter |
277 |
/** |
4070 |
09 Aug 21 |
peter |
Remove elements in range [first, last). |
4070 |
09 Aug 21 |
peter |
279 |
|
4070 |
09 Aug 21 |
peter |
\return An iterator pointing to the element that follows the |
4070 |
09 Aug 21 |
peter |
last element removed. |
4087 |
30 Aug 21 |
peter |
282 |
|
4087 |
30 Aug 21 |
peter |
Complexity: Linear in number of elements erased. |
4070 |
09 Aug 21 |
peter |
284 |
*/ |
4070 |
09 Aug 21 |
peter |
285 |
iterator erase(const_iterator first, const_iterator last); |
4070 |
09 Aug 21 |
peter |
286 |
|
4070 |
09 Aug 21 |
peter |
287 |
/** |
4087 |
30 Aug 21 |
peter |
Find an element that is equivalent to x. |
4087 |
30 Aug 21 |
peter |
289 |
|
4087 |
30 Aug 21 |
peter |
\return end() if no such element exists |
4087 |
30 Aug 21 |
peter |
291 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4065 |
05 Aug 21 |
peter |
293 |
*/ |
4037 |
25 Jan 21 |
peter |
294 |
const_iterator find(const T& x) const; |
4037 |
25 Jan 21 |
peter |
295 |
|
4037 |
25 Jan 21 |
peter |
296 |
|
4065 |
05 Aug 21 |
peter |
297 |
/** |
4065 |
05 Aug 21 |
peter |
\brief insert an element |
4087 |
30 Aug 21 |
peter |
299 |
|
4087 |
30 Aug 21 |
peter |
\return a n iterator pointing to just inserted element |
4087 |
30 Aug 21 |
peter |
301 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4065 |
05 Aug 21 |
peter |
303 |
*/ |
4037 |
25 Jan 21 |
peter |
304 |
iterator insert(const T& element) |
4037 |
25 Jan 21 |
peter |
305 |
{ |
4037 |
25 Jan 21 |
peter |
306 |
std::unique_ptr<ranking::NodeValue<T>> |
4037 |
25 Jan 21 |
peter |
307 |
newnode(new ranking::NodeValue<T>(element)); |
4037 |
25 Jan 21 |
peter |
308 |
return insert(std::move(newnode)); |
4037 |
25 Jan 21 |
peter |
309 |
} |
4037 |
25 Jan 21 |
peter |
310 |
|
4037 |
25 Jan 21 |
peter |
311 |
|
4065 |
05 Aug 21 |
peter |
312 |
/** |
4065 |
05 Aug 21 |
peter |
\brief insert an element |
4087 |
30 Aug 21 |
peter |
314 |
|
4087 |
30 Aug 21 |
peter |
Same as insert(const T& element) but moves rather than copy \c |
4087 |
30 Aug 21 |
peter |
element. |
4065 |
05 Aug 21 |
peter |
317 |
*/ |
4037 |
25 Jan 21 |
peter |
318 |
iterator insert(T&& element) |
4037 |
25 Jan 21 |
peter |
319 |
{ |
4037 |
25 Jan 21 |
peter |
320 |
std::unique_ptr<ranking::NodeValue<T>> |
4037 |
25 Jan 21 |
peter |
321 |
newnode(new ranking::NodeValue<T>(std::move(element))); |
4037 |
25 Jan 21 |
peter |
322 |
return insert(std::move(newnode)); |
4037 |
25 Jan 21 |
peter |
323 |
} |
4037 |
25 Jan 21 |
peter |
324 |
|
4037 |
25 Jan 21 |
peter |
325 |
|
4065 |
05 Aug 21 |
peter |
326 |
/** |
4065 |
05 Aug 21 |
peter |
\brief insert with hint |
4077 |
26 Aug 21 |
peter |
328 |
|
4077 |
26 Aug 21 |
peter |
If \c hint will follow the inserted element, the insertion is done |
4077 |
26 Aug 21 |
peter |
in constant time. Otherwise, the usual insert function is |
4077 |
26 Aug 21 |
peter |
called which takes logN. |
4065 |
05 Aug 21 |
peter |
332 |
*/ |
4037 |
25 Jan 21 |
peter |
333 |
iterator insert(const_iterator hint, const T& element) |
4037 |
25 Jan 21 |
peter |
334 |
{ |
4077 |
26 Aug 21 |
peter |
335 |
std::unique_ptr<ranking::NodeValue<T>> |
4077 |
26 Aug 21 |
peter |
336 |
newnode(new ranking::NodeValue<T>(element)); |
4077 |
26 Aug 21 |
peter |
337 |
return insert(hint, std::move(newnode)); |
4037 |
25 Jan 21 |
peter |
338 |
} |
4037 |
25 Jan 21 |
peter |
339 |
|
4037 |
25 Jan 21 |
peter |
340 |
|
4065 |
05 Aug 21 |
peter |
341 |
/** |
4065 |
05 Aug 21 |
peter |
\brief insert with hint |
4087 |
30 Aug 21 |
peter |
343 |
|
4087 |
30 Aug 21 |
peter |
Same as as insert(const_iterator, const T&) but move instead of |
4087 |
30 Aug 21 |
peter |
copy \c element. |
4065 |
05 Aug 21 |
peter |
346 |
*/ |
4037 |
25 Jan 21 |
peter |
347 |
iterator insert(const_iterator hint, T&& element) |
4037 |
25 Jan 21 |
peter |
348 |
{ |
4077 |
26 Aug 21 |
peter |
349 |
std::unique_ptr<ranking::NodeValue<T>> |
4077 |
26 Aug 21 |
peter |
350 |
newnode(new ranking::NodeValue<T>(std::move(element))); |
4077 |
26 Aug 21 |
peter |
351 |
return insert(hint, std::move(newnode)); |
4037 |
25 Jan 21 |
peter |
352 |
} |
4037 |
25 Jan 21 |
peter |
353 |
|
4037 |
25 Jan 21 |
peter |
354 |
|
4065 |
05 Aug 21 |
peter |
355 |
/** |
4065 |
05 Aug 21 |
peter |
\brief insert range |
4087 |
30 Aug 21 |
peter |
357 |
|
4087 |
30 Aug 21 |
peter |
Complexity: N log S, where S is size of container and N is |
4087 |
30 Aug 21 |
peter |
number of inserted elements. If inserted range is sorted, |
4087 |
30 Aug 21 |
peter |
complexity linear, N. |
4065 |
05 Aug 21 |
peter |
361 |
*/ |
4037 |
25 Jan 21 |
peter |
362 |
template<typename InputIterator> |
4037 |
25 Jan 21 |
peter |
363 |
void insert(InputIterator first, InputIterator last) |
4037 |
25 Jan 21 |
peter |
364 |
{ |
4037 |
25 Jan 21 |
peter |
365 |
for (; first!=last; ++first) |
4037 |
25 Jan 21 |
peter |
366 |
insert(end(), *first); |
4037 |
25 Jan 21 |
peter |
367 |
} |
4037 |
25 Jan 21 |
peter |
368 |
|
4037 |
25 Jan 21 |
peter |
369 |
|
4065 |
05 Aug 21 |
peter |
370 |
/** |
4065 |
05 Aug 21 |
peter |
\return the first element which is equal (or greater) to \c x |
4087 |
30 Aug 21 |
peter |
372 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4065 |
05 Aug 21 |
peter |
374 |
*/ |
4037 |
25 Jan 21 |
peter |
375 |
const_iterator lower_bound(const T& x) const |
4037 |
25 Jan 21 |
peter |
376 |
{ |
4064 |
05 Aug 21 |
peter |
377 |
if (empty()) |
4064 |
05 Aug 21 |
peter |
378 |
return cend(); |
4072 |
20 Aug 21 |
peter |
379 |
return lower_bound(root_node(), head_node(), x); |
4037 |
25 Jan 21 |
peter |
380 |
} |
4037 |
25 Jan 21 |
peter |
381 |
|
4037 |
25 Jan 21 |
peter |
382 |
|
4065 |
05 Aug 21 |
peter |
383 |
/** |
4065 |
05 Aug 21 |
peter |
\return the first element which is greater than \c x |
4087 |
30 Aug 21 |
peter |
385 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4065 |
05 Aug 21 |
peter |
387 |
*/ |
4037 |
25 Jan 21 |
peter |
388 |
const_iterator upper_bound(const T& x) const |
4037 |
25 Jan 21 |
peter |
389 |
{ |
4064 |
05 Aug 21 |
peter |
390 |
if (empty()) |
4064 |
05 Aug 21 |
peter |
391 |
return cend(); |
4072 |
20 Aug 21 |
peter |
392 |
return upper_bound(root_node(), head_node(), x); |
4037 |
25 Jan 21 |
peter |
393 |
} |
4037 |
25 Jan 21 |
peter |
394 |
|
4037 |
25 Jan 21 |
peter |
395 |
|
4065 |
05 Aug 21 |
peter |
396 |
/** |
4065 |
05 Aug 21 |
peter |
\return number of elements smaller than \c it |
4087 |
30 Aug 21 |
peter |
398 |
|
4087 |
30 Aug 21 |
peter |
Complexity: logarithmic in size of container. |
4065 |
05 Aug 21 |
peter |
400 |
*/ |
4037 |
25 Jan 21 |
peter |
401 |
size_t ranking(const_iterator it) const |
4037 |
25 Jan 21 |
peter |
402 |
{ |
4072 |
20 Aug 21 |
peter |
403 |
YAT_ASSERT(it.node_); |
4071 |
18 Aug 21 |
peter |
404 |
return impl_.ranking(it.node_); |
4037 |
25 Jan 21 |
peter |
405 |
} |
4037 |
25 Jan 21 |
peter |
406 |
|
4037 |
25 Jan 21 |
peter |
407 |
|
4065 |
05 Aug 21 |
peter |
408 |
/** |
4065 |
05 Aug 21 |
peter |
\return number of elements in container |
4087 |
30 Aug 21 |
peter |
410 |
|
4087 |
30 Aug 21 |
peter |
Complexity: constant time |
4065 |
05 Aug 21 |
peter |
412 |
*/ |
4064 |
05 Aug 21 |
peter |
413 |
size_t size(void) const |
4064 |
05 Aug 21 |
peter |
414 |
{ |
4072 |
20 Aug 21 |
peter |
415 |
return impl_.size(); |
4064 |
05 Aug 21 |
peter |
416 |
} |
4064 |
05 Aug 21 |
peter |
417 |
|
4037 |
25 Jan 21 |
peter |
418 |
private: |
4064 |
05 Aug 21 |
peter |
419 |
Compare compare_; |
4087 |
30 Aug 21 |
peter |
// Things that are agnostic to T are implemented in impl_. |
4064 |
05 Aug 21 |
peter |
421 |
ranking::Impl impl_; |
4064 |
05 Aug 21 |
peter |
422 |
|
4077 |
26 Aug 21 |
peter |
423 |
iterator |
4077 |
26 Aug 21 |
peter |
424 |
insert_and_rebalance(std::unique_ptr<ranking::NodeValue<T>>&& element, |
4077 |
26 Aug 21 |
peter |
425 |
ranking::NodeBase& parent, bool left) |
4077 |
26 Aug 21 |
peter |
426 |
{ |
4077 |
26 Aug 21 |
peter |
427 |
iterator result(element.get()); |
4077 |
26 Aug 21 |
peter |
428 |
impl_.insert_and_rebalance(std::move(element), parent, left); |
4077 |
26 Aug 21 |
peter |
429 |
YAT_ASSERT(validate()); |
4077 |
26 Aug 21 |
peter |
430 |
return result; |
4077 |
26 Aug 21 |
peter |
431 |
} |
4077 |
26 Aug 21 |
peter |
432 |
|
4077 |
26 Aug 21 |
peter |
433 |
|
4077 |
26 Aug 21 |
peter |
434 |
|
4071 |
18 Aug 21 |
peter |
435 |
void print(const ranking::NodeBase* p, std::ostream& os) const |
4037 |
25 Jan 21 |
peter |
436 |
{ |
4070 |
09 Aug 21 |
peter |
437 |
if (p) { |
4070 |
09 Aug 21 |
peter |
438 |
if (p->is_head_node()==false) { |
4071 |
18 Aug 21 |
peter |
439 |
print(p->right_, os); |
4070 |
09 Aug 21 |
peter |
440 |
} |
4071 |
18 Aug 21 |
peter |
441 |
os << std::string(p->generation()*4, ' '); |
4070 |
09 Aug 21 |
peter |
442 |
if (!p->is_head_node()) |
4071 |
18 Aug 21 |
peter |
443 |
os << value(p); |
4070 |
09 Aug 21 |
peter |
444 |
else |
4071 |
18 Aug 21 |
peter |
445 |
os << "H"; |
4072 |
20 Aug 21 |
peter |
446 |
os << ", H=" << ranking::height(p) << ", S=" << ranking::size(p); |
4071 |
18 Aug 21 |
peter |
447 |
os << ": " |
4072 |
20 Aug 21 |
peter |
448 |
<< p->parent_ << " " |
4072 |
20 Aug 21 |
peter |
449 |
<< p << " " |
4072 |
20 Aug 21 |
peter |
450 |
<< p->left_ << " " |
4072 |
20 Aug 21 |
peter |
451 |
<< p->right_ << "\n"; |
4070 |
09 Aug 21 |
peter |
452 |
if (p->is_head_node()==false) { |
4071 |
18 Aug 21 |
peter |
453 |
print(p->left_, os); |
4070 |
09 Aug 21 |
peter |
454 |
} |
4070 |
09 Aug 21 |
peter |
455 |
if (p->parent_ && !p->is_left_node() && !p->is_right_node()) { |
4071 |
18 Aug 21 |
peter |
456 |
os << "print error: " << p << "\n"; |
4070 |
09 Aug 21 |
peter |
457 |
exit(1); |
4070 |
09 Aug 21 |
peter |
458 |
} |
4069 |
06 Aug 21 |
peter |
459 |
} |
4037 |
25 Jan 21 |
peter |
460 |
} |
4037 |
25 Jan 21 |
peter |
461 |
|
4069 |
06 Aug 21 |
peter |
// return a copy of x but with children and parent set to nullptr. |
4069 |
06 Aug 21 |
peter |
463 |
ranking::NodeValue<T>* |
4069 |
06 Aug 21 |
peter |
464 |
clone_node(const ranking::NodeValue<T>* x) const; |
4037 |
25 Jan 21 |
peter |
465 |
|
4069 |
06 Aug 21 |
peter |
466 |
/** |
4069 |
06 Aug 21 |
peter |
copy data in other.Impl_ into impl_ |
4037 |
25 Jan 21 |
peter |
468 |
|
4069 |
06 Aug 21 |
peter |
Basically copy constructor of Impl but nodes (except for head |
4069 |
06 Aug 21 |
peter |
node) are copied as NodeValue<T> and Impl is not aware of T. |
4069 |
06 Aug 21 |
peter |
471 |
*/ |
4069 |
06 Aug 21 |
peter |
472 |
ranking::NodeValue<T>* copy(const Ranking& other); |
4037 |
25 Jan 21 |
peter |
473 |
|
4069 |
06 Aug 21 |
peter |
474 |
/** |
4069 |
06 Aug 21 |
peter |
Create a copy of root and return it |
4069 |
06 Aug 21 |
peter |
476 |
*/ |
4072 |
20 Aug 21 |
peter |
477 |
ranking::NodeValue<T>* copy(const ranking::NodeValue<T>* root) const; |
4037 |
25 Jan 21 |
peter |
478 |
|
4070 |
09 Aug 21 |
peter |
479 |
/** |
4070 |
09 Aug 21 |
peter |
Remove node position is pointing to |
4070 |
09 Aug 21 |
peter |
481 |
*/ |
4070 |
09 Aug 21 |
peter |
482 |
void erase_node(const_iterator position); |
4037 |
25 Jan 21 |
peter |
483 |
|
4064 |
05 Aug 21 |
peter |
// return the root node |
4072 |
20 Aug 21 |
peter |
485 |
const ranking::NodeValue<T>* root_node(void) const |
4037 |
25 Jan 21 |
peter |
486 |
{ |
4072 |
20 Aug 21 |
peter |
487 |
return static_cast<const ranking::NodeValue<T>*>(impl_.root_node()); |
4037 |
25 Jan 21 |
peter |
488 |
} |
4037 |
25 Jan 21 |
peter |
489 |
|
4037 |
25 Jan 21 |
peter |
490 |
|
4072 |
20 Aug 21 |
peter |
491 |
ranking::NodeValue<T>* root_node(void) |
4037 |
25 Jan 21 |
peter |
492 |
{ |
4072 |
20 Aug 21 |
peter |
493 |
return static_cast<ranking::NodeValue<T>*>(impl_.root_node()); |
4037 |
25 Jan 21 |
peter |
494 |
} |
4037 |
25 Jan 21 |
peter |
495 |
|
4037 |
25 Jan 21 |
peter |
496 |
|
4072 |
20 Aug 21 |
peter |
497 |
const ranking::NodeBase* head_node(void) const |
4037 |
25 Jan 21 |
peter |
498 |
{ |
4064 |
05 Aug 21 |
peter |
499 |
return &impl_.head_; |
4037 |
25 Jan 21 |
peter |
500 |
} |
4037 |
25 Jan 21 |
peter |
501 |
|
4037 |
25 Jan 21 |
peter |
502 |
|
4072 |
20 Aug 21 |
peter |
503 |
ranking::NodeBase* head_node(void) |
4037 |
25 Jan 21 |
peter |
504 |
{ |
4064 |
05 Aug 21 |
peter |
505 |
return &impl_.head_; |
4037 |
25 Jan 21 |
peter |
506 |
} |
4037 |
25 Jan 21 |
peter |
507 |
|
4037 |
25 Jan 21 |
peter |
508 |
|
4037 |
25 Jan 21 |
peter |
509 |
const ranking::NodeValue<T>* |
4037 |
25 Jan 21 |
peter |
510 |
left(const ranking::NodeBase* x) const |
4037 |
25 Jan 21 |
peter |
511 |
{ |
4064 |
05 Aug 21 |
peter |
512 |
YAT_ASSERT(x->left_ != &impl_.head_); |
4037 |
25 Jan 21 |
peter |
513 |
return static_cast<const ranking::NodeValue<T>*>(x->left_); |
4037 |
25 Jan 21 |
peter |
514 |
} |
4037 |
25 Jan 21 |
peter |
515 |
|
4037 |
25 Jan 21 |
peter |
516 |
|
4037 |
25 Jan 21 |
peter |
517 |
ranking::NodeValue<T>* |
4037 |
25 Jan 21 |
peter |
518 |
left(ranking::NodeBase* x) const |
4037 |
25 Jan 21 |
peter |
519 |
{ |
4064 |
05 Aug 21 |
peter |
520 |
YAT_ASSERT(x->left_ != &impl_.head_); |
4037 |
25 Jan 21 |
peter |
521 |
return static_cast<ranking::NodeValue<T>*>(x->left_); |
4037 |
25 Jan 21 |
peter |
522 |
} |
4037 |
25 Jan 21 |
peter |
523 |
|
4037 |
25 Jan 21 |
peter |
524 |
|
4037 |
25 Jan 21 |
peter |
525 |
const ranking::NodeValue<T>* |
4037 |
25 Jan 21 |
peter |
526 |
right(const ranking::NodeBase* x) const |
4037 |
25 Jan 21 |
peter |
527 |
{ |
4064 |
05 Aug 21 |
peter |
528 |
YAT_ASSERT(x->right_ != &impl_.head_); |
4037 |
25 Jan 21 |
peter |
529 |
return static_cast<const ranking::NodeValue<T>*>(x->right_); |
4037 |
25 Jan 21 |
peter |
530 |
} |
4037 |
25 Jan 21 |
peter |
531 |
|
4037 |
25 Jan 21 |
peter |
532 |
|
4037 |
25 Jan 21 |
peter |
533 |
ranking::NodeValue<T>* |
4037 |
25 Jan 21 |
peter |
534 |
right(ranking::NodeBase* x) const |
4037 |
25 Jan 21 |
peter |
535 |
{ |
4064 |
05 Aug 21 |
peter |
536 |
YAT_ASSERT(x->right_ != &impl_.head_); |
4037 |
25 Jan 21 |
peter |
537 |
return static_cast<ranking::NodeValue<T>*>(x->right_); |
4037 |
25 Jan 21 |
peter |
538 |
} |
4037 |
25 Jan 21 |
peter |
539 |
|
4037 |
25 Jan 21 |
peter |
540 |
|
4037 |
25 Jan 21 |
peter |
// delete x and its offsprings |
4069 |
06 Aug 21 |
peter |
542 |
void erase(ranking::NodeValue<T>* x) const |
4037 |
25 Jan 21 |
peter |
543 |
{ |
4037 |
25 Jan 21 |
peter |
544 |
while (x) { |
4077 |
26 Aug 21 |
peter |
545 |
if (x->right_) |
4069 |
06 Aug 21 |
peter |
546 |
erase(right(x)); |
4037 |
25 Jan 21 |
peter |
547 |
ranking::NodeValue<T>* tmp = left(x); |
4037 |
25 Jan 21 |
peter |
548 |
delete x; |
4037 |
25 Jan 21 |
peter |
549 |
x = tmp; |
4037 |
25 Jan 21 |
peter |
550 |
} |
4037 |
25 Jan 21 |
peter |
551 |
} |
4037 |
25 Jan 21 |
peter |
552 |
|
4037 |
25 Jan 21 |
peter |
553 |
|
4064 |
05 Aug 21 |
peter |
554 |
/** |
4064 |
05 Aug 21 |
peter |
traverse the tree and find a suitable leaf where we can insert |
4064 |
05 Aug 21 |
peter |
\c element and keep the tree sorted. |
4064 |
05 Aug 21 |
peter |
557 |
*/ |
4037 |
25 Jan 21 |
peter |
558 |
iterator insert(std::unique_ptr<ranking::NodeValue<T>>&& element) |
4037 |
25 Jan 21 |
peter |
559 |
{ |
4072 |
20 Aug 21 |
peter |
560 |
|
4064 |
05 Aug 21 |
peter |
561 |
if (empty()) { |
4072 |
20 Aug 21 |
peter |
562 |
element->parent_ = &impl_.head_; |
4072 |
20 Aug 21 |
peter |
563 |
impl_.root_node() = element.release(); |
4072 |
20 Aug 21 |
peter |
564 |
impl_.head_.left_ = impl_.root_node(); |
4072 |
20 Aug 21 |
peter |
565 |
impl_.head_.right_ = impl_.root_node(); |
4079 |
26 Aug 21 |
peter |
566 |
impl_.right_most() = impl_.root_node(); |
4072 |
20 Aug 21 |
peter |
567 |
impl_.head_.update_height(); |
4072 |
20 Aug 21 |
peter |
568 |
impl_.head_.update_size(); |
4071 |
18 Aug 21 |
peter |
569 |
|
4072 |
20 Aug 21 |
peter |
570 |
YAT_ASSERT(impl_.root_node()->parent_); |
4072 |
20 Aug 21 |
peter |
571 |
YAT_ASSERT(impl_.root_node()->parent_ == &impl_.head_); |
4072 |
20 Aug 21 |
peter |
572 |
YAT_ASSERT(impl_.root_node()->is_left_node()); |
4072 |
20 Aug 21 |
peter |
573 |
|
4064 |
05 Aug 21 |
peter |
574 |
YAT_ASSERT(validate()); |
4077 |
26 Aug 21 |
peter |
575 |
return iterator(root_node()); |
4064 |
05 Aug 21 |
peter |
576 |
} |
4064 |
05 Aug 21 |
peter |
577 |
|
4077 |
26 Aug 21 |
peter |
578 |
return insert(impl_.root_node(), std::move(element)); |
4077 |
26 Aug 21 |
peter |
579 |
} |
4077 |
26 Aug 21 |
peter |
580 |
|
4077 |
26 Aug 21 |
peter |
581 |
|
4077 |
26 Aug 21 |
peter |
// Insert \a element into the subtree in which x is the root. |
4077 |
26 Aug 21 |
peter |
583 |
iterator insert(ranking::NodeBase* x, |
4077 |
26 Aug 21 |
peter |
584 |
std::unique_ptr<ranking::NodeValue<T>>&& element) |
4077 |
26 Aug 21 |
peter |
585 |
{ |
4064 |
05 Aug 21 |
peter |
586 |
YAT_ASSERT(x); |
4064 |
05 Aug 21 |
peter |
587 |
YAT_ASSERT(!x->is_head_node()); |
4064 |
05 Aug 21 |
peter |
588 |
|
4064 |
05 Aug 21 |
peter |
589 |
while (true) { |
4072 |
20 Aug 21 |
peter |
590 |
ranking::NodeBase* parent = x; |
4071 |
18 Aug 21 |
peter |
591 |
if (compare_(element->value(), value(x))) { |
4064 |
05 Aug 21 |
peter |
592 |
x = x->left_; |
4077 |
26 Aug 21 |
peter |
593 |
if (x == nullptr) |
4077 |
26 Aug 21 |
peter |
594 |
return insert_and_rebalance(std::move(element), *parent, true); |
4064 |
05 Aug 21 |
peter |
595 |
} |
4064 |
05 Aug 21 |
peter |
596 |
else { |
4064 |
05 Aug 21 |
peter |
597 |
x = x->right_; |
4077 |
26 Aug 21 |
peter |
598 |
if (x == nullptr) |
4077 |
26 Aug 21 |
peter |
599 |
return insert_and_rebalance(std::move(element), *parent, false); |
4064 |
05 Aug 21 |
peter |
600 |
} |
4064 |
05 Aug 21 |
peter |
601 |
} |
4074 |
20 Aug 21 |
peter |
602 |
YAT_ASSERT(0 && "we can't reach here"); |
4077 |
26 Aug 21 |
peter |
603 |
return iterator(element.get()); |
4037 |
25 Jan 21 |
peter |
604 |
} |
4037 |
25 Jan 21 |
peter |
605 |
|
4037 |
25 Jan 21 |
peter |
606 |
|
4077 |
26 Aug 21 |
peter |
607 |
iterator insert(const_iterator hint, |
4077 |
26 Aug 21 |
peter |
608 |
std::unique_ptr<ranking::NodeValue<T>>&& element) |
4077 |
26 Aug 21 |
peter |
609 |
{ |
4077 |
26 Aug 21 |
peter |
// special case when hint == end() |
4077 |
26 Aug 21 |
peter |
611 |
if (hint.node_ == head_node()) { |
4077 |
26 Aug 21 |
peter |
612 |
YAT_ASSERT(hint == cend()); |
4077 |
26 Aug 21 |
peter |
613 |
if (empty() || compare_(element->value(), value(impl_.right_most()))) |
4077 |
26 Aug 21 |
peter |
614 |
return insert(std::move(element)); |
4077 |
26 Aug 21 |
peter |
615 |
return insert_and_rebalance(std::move(element), *impl_.right_most(), |
4077 |
26 Aug 21 |
peter |
616 |
false); |
4077 |
26 Aug 21 |
peter |
617 |
} |
4077 |
26 Aug 21 |
peter |
618 |
|
4077 |
26 Aug 21 |
peter |
619 |
YAT_ASSERT(hint != end()); |
4077 |
26 Aug 21 |
peter |
620 |
|
4077 |
26 Aug 21 |
peter |
// value <= hint i.e. !(hint<value) |
4077 |
26 Aug 21 |
peter |
622 |
if (!compare_(*hint, element->value())) { |
4077 |
26 Aug 21 |
peter |
// if hint == begin |
4077 |
26 Aug 21 |
peter |
624 |
if (hint.node_ == impl_.left_most()) { |
4077 |
26 Aug 21 |
peter |
625 |
YAT_ASSERT(hint == cbegin()); |
4077 |
26 Aug 21 |
peter |
626 |
return insert_and_rebalance(std::move(element), |
4077 |
26 Aug 21 |
peter |
627 |
*impl_.left_most(), |
4077 |
26 Aug 21 |
peter |
628 |
true); |
4077 |
26 Aug 21 |
peter |
629 |
} |
4077 |
26 Aug 21 |
peter |
630 |
|
4077 |
26 Aug 21 |
peter |
// prev <= value <= hint insert |
4077 |
26 Aug 21 |
peter |
632 |
YAT_ASSERT(hint != cbegin()); |
4077 |
26 Aug 21 |
peter |
633 |
auto before = std::prev(hint); |
4077 |
26 Aug 21 |
peter |
634 |
if (!compare_(element->value(), *before)) { |
4077 |
26 Aug 21 |
peter |
635 |
return insert(const_cast<ranking::NodeBase*>(hint.node_), |
4077 |
26 Aug 21 |
peter |
636 |
std::move(element)); |
4077 |
26 Aug 21 |
peter |
637 |
} |
4077 |
26 Aug 21 |
peter |
638 |
else { |
4077 |
26 Aug 21 |
peter |
639 |
return insert(std::move(element)); |
4077 |
26 Aug 21 |
peter |
640 |
} |
4077 |
26 Aug 21 |
peter |
641 |
} |
4077 |
26 Aug 21 |
peter |
// else value > hint |
4077 |
26 Aug 21 |
peter |
643 |
else { |
4077 |
26 Aug 21 |
peter |
644 |
YAT_ASSERT(compare_(*hint, element->value())); |
4077 |
26 Aug 21 |
peter |
// hint == rightmost |
4077 |
26 Aug 21 |
peter |
646 |
if (hint.node_ == impl_.right_most()) { |
4077 |
26 Aug 21 |
peter |
647 |
return insert_and_rebalance(std::move(element), |
4077 |
26 Aug 21 |
peter |
648 |
*impl_.right_most(), |
4077 |
26 Aug 21 |
peter |
649 |
false); |
4077 |
26 Aug 21 |
peter |
650 |
} |
4077 |
26 Aug 21 |
peter |
651 |
auto after = std::next(hint); |
4077 |
26 Aug 21 |
peter |
652 |
YAT_ASSERT(after != cend()); |
4077 |
26 Aug 21 |
peter |
// hint < value <= after |
4077 |
26 Aug 21 |
peter |
654 |
if (!compare_(*after, element->value())) { |
4077 |
26 Aug 21 |
peter |
655 |
return insert(const_cast<ranking::NodeBase*>(after.node_), |
4077 |
26 Aug 21 |
peter |
656 |
std::move(element)); |
4077 |
26 Aug 21 |
peter |
657 |
} |
4077 |
26 Aug 21 |
peter |
658 |
} |
4077 |
26 Aug 21 |
peter |
659 |
|
4077 |
26 Aug 21 |
peter |
660 |
return insert(std::move(element)); |
4077 |
26 Aug 21 |
peter |
661 |
} |
4077 |
26 Aug 21 |
peter |
662 |
|
4077 |
26 Aug 21 |
peter |
663 |
|
4072 |
20 Aug 21 |
peter |
664 |
/* |
4072 |
20 Aug 21 |
peter |
Find the first node that is greater or equal to key, i.e., all |
4072 |
20 Aug 21 |
peter |
elements left of returned node are less than key. |
4072 |
20 Aug 21 |
peter |
667 |
*/ |
4037 |
25 Jan 21 |
peter |
668 |
const_iterator |
4037 |
25 Jan 21 |
peter |
669 |
lower_bound(const ranking::NodeValue<T>* x, const ranking::NodeBase* y, |
4037 |
25 Jan 21 |
peter |
670 |
const T& key) const |
4037 |
25 Jan 21 |
peter |
671 |
{ |
4072 |
20 Aug 21 |
peter |
// x is used to traverse the tree |
4072 |
20 Aug 21 |
peter |
// y holds the result |
4064 |
05 Aug 21 |
peter |
674 |
|
4037 |
25 Jan 21 |
peter |
675 |
while (x) { |
4072 |
20 Aug 21 |
peter |
// key is less (or equal) than x, store x as potential result |
4072 |
20 Aug 21 |
peter |
// and search in left branch |
4037 |
25 Jan 21 |
peter |
678 |
if (!compare_(x->value(), key)) { |
4037 |
25 Jan 21 |
peter |
679 |
y = x; |
4037 |
25 Jan 21 |
peter |
680 |
x = left(x); |
4037 |
25 Jan 21 |
peter |
681 |
} |
4072 |
20 Aug 21 |
peter |
// key is greater than x, the lower bound is not x; it is |
4072 |
20 Aug 21 |
peter |
// either in the right branch or a previously assigned |
4072 |
20 Aug 21 |
peter |
// ancestor. Do not store x as potential result, but search |
4072 |
20 Aug 21 |
peter |
// branch. |
4072 |
20 Aug 21 |
peter |
686 |
else |
4037 |
25 Jan 21 |
peter |
687 |
x = right(x); |
4037 |
25 Jan 21 |
peter |
688 |
} |
4072 |
20 Aug 21 |
peter |
// x has reached a leaf, and the result should be stored in y |
4072 |
20 Aug 21 |
peter |
690 |
|
4072 |
20 Aug 21 |
peter |
// returned node is not smaller than key |
4072 |
20 Aug 21 |
peter |
692 |
YAT_ASSERT(y==head_node() || !compare_(value(y), key)); |
4072 |
20 Aug 21 |
peter |
// all nodes left of returned node are smaller than key |
4072 |
20 Aug 21 |
peter |
694 |
YAT_ASSERT(y->left_==nullptr || |
4072 |
20 Aug 21 |
peter |
695 |
compare_(value(y->left_->right_most()), key)); |
4037 |
25 Jan 21 |
peter |
696 |
return const_iterator(y); |
4037 |
25 Jan 21 |
peter |
697 |
} |
4037 |
25 Jan 21 |
peter |
698 |
|
4037 |
25 Jan 21 |
peter |
699 |
|
4069 |
06 Aug 21 |
peter |
700 |
const ranking::NodeValue<T>* parent(const ranking::NodeBase* x) const |
4069 |
06 Aug 21 |
peter |
701 |
{ |
4069 |
06 Aug 21 |
peter |
702 |
YAT_ASSERT(x); |
4069 |
06 Aug 21 |
peter |
703 |
YAT_ASSERT(x->parent_); |
4069 |
06 Aug 21 |
peter |
704 |
YAT_ASSERT(x->parent_ != &impl_.head_); |
4069 |
06 Aug 21 |
peter |
705 |
return static_cast<const ranking::NodeValue<T>*>(x->parent_); |
4069 |
06 Aug 21 |
peter |
706 |
} |
4069 |
06 Aug 21 |
peter |
707 |
|
4069 |
06 Aug 21 |
peter |
708 |
|
4069 |
06 Aug 21 |
peter |
709 |
ranking::NodeValue<T>* parent(ranking::NodeBase* x) const |
4069 |
06 Aug 21 |
peter |
710 |
{ |
4069 |
06 Aug 21 |
peter |
711 |
YAT_ASSERT(x); |
4069 |
06 Aug 21 |
peter |
712 |
YAT_ASSERT(x->parent_); |
4069 |
06 Aug 21 |
peter |
713 |
YAT_ASSERT(x->parent_ != &impl_.head_); |
4069 |
06 Aug 21 |
peter |
714 |
return static_cast<ranking::NodeValue<T>*>(x->parent_); |
4069 |
06 Aug 21 |
peter |
715 |
} |
4069 |
06 Aug 21 |
peter |
716 |
|
4069 |
06 Aug 21 |
peter |
717 |
|
4037 |
25 Jan 21 |
peter |
718 |
/* |
4072 |
20 Aug 21 |
peter |
Find the first node that is greater than key, i.e., all |
4072 |
20 Aug 21 |
peter |
elements left of returned node are less or equal to key. |
4072 |
20 Aug 21 |
peter |
721 |
*/ |
4037 |
25 Jan 21 |
peter |
722 |
const_iterator |
4037 |
25 Jan 21 |
peter |
723 |
upper_bound(const ranking::NodeValue<T>* x, const ranking::NodeBase* y, |
4037 |
25 Jan 21 |
peter |
724 |
const T& key) const |
4037 |
25 Jan 21 |
peter |
725 |
{ |
4072 |
20 Aug 21 |
peter |
// x is used to traverse the tree |
4072 |
20 Aug 21 |
peter |
// y holds the result |
4064 |
05 Aug 21 |
peter |
728 |
|
4037 |
25 Jan 21 |
peter |
729 |
while (x) { |
4072 |
20 Aug 21 |
peter |
// key is less than x value, x is a potential upper_bound, |
4072 |
20 Aug 21 |
peter |
// store and search in left |
4037 |
25 Jan 21 |
peter |
732 |
if (compare_(key, x->value())) { |
4037 |
25 Jan 21 |
peter |
733 |
y = x; |
4037 |
25 Jan 21 |
peter |
734 |
x = left(x); |
4037 |
25 Jan 21 |
peter |
735 |
} |
4064 |
05 Aug 21 |
peter |
736 |
else { |
4072 |
20 Aug 21 |
peter |
// key is greater (or equal) than x, x is not the upper |
4072 |
20 Aug 21 |
peter |
// bound. It is either in the right branch or in a |
4072 |
20 Aug 21 |
peter |
// previously assigned ancestor (current y). |
4037 |
25 Jan 21 |
peter |
740 |
x = right(x); |
4064 |
05 Aug 21 |
peter |
741 |
} |
4037 |
25 Jan 21 |
peter |
742 |
} |
4072 |
20 Aug 21 |
peter |
// x has reached a leaf, and the result should be stored in y |
4072 |
20 Aug 21 |
peter |
744 |
|
4072 |
20 Aug 21 |
peter |
// key is less than returned node |
4072 |
20 Aug 21 |
peter |
746 |
YAT_ASSERT(y==head_node() || compare_(key, value(y))); |
4072 |
20 Aug 21 |
peter |
// all nodes left of returned node are smaller (or equal) than |
4072 |
20 Aug 21 |
peter |
// key, i.e., key is not smaller than any of the nodes to the |
4072 |
20 Aug 21 |
peter |
// left of returned node. |
4072 |
20 Aug 21 |
peter |
750 |
YAT_ASSERT(y->left_==nullptr || |
4072 |
20 Aug 21 |
peter |
751 |
!compare_(key, value(y->left_->right_most()))); |
4037 |
25 Jan 21 |
peter |
752 |
return const_iterator(y); |
4037 |
25 Jan 21 |
peter |
753 |
} |
4037 |
25 Jan 21 |
peter |
754 |
|
4037 |
25 Jan 21 |
peter |
755 |
|
4071 |
18 Aug 21 |
peter |
756 |
const T& value(const ranking::NodeBase* p) const |
4071 |
18 Aug 21 |
peter |
757 |
{ |
4071 |
18 Aug 21 |
peter |
758 |
YAT_ASSERT(p); |
4071 |
18 Aug 21 |
peter |
759 |
YAT_ASSERT(!p->is_head_node()); |
4071 |
18 Aug 21 |
peter |
760 |
return static_cast<const ranking::NodeValue<T>*>(p)->value(); |
4071 |
18 Aug 21 |
peter |
761 |
} |
4071 |
18 Aug 21 |
peter |
762 |
|
4071 |
18 Aug 21 |
peter |
763 |
|
4064 |
05 Aug 21 |
peter |
764 |
bool validate(void) const |
4037 |
25 Jan 21 |
peter |
765 |
{ |
4072 |
20 Aug 21 |
peter |
766 |
#ifndef YAT_DEBUG_RANKING |
4072 |
20 Aug 21 |
peter |
767 |
return true; |
4072 |
20 Aug 21 |
peter |
768 |
#else |
4072 |
20 Aug 21 |
peter |
769 |
if (!impl_.validate()) { |
4072 |
20 Aug 21 |
peter |
770 |
std::cerr << "Impl::validate failed\n"; |
4071 |
18 Aug 21 |
peter |
771 |
return false; |
4072 |
20 Aug 21 |
peter |
772 |
} |
4072 |
20 Aug 21 |
peter |
773 |
|
4071 |
18 Aug 21 |
peter |
774 |
bool ok = true; |
4071 |
18 Aug 21 |
peter |
775 |
size_t rank = 0; |
4072 |
20 Aug 21 |
peter |
776 |
YAT_ASSERT(cbegin().node_); |
4072 |
20 Aug 21 |
peter |
777 |
YAT_ASSERT(cend().node_); |
4071 |
18 Aug 21 |
peter |
778 |
for (auto it = cbegin(); it!=cend(); ++it) { |
4071 |
18 Aug 21 |
peter |
779 |
size_t r = ranking(it); |
4071 |
18 Aug 21 |
peter |
780 |
if (r != rank) { |
4071 |
18 Aug 21 |
peter |
781 |
std::cerr << "ranking: " << r << "; expected: " << rank << "\n"; |
4071 |
18 Aug 21 |
peter |
782 |
std::cerr << "size: " << it.node_->size_ << "\n"; |
4071 |
18 Aug 21 |
peter |
783 |
std::cerr << it.node_->parent_ << " " |
4071 |
18 Aug 21 |
peter |
784 |
<< it.node_->is_left_node() << " " |
4071 |
18 Aug 21 |
peter |
785 |
<< it.node_->is_right_node() << "\n---\n"; |
4071 |
18 Aug 21 |
peter |
786 |
ok = false; |
4071 |
18 Aug 21 |
peter |
787 |
} |
4071 |
18 Aug 21 |
peter |
788 |
++rank; |
4071 |
18 Aug 21 |
peter |
789 |
} |
4071 |
18 Aug 21 |
peter |
790 |
return ok; |
4064 |
05 Aug 21 |
peter |
791 |
#endif |
4069 |
06 Aug 21 |
peter |
792 |
} |
4069 |
06 Aug 21 |
peter |
793 |
}; |
4037 |
25 Jan 21 |
peter |
794 |
|
4070 |
09 Aug 21 |
peter |
// avoid doxygen reading code below as it has problems to to match |
4070 |
09 Aug 21 |
peter |
// declarations and implementations unless matching perfectly. |
4069 |
06 Aug 21 |
peter |
797 |
|
4070 |
09 Aug 21 |
peter |
/// \cond IGNORE_DOXYGEN |
4070 |
09 Aug 21 |
peter |
799 |
|
4069 |
06 Aug 21 |
peter |
// implementations |
4070 |
09 Aug 21 |
peter |
801 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
802 |
Ranking<T,C>::Ranking(const Ranking& other) |
4069 |
06 Aug 21 |
peter |
803 |
: compare_(other.compare()) |
4069 |
06 Aug 21 |
peter |
804 |
{ |
4069 |
06 Aug 21 |
peter |
805 |
if (!other.empty()) |
4072 |
20 Aug 21 |
peter |
806 |
impl_.root_node() = copy(other); |
4069 |
06 Aug 21 |
peter |
807 |
YAT_ASSERT(validate()); |
4069 |
06 Aug 21 |
peter |
808 |
} |
4069 |
06 Aug 21 |
peter |
809 |
|
4069 |
06 Aug 21 |
peter |
810 |
|
4070 |
09 Aug 21 |
peter |
811 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
812 |
Ranking<T,C>::Ranking(Ranking&& other) |
4069 |
06 Aug 21 |
peter |
813 |
: compare_(std::move(other.compare())), impl_(std::move(other.impl_)) |
4069 |
06 Aug 21 |
peter |
814 |
{ |
4069 |
06 Aug 21 |
peter |
815 |
YAT_ASSERT(validate()); |
4069 |
06 Aug 21 |
peter |
816 |
} |
4069 |
06 Aug 21 |
peter |
817 |
|
4069 |
06 Aug 21 |
peter |
818 |
|
4070 |
09 Aug 21 |
peter |
819 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
820 |
Ranking<T, C>& Ranking<T, C>::operator=(const Ranking& other) |
4069 |
06 Aug 21 |
peter |
821 |
{ |
4069 |
06 Aug 21 |
peter |
822 |
if (this != &other) { |
4069 |
06 Aug 21 |
peter |
823 |
Ranking tmp(other); |
4069 |
06 Aug 21 |
peter |
824 |
*this = std::move(tmp); |
4037 |
25 Jan 21 |
peter |
825 |
} |
4069 |
06 Aug 21 |
peter |
826 |
return *this; |
4069 |
06 Aug 21 |
peter |
827 |
} |
4037 |
25 Jan 21 |
peter |
828 |
|
4037 |
25 Jan 21 |
peter |
829 |
|
4070 |
09 Aug 21 |
peter |
830 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
831 |
Ranking<T, C>& Ranking<T, C>::operator=(Ranking&& other) |
4069 |
06 Aug 21 |
peter |
832 |
{ |
4069 |
06 Aug 21 |
peter |
833 |
clear(); |
4069 |
06 Aug 21 |
peter |
834 |
compare_ = std::move(other.compare_); |
4069 |
06 Aug 21 |
peter |
835 |
impl_ = std::move(other.impl_); |
4069 |
06 Aug 21 |
peter |
836 |
return *this; |
4069 |
06 Aug 21 |
peter |
837 |
} |
4069 |
06 Aug 21 |
peter |
838 |
|
4069 |
06 Aug 21 |
peter |
839 |
|
4070 |
09 Aug 21 |
peter |
840 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
841 |
ranking::NodeValue<T>* Ranking<T,C>::copy(const Ranking& other) |
4069 |
06 Aug 21 |
peter |
842 |
{ |
4072 |
20 Aug 21 |
peter |
843 |
YAT_ASSERT(other.root_node()); |
4072 |
20 Aug 21 |
peter |
844 |
ranking::NodeValue<T>* root = copy(other.root_node()); |
4072 |
20 Aug 21 |
peter |
845 |
root->parent_ = head_node(); |
4072 |
20 Aug 21 |
peter |
846 |
head_node()->left_ = root; |
4072 |
20 Aug 21 |
peter |
847 |
head_node()->right_ = root->left_most(); |
4072 |
20 Aug 21 |
peter |
848 |
head_node()->update_height(); |
4072 |
20 Aug 21 |
peter |
849 |
head_node()->update_size(); |
4079 |
26 Aug 21 |
peter |
850 |
if (root_node()) |
4079 |
26 Aug 21 |
peter |
851 |
impl_.right_most() = root_node()->right_most(); |
4079 |
26 Aug 21 |
peter |
852 |
else |
4079 |
26 Aug 21 |
peter |
853 |
impl_.right_most() = head_node(); |
4069 |
06 Aug 21 |
peter |
854 |
YAT_ASSERT(validate()); |
4069 |
06 Aug 21 |
peter |
855 |
return root; |
4069 |
06 Aug 21 |
peter |
856 |
} |
4069 |
06 Aug 21 |
peter |
857 |
|
4069 |
06 Aug 21 |
peter |
858 |
|
4070 |
09 Aug 21 |
peter |
859 |
template<typename T, typename C> |
4072 |
20 Aug 21 |
peter |
860 |
ranking::NodeValue<T>* |
4072 |
20 Aug 21 |
peter |
861 |
Ranking<T,C>::copy(const ranking::NodeValue<T>* x) const |
4069 |
06 Aug 21 |
peter |
862 |
{ |
4069 |
06 Aug 21 |
peter |
863 |
YAT_ASSERT(x); |
4069 |
06 Aug 21 |
peter |
864 |
ranking::NodeValue<T>* root = clone_node(x); |
4072 |
20 Aug 21 |
peter |
865 |
YAT_ASSERT(root); |
4071 |
18 Aug 21 |
peter |
866 |
root->height_ = x->height_; |
4071 |
18 Aug 21 |
peter |
867 |
root->size_ = x->size_; |
4072 |
20 Aug 21 |
peter |
868 |
|
4069 |
06 Aug 21 |
peter |
869 |
try { |
4072 |
20 Aug 21 |
peter |
870 |
if (x->left_) { |
4072 |
20 Aug 21 |
peter |
871 |
root->left_ = copy(left(x)); |
4072 |
20 Aug 21 |
peter |
872 |
root->left_->parent_ = root; |
4069 |
06 Aug 21 |
peter |
873 |
} |
4072 |
20 Aug 21 |
peter |
874 |
if (x->right_) { |
4072 |
20 Aug 21 |
peter |
875 |
root->right_ = copy(right(x)); |
4072 |
20 Aug 21 |
peter |
876 |
root->right_->parent_ = root; |
4069 |
06 Aug 21 |
peter |
877 |
} |
4069 |
06 Aug 21 |
peter |
878 |
} |
4069 |
06 Aug 21 |
peter |
879 |
catch (std::exception& e) { |
4069 |
06 Aug 21 |
peter |
880 |
erase(root); |
4069 |
06 Aug 21 |
peter |
881 |
std::rethrow_exception(std::current_exception()); |
4069 |
06 Aug 21 |
peter |
882 |
} |
4069 |
06 Aug 21 |
peter |
883 |
return root; |
4069 |
06 Aug 21 |
peter |
884 |
} |
4069 |
06 Aug 21 |
peter |
885 |
|
4069 |
06 Aug 21 |
peter |
886 |
|
4070 |
09 Aug 21 |
peter |
887 |
template<typename T, typename C> |
4069 |
06 Aug 21 |
peter |
888 |
ranking::NodeValue<T>* |
4070 |
09 Aug 21 |
peter |
889 |
Ranking<T,C>::clone_node(const ranking::NodeValue<T>* x) const |
4069 |
06 Aug 21 |
peter |
890 |
{ |
4069 |
06 Aug 21 |
peter |
891 |
YAT_ASSERT(x); |
4069 |
06 Aug 21 |
peter |
892 |
ranking::NodeValue<T>* res = new ranking::NodeValue<T>(x->value()); |
4069 |
06 Aug 21 |
peter |
893 |
res->left_ = nullptr; |
4069 |
06 Aug 21 |
peter |
894 |
res->right_ = nullptr; |
4069 |
06 Aug 21 |
peter |
895 |
res->parent_ = nullptr; |
4069 |
06 Aug 21 |
peter |
896 |
return res; |
4069 |
06 Aug 21 |
peter |
897 |
} |
4069 |
06 Aug 21 |
peter |
898 |
|
4070 |
09 Aug 21 |
peter |
899 |
|
4070 |
09 Aug 21 |
peter |
900 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
901 |
void Ranking<T, C>::erase_node(typename Ranking<T, C>::const_iterator p) |
4070 |
09 Aug 21 |
peter |
902 |
{ |
4070 |
09 Aug 21 |
peter |
903 |
YAT_ASSERT(p != end()); |
4070 |
09 Aug 21 |
peter |
904 |
const ranking::NodeBase* node = p.node_; |
4070 |
09 Aug 21 |
peter |
905 |
YAT_ASSERT(node); |
4070 |
09 Aug 21 |
peter |
906 |
|
4072 |
20 Aug 21 |
peter |
907 |
impl_.erase_and_rebalance(node); |
4073 |
20 Aug 21 |
peter |
908 |
delete node; |
4072 |
20 Aug 21 |
peter |
909 |
YAT_ASSERT(validate()); |
4072 |
20 Aug 21 |
peter |
910 |
return; |
4070 |
09 Aug 21 |
peter |
911 |
} |
4070 |
09 Aug 21 |
peter |
912 |
|
4070 |
09 Aug 21 |
peter |
913 |
|
4070 |
09 Aug 21 |
peter |
914 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
915 |
typename Ranking<T, C>::iterator |
4070 |
09 Aug 21 |
peter |
916 |
Ranking<T, C>::erase(typename Ranking<T, C>::const_iterator p) |
4070 |
09 Aug 21 |
peter |
917 |
{ |
4070 |
09 Aug 21 |
peter |
918 |
YAT_ASSERT(p != end()); |
4070 |
09 Aug 21 |
peter |
919 |
const_iterator res = p; |
4070 |
09 Aug 21 |
peter |
920 |
++res; |
4070 |
09 Aug 21 |
peter |
921 |
erase_node(p); |
4070 |
09 Aug 21 |
peter |
// iterator and const_iterator are same at the moment |
4070 |
09 Aug 21 |
peter |
923 |
return res; |
4070 |
09 Aug 21 |
peter |
924 |
} |
4070 |
09 Aug 21 |
peter |
925 |
|
4070 |
09 Aug 21 |
peter |
926 |
|
4070 |
09 Aug 21 |
peter |
927 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
928 |
typename Ranking<T, C>::size_type Ranking<T, C>::erase(const T& value) |
4070 |
09 Aug 21 |
peter |
929 |
{ |
4070 |
09 Aug 21 |
peter |
930 |
auto it = lower_bound(value); |
4070 |
09 Aug 21 |
peter |
931 |
typename Ranking<T, C>::size_type n = 0; |
4070 |
09 Aug 21 |
peter |
932 |
while (it!=end() && !compare_(value, *it)) { |
4070 |
09 Aug 21 |
peter |
933 |
erase_node(it++); |
4070 |
09 Aug 21 |
peter |
934 |
++n; |
4070 |
09 Aug 21 |
peter |
935 |
} |
4070 |
09 Aug 21 |
peter |
936 |
return n; |
4070 |
09 Aug 21 |
peter |
937 |
} |
4070 |
09 Aug 21 |
peter |
938 |
|
4070 |
09 Aug 21 |
peter |
939 |
|
4070 |
09 Aug 21 |
peter |
940 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
941 |
typename Ranking<T, C>::iterator |
4070 |
09 Aug 21 |
peter |
942 |
Ranking<T, C>::erase(typename Ranking<T, C>::const_iterator first, |
4070 |
09 Aug 21 |
peter |
943 |
typename Ranking<T, C>::const_iterator last) |
4070 |
09 Aug 21 |
peter |
944 |
{ |
4070 |
09 Aug 21 |
peter |
945 |
if (first == cbegin() && last == cend()) |
4070 |
09 Aug 21 |
peter |
946 |
clear(); |
4070 |
09 Aug 21 |
peter |
947 |
else |
4070 |
09 Aug 21 |
peter |
948 |
while (first != last) { |
4070 |
09 Aug 21 |
peter |
949 |
erase_node(first++); |
4070 |
09 Aug 21 |
peter |
950 |
} |
4070 |
09 Aug 21 |
peter |
951 |
return last; |
4070 |
09 Aug 21 |
peter |
952 |
} |
4070 |
09 Aug 21 |
peter |
953 |
|
4070 |
09 Aug 21 |
peter |
954 |
|
4070 |
09 Aug 21 |
peter |
955 |
template<typename T, typename C> |
4070 |
09 Aug 21 |
peter |
956 |
typename Ranking<T, C>::const_iterator Ranking<T, C>::find(const T& x) const |
4070 |
09 Aug 21 |
peter |
957 |
{ |
4070 |
09 Aug 21 |
peter |
958 |
auto it = lower_bound(x); |
4070 |
09 Aug 21 |
peter |
959 |
if (it != cend() && compare_(x, *it)) |
4070 |
09 Aug 21 |
peter |
960 |
it = cend(); |
4070 |
09 Aug 21 |
peter |
961 |
return it; |
4070 |
09 Aug 21 |
peter |
962 |
} |
4070 |
09 Aug 21 |
peter |
963 |
|
4070 |
09 Aug 21 |
peter |
/// \endcond |
4070 |
09 Aug 21 |
peter |
965 |
|
4037 |
25 Jan 21 |
peter |
966 |
}}} // of namespace utility, yat, and theplu |
4037 |
25 Jan 21 |
peter |
967 |
#endif |