3737// - an int < 0 when a < b
3838// - an int == 0 when a == b
3939// - 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
4448// K needs to be of a type that is trivially destructible.
4549// K needs to be stored by the user and is not stored inside the tree.
4650// Nodes are address stable and will not change during its lifetime.
4751
4852// A red-black tree is constructed with four template parameters:
4953// K is the key type stored in the tree nodes.
5054// 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:
5256// - an int < 0 when a < b
5357// - an int == 0 when a == b
5458// - an int > 0 when a > b
@@ -198,20 +202,20 @@ class AbstractRBTree {
198202 struct has_cmp_type <CMP, RET, ARG1, ARG2, decltype (static_cast <RET(*)(ARG1, ARG2)>(CMP::cmp), void ())> : std::true_type {};
199203
200204 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;
202206
203207 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;
205209
206210 template <typename CMP>
207211 static constexpr bool HasNodeVerifier = has_cmp_type<CMP, bool , const NodeType*, const NodeType*>::value;
208212
209- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator <CMP>)>
213+ template <typename CMP = COMPARATOR, ENABLE_IF(HasKeyComparator<CMP> && !HasNodeComparator <CMP>)>
210214 int cmp (const K& a, const NodeType* b) const {
211215 return COMPARATOR::cmp (a, b->key ());
212216 }
213217
214- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator <CMP>)>
218+ template <typename CMP = COMPARATOR, ENABLE_IF(HasNodeComparator <CMP>)>
215219 int cmp (const K& a, const NodeType* b) const {
216220 return COMPARATOR::cmp (a, b);
217221 }
@@ -226,24 +230,13 @@ class AbstractRBTree {
226230 return COMPARATOR::cmp (a, b);
227231 }
228232
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 {}
243236
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 " );
247240 }
248241
249242 // True if node is black (nil nodes count as black)
@@ -272,7 +265,7 @@ class AbstractRBTree {
272265
273266 AbstractRBTree () : _num_nodes(0 ), _root(nullptr ) DEBUG_ONLY(COMMA _expected_visited (false )) {
274267 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>,
276269 " comparator must be of correct type" );
277270 }
278271
@@ -425,12 +418,12 @@ class AbstractRBTree {
425418 verify_self ([](const NodeType* a, const NodeType* b){ return COMPARATOR::cmp (a, b);});
426419 }
427420
428- template <typename CMP = COMPARATOR, ENABLE_IF(IsKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
421+ template <typename CMP = COMPARATOR, ENABLE_IF(HasKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
429422 void verify_self () const {
430423 verify_self ([](const NodeType* a, const NodeType* b){ return COMPARATOR::cmp (a->key (), b->key ()) < 0 ; });
431424 }
432425
433- template <typename CMP = COMPARATOR, ENABLE_IF(IsNodeComparator <CMP> && !HasNodeVerifier<CMP>)>
426+ template <typename CMP = COMPARATOR, ENABLE_IF(HasNodeComparator<CMP> && !HasKeyComparator <CMP> && !HasNodeVerifier<CMP>)>
434427 void verify_self () const {
435428 verify_self ([](const NodeType*, const NodeType*){ return true ;});
436429 }
0 commit comments