37
37
// - an int < 0 when a < b
38
38
// - an int == 0 when a == b
39
39
// - an int > 0 when a > b
40
- // A second static function `cmp(const IntrusiveRBNode* a, const IntrusiveRBNode* b)`
41
- // used for `verify_self` and other extra validation can optionally be provided. This should return:
42
- // - true if a < b
43
- // - false otherwise
40
+ // Additional static functions used for extra validation can optionally be provided:
41
+ // `cmp(K a, K b)` which returns:
42
+ // - an int < 0 when a < b
43
+ // - an int == 0 when a == b
44
+ // - an int > 0 when a > b
45
+ // `cmp(const IntrusiveRBNode* a, const IntrusiveRBNode* b)` which returns:
46
+ // - true if a < b
47
+ // - false otherwise
44
48
// K needs to be of a type that is trivially destructible.
45
49
// K needs to be stored by the user and is not stored inside the tree.
46
50
// Nodes are address stable and will not change during its lifetime.
47
51
48
52
// A red-black tree is constructed with four template parameters:
49
53
// K is the key type stored in the tree nodes.
50
54
// V is the value type stored in the tree nodes.
51
- // COMPARATOR must have one of the static functions `cmp(K a, K b)` or `cmp(K a, const RBNode<K, V>* b)` which returns:
55
+ // COMPARATOR must have a static function `cmp(K a, K b)` which returns:
52
56
// - an int < 0 when a < b
53
57
// - an int == 0 when a == b
54
58
// - an int > 0 when a > b
@@ -198,20 +202,20 @@ class AbstractRBTree {
198
202
struct has_cmp_type <CMP, RET, ARG1, ARG2, decltype (static_cast <RET(*)(ARG1, ARG2)>(CMP::cmp), void ())> : std::true_type {};
199
203
200
204
template <typename CMP>
201
- static constexpr bool IsKeyComparator = has_cmp_type<CMP, int , K, K>::value;
205
+ static constexpr bool HasKeyComparator = has_cmp_type<CMP, int , K, K>::value;
202
206
203
207
template <typename CMP>
204
- static constexpr bool IsNodeComparator = has_cmp_type<CMP, int , K, const NodeType*>::value;
208
+ static constexpr bool HasNodeComparator = has_cmp_type<CMP, int , K, const NodeType*>::value;
205
209
206
210
template <typename CMP>
207
211
static constexpr bool HasNodeVerifier = has_cmp_type<CMP, bool , const NodeType*, const NodeType*>::value;
208
212
209
- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator <CMP>)>
213
+ template <typename CMP = COMPARATOR, ENABLE_IF(HasKeyComparator<CMP> && !HasNodeComparator <CMP>)>
210
214
int cmp (const K& a, const NodeType* b) const {
211
215
return COMPARATOR::cmp (a, b->key ());
212
216
}
213
217
214
- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator <CMP>)>
218
+ template <typename CMP = COMPARATOR, ENABLE_IF(HasNodeComparator <CMP>)>
215
219
int cmp (const K& a, const NodeType* b) const {
216
220
return COMPARATOR::cmp (a, b);
217
221
}
@@ -226,24 +230,13 @@ class AbstractRBTree {
226
230
return COMPARATOR::cmp (a, b);
227
231
}
228
232
229
- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator<CMP>)>
230
- void assert_leq (const K& a, const NodeType* b) const {
231
- assert (COMPARATOR::cmp (a, b->key ()) <= 0 , " key not <= node" );
232
- }
233
-
234
- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator<CMP>)>
235
- void assert_leq (const K& a, const NodeType* b) const {
236
- assert (COMPARATOR::cmp (a, b) <= 0 , " key not <= node" );
237
- }
238
-
239
- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator<CMP>)>
240
- void assert_geq (const K& a, const NodeType* b) const {
241
- assert (COMPARATOR::cmp (a, b->key ()) >= 0 , " key not >= node" );
242
- }
233
+ // Cannot assert if no key comparator exist.
234
+ template <typename CMP = COMPARATOR, ENABLE_IF(!HasKeyComparator<CMP>)>
235
+ void assert_key_leq (K a, K b) const {}
243
236
244
- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator <CMP>)>
245
- void assert_geq ( const K& a, const NodeType* b) const {
246
- assert (COMPARATOR::cmp (a, b) > = 0 , " key not >= node " );
237
+ template <typename CMP = COMPARATOR, ENABLE_IF(HasKeyComparator <CMP>)>
238
+ void assert_key_leq (K a, K b) const {
239
+ assert (COMPARATOR::cmp (a, b) < = 0 , " key a must be less or equal to key b " );
247
240
}
248
241
249
242
// True if node is black (nil nodes count as black)
@@ -272,7 +265,7 @@ class AbstractRBTree {
272
265
273
266
AbstractRBTree () : _num_nodes(0 ), _root(nullptr ) DEBUG_ONLY(COMMA _expected_visited (false )) {
274
267
static_assert (std::is_trivially_destructible<K>::value, " key type must be trivially destructable" );
275
- static_assert (IsKeyComparator <COMPARATOR> || IsNodeComparator <COMPARATOR>,
268
+ static_assert (HasKeyComparator <COMPARATOR> || HasNodeComparator <COMPARATOR>,
276
269
" comparator must be of correct type" );
277
270
}
278
271
@@ -425,12 +418,12 @@ class AbstractRBTree {
425
418
verify_self ([](const NodeType* a, const NodeType* b){ return COMPARATOR::cmp (a, b);});
426
419
}
427
420
428
- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
421
+ template <typename CMP = COMPARATOR, ENABLE_IF(HasKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
429
422
void verify_self () const {
430
423
verify_self ([](const NodeType* a, const NodeType* b){ return COMPARATOR::cmp (a->key (), b->key ()) < 0 ; });
431
424
}
432
425
433
- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator <CMP> && !HasNodeVerifier<CMP>)>
426
+ template <typename CMP = COMPARATOR, ENABLE_IF(HasNodeComparator<CMP> && !HasKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
434
427
void verify_self () const {
435
428
verify_self ([](const NodeType*, const NodeType*){ return true ;});
436
429
}
0 commit comments