forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathordered_vector.h
More file actions
309 lines (266 loc) · 11.8 KB
/
ordered_vector.h
File metadata and controls
309 lines (266 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file ordered_vector.h
* @author drose
* @date 2002-02-20
*/
#ifndef ORDERED_VECTOR_H
#define ORDERED_VECTOR_H
#ifdef CPPPARSER // hack around this for interigate...
// ****** HACK allert *** this code is intended to tell interigate to not
// expand this class definition past basic names It drops the interigate
// memory foot pront and user time by a bunch on pc cygwin from 3 minutes to
// 17 seconds ?? really need to explore interigate to figure out what is going
// on ..
template<class Key, class Compare = std::less<int>, class Vector = pvector<Key> > class ov_multiset
{
};
template<class Key, class Compare = std::less<int>, class Vector = pvector<Key> > class ov_set
{
};
template<class Key, class Compare = std::less<int>, class Vector = pvector<Key> > class ordered_vector
{
};
#else // cppparser
#include "pandabase.h"
#include "pvector.h"
#include "pset.h"
#include "pnotify.h"
#include <algorithm>
// There are some inheritance issues with template classes and typedef names.
// Template classes that inherit typedef names from their base class, which is
// also a template class, may confuse the typedef names with globally scoped
// template names. In particular, the local "iterator" type is easily
// confused with the std::iterator template class.
// To work around this problem, as well as a problem in gcc 2.95.3 with
// value_type etc. not inheriting properly (even though we explicitly typedef
// them in the derived class), we rename the questionable typedefs here so
// that they no longer conflict with the global template classes.
#define KEY_TYPE key_type_0
#define VALUE_TYPE value_type_0
#define REFERENCE reference_0
#define CONST_REFERENCE const_reference_0
#define KEY_COMPARE key_compare_0
#define VALUE_COMPARE value_compare_0
#define ITERATOR iterator_0
#define CONST_ITERATOR const_iterator_0
#define REVERSE_ITERATOR reverse_iterator_0
#define CONST_REVERSE_ITERATOR const_reverse_iterator_0
#define DIFFERENCE_TYPE difference_type_0
#define SIZE_TYPE size_type_0
/**
* This template class presents an interface similar to the STL set or
* multiset (and ov_set and ov_multiset are implemented specifically, below),
* but it is implemented using a vector that is kept always in sorted order.
*
* In most cases, an ov_set or ov_multiset may be dropped in transparently in
* place of a set or multiset, but the implementation difference has a few
* implications:
*
* (1) The ov_multiset will maintain stability of order between elements that
* sort equally: they are stored in the order in which they were added, from
* back to front.
*
* (2) Insert and erase operations into the middle of the set can be slow,
* just as inserting into the middle of a vector can be slow. In fact,
* building up an ov_set by inserting elements one at a time is an n^2
* operation. On the other hand, building up an ov_set by adding elements to
* the end, one at time, is somewhat faster than building up a traditional
* set; and you can even add unsorted elements with push_back() and then call
* sort() when you're done, for a log(n) operation.
*
* (3) Iterators may not be valid for the life of the ordered_vector. If the
* vector reallocates itself, all iterators are invalidated.
*
* (4) Random access into the set is easy with the [] operator.
*/
template<class Key, class Compare = std::less<Key>, class Vector = pvector<Key> >
class ordered_vector {
public:
// Typedefs
typedef Key KEY_TYPE;
typedef Key VALUE_TYPE;
typedef Key &REFERENCE;
typedef const Key &CONST_REFERENCE;
typedef Compare KEY_COMPARE;
typedef Compare VALUE_COMPARE;
// Be careful when using the non-const iterators that you do not disturb the
// sorted order of the vector, or that if you do, you call sort() when you
// are done.
typedef typename Vector::iterator ITERATOR;
typedef typename Vector::const_iterator CONST_ITERATOR;
typedef typename Vector::reverse_iterator REVERSE_ITERATOR;
typedef typename Vector::const_reverse_iterator CONST_REVERSE_ITERATOR;
typedef typename Vector::difference_type DIFFERENCE_TYPE;
typedef typename Vector::size_type SIZE_TYPE;
// Since the #define symbols do not actually expand to the correct names, we
// have to re-typedef them so callers can reference them by their correct,
// lowercase names.
typedef KEY_TYPE key_type;
typedef VALUE_TYPE value_type;
typedef REFERENCE reference;
typedef CONST_REFERENCE const_reference;
typedef KEY_COMPARE key_compare;
typedef VALUE_COMPARE value_compare;
typedef ITERATOR iterator;
typedef CONST_ITERATOR const_iterator;
typedef REVERSE_ITERATOR reverse_iterator;
typedef CONST_REVERSE_ITERATOR const_reverse_iterator;
typedef DIFFERENCE_TYPE difference_type;
typedef SIZE_TYPE size_type;
public:
// Constructors. We don't implement the whole slew of STL constructors here
// yet.
INLINE ordered_vector(TypeHandle type_handle = ov_set_type_handle);
INLINE ordered_vector(const Compare &compare,
TypeHandle type_handle = ov_set_type_handle);
// Iterator access.
INLINE ITERATOR begin();
INLINE ITERATOR end();
INLINE REVERSE_ITERATOR rbegin();
INLINE REVERSE_ITERATOR rend();
INLINE CONST_ITERATOR begin() const;
INLINE CONST_ITERATOR end() const;
INLINE CONST_REVERSE_ITERATOR rbegin() const;
INLINE CONST_REVERSE_ITERATOR rend() const;
INLINE CONST_ITERATOR cbegin() const;
INLINE CONST_ITERATOR cend() const;
INLINE CONST_REVERSE_ITERATOR crbegin() const;
INLINE CONST_REVERSE_ITERATOR crend() const;
// Random access.
INLINE reference operator [] (SIZE_TYPE n);
INLINE const_reference operator [] (SIZE_TYPE n) const;
INLINE reference front();
INLINE const_reference front() const;
INLINE reference back();
INLINE const_reference back() const;
// Size information.
INLINE SIZE_TYPE size() const;
INLINE SIZE_TYPE max_size() const;
INLINE bool empty() const;
// Equivalence and lexicographical comparisons.
INLINE bool operator == (const ordered_vector<Key, Compare, Vector> &other) const;
INLINE bool operator != (const ordered_vector<Key, Compare, Vector> &other) const;
INLINE bool operator < (const ordered_vector<Key, Compare, Vector> &other) const;
INLINE bool operator > (const ordered_vector<Key, Compare, Vector> &other) const;
INLINE bool operator <= (const ordered_vector<Key, Compare, Vector> &other) const;
INLINE bool operator >= (const ordered_vector<Key, Compare, Vector> &other) const;
// Insert operations.
ITERATOR insert_unique(ITERATOR position, const VALUE_TYPE &key);
ITERATOR insert_nonunique(ITERATOR position, const VALUE_TYPE &key);
INLINE std::pair<ITERATOR, bool> insert_unique(const VALUE_TYPE &key);
INLINE ITERATOR insert_nonunique(const VALUE_TYPE &key);
INLINE ITERATOR insert_unverified(ITERATOR position, const VALUE_TYPE &key);
// Erase operations.
INLINE ITERATOR erase(ITERATOR position);
INLINE SIZE_TYPE erase(const KEY_TYPE &key);
INLINE void erase(ITERATOR first, ITERATOR last);
INLINE void clear();
// Find operations.
INLINE ITERATOR find(const KEY_TYPE &key);
INLINE CONST_ITERATOR find(const KEY_TYPE &key) const;
INLINE ITERATOR find_particular(const KEY_TYPE &key);
INLINE CONST_ITERATOR find_particular(const KEY_TYPE &key) const;
INLINE SIZE_TYPE count(const KEY_TYPE &key) const;
INLINE ITERATOR lower_bound(const KEY_TYPE &key);
INLINE CONST_ITERATOR lower_bound(const KEY_TYPE &key) const;
INLINE ITERATOR upper_bound(const KEY_TYPE &key);
INLINE CONST_ITERATOR upper_bound(const KEY_TYPE &key) const;
INLINE std::pair<ITERATOR, ITERATOR> equal_range(const KEY_TYPE &key);
INLINE std::pair<CONST_ITERATOR, CONST_ITERATOR> equal_range(const KEY_TYPE &key) const;
// Special operations.
INLINE void swap(ordered_vector<Key, Compare, Vector> &other);
INLINE void reserve(SIZE_TYPE n);
INLINE void sort_unique();
INLINE void sort_nonunique();
bool verify_list_unique() const;
bool verify_list_nonunique() const;
INLINE void push_back(const VALUE_TYPE &key);
INLINE void push_back(VALUE_TYPE &&key);
INLINE void pop_back();
INLINE void resize(SIZE_TYPE n);
INLINE void resize(SIZE_TYPE n, const VALUE_TYPE &value);
private:
INLINE ITERATOR nci(CONST_ITERATOR i);
INLINE ITERATOR find_insert_position(ITERATOR first, ITERATOR last,
const KEY_TYPE &key);
ITERATOR r_find_insert_position(ITERATOR first, ITERATOR last,
const KEY_TYPE &key);
CONST_ITERATOR r_find(CONST_ITERATOR first, CONST_ITERATOR last,
CONST_ITERATOR not_found,
const KEY_TYPE &key) const;
CONST_ITERATOR r_find_particular(CONST_ITERATOR first, CONST_ITERATOR last,
CONST_ITERATOR not_found,
const KEY_TYPE &key) const;
SIZE_TYPE r_count(CONST_ITERATOR first, CONST_ITERATOR last,
const KEY_TYPE &key) const;
CONST_ITERATOR r_lower_bound(CONST_ITERATOR first, CONST_ITERATOR last,
const KEY_TYPE &key) const;
CONST_ITERATOR r_upper_bound(CONST_ITERATOR first, CONST_ITERATOR last,
const KEY_TYPE &key) const;
std::pair<CONST_ITERATOR, CONST_ITERATOR>
r_equal_range(CONST_ITERATOR first, CONST_ITERATOR last,
const KEY_TYPE &key) const;
// This function object is used in sort_unique(). It returns true if two
// consecutive sorted elements are equivalent.
class EquivalentTest {
public:
// For some reason, VC++ won't allow us to define these bodies outside the
// class; they must be defined here. The error message is C3206: "member
// functions of nested classes of a template class cannot be defined
// outside the class".
INLINE EquivalentTest(const Compare &compare) :
_compare(compare) { }
INLINE bool operator () (const KEY_TYPE &a, const KEY_TYPE &b) {
nassertr(!_compare(b, a), false);
return !_compare(a, b);
}
Compare _compare;
};
Compare _compare;
Vector _vector;
};
/**
* A specialization of ordered_vector that emulates a standard STL set: one
* copy of each element is allowed.
*/
template<class Key, class Compare = std::less<Key>, class Vector = pvector<Key> >
class ov_set : public ordered_vector<Key, Compare, Vector> {
public:
typedef typename ordered_vector<Key, Compare, Vector>::ITERATOR ITERATOR;
typedef typename ordered_vector<Key, Compare, Vector>::VALUE_TYPE VALUE_TYPE;
INLINE ov_set(TypeHandle type_handle = ov_set_type_handle);
INLINE ov_set(const Compare &compare,
TypeHandle type_handle = ov_set_type_handle);
INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
INLINE std::pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
INLINE void sort();
INLINE bool verify_list() const;
};
/**
* A specialization of ordered_vector that emulates a standard STL set: many
* copies of each element are allowed.
*/
template<class Key, class Compare = std::less<Key>, class Vector = pvector<Key> >
class ov_multiset : public ordered_vector<Key, Compare, Vector> {
public:
typedef typename ordered_vector<Key, Compare, Vector>::ITERATOR ITERATOR;
typedef typename ordered_vector<Key, Compare, Vector>::VALUE_TYPE VALUE_TYPE;
INLINE ov_multiset(TypeHandle type_handle = ov_set_type_handle);
INLINE ov_multiset(const Compare &compare,
TypeHandle type_handle = ov_set_type_handle);
INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
INLINE ITERATOR insert(const VALUE_TYPE &key);
INLINE void sort();
INLINE bool verify_list() const;
};
#include "ordered_vector.I"
#include "ordered_vector.T"
#endif // cppparser ..
#endif