Skip to content

Commit a7120bb

Browse files
committed
feat: value_compare must be generic in RedBlack and BST
1 parent 344add7 commit a7120bb

7 files changed

Lines changed: 139 additions & 75 deletions

File tree

include/functional.hpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef FUNCTIONAL_HPP
22
#define FUNCTIONAL_HPP
33

4+
#include <climits>
5+
46
namespace ft
57
{
68

@@ -15,8 +17,40 @@ template <class T> struct greater
1517
{
1618
return first > second;
1719
}
20+
21+
static const int TEST_MIN = INT_MAX;
22+
static const int TEST_MAX = INT_MIN;
23+
};
24+
25+
template <class T> struct less
26+
{
27+
bool operator()(const T& first, const T& second) const
28+
{
29+
return first < second;
30+
}
31+
32+
template <class U> bool operator()(const T& first, const U& second) const
33+
{
34+
return first < second;
35+
}
36+
37+
static const int TEST_MIN = INT_MIN;
38+
static const int TEST_MAX = INT_MAX;
39+
};
40+
41+
template <class c, class T> struct notCompare : public c
42+
{
43+
bool operator()(const T& first, const T& second) const
44+
{
45+
return !c::operator()(first, second);
46+
}
47+
48+
template <class U> bool operator()(const T& first, const U& second) const
49+
{
50+
return !c::operator()(first, second);
51+
}
1852
};
1953

2054
} // namespace ft
2155

22-
#endif
56+
#endif

include/tree/BinarySearchTree.hpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,17 @@
44
#include "__except__.hpp"
55
#include "__macros__.hpp"
66
#include "_phc.hpp"
7+
#include "functional.hpp"
78
#include "iterator.hpp"
89

910
namespace ft
1011
{
1112

12-
struct less
13+
template <class Comp> struct value_compare
1314
{
14-
bool operator()(const int& a, const int& b) const
15-
{
16-
return a < b;
17-
}
18-
};
19-
20-
struct value_compare
21-
{
22-
less c;
15+
Comp c;
2316

24-
value_compare(less c = less()) : c(c)
17+
value_compare(Comp c = Comp()) : c(c)
2518
{
2619
}
2720

@@ -31,7 +24,7 @@ struct value_compare
3124
}
3225
};
3326

34-
class TreeNode
27+
template <class Comp> class TreeNode
3528
{
3629
protected:
3730
int* _val;
@@ -56,31 +49,34 @@ class TreeNode
5649
return !is(val);
5750
}
5851

59-
bool compare(const value_compare& cmp, const int& val) const
52+
bool compare(const value_compare<Comp>& cmp, const int& val) const
6053
{
6154
return cmp(getValue(), val);
6255
}
6356

64-
bool notCompare(const value_compare& cmp, const int& val) const
57+
bool notCompare(const value_compare<Comp>& cmp, const int& val) const
6558
{
6659
return !compare(cmp, val);
6760
}
6861
};
6962

70-
template <class Node> class BinarySearchTree;
63+
template <class Comp, class Node> class BinarySearchTree;
7164

72-
class BinaryTreeNode : public TreeNode
65+
template <class Comp> class BinaryTreeNode : public TreeNode<Comp>
7366
{
74-
friend class BinarySearchTree<BinaryTreeNode>;
67+
friend class BinarySearchTree<Comp, BinaryTreeNode>;
7568

7669
protected:
7770
BinaryTreeNode* _left;
7871
BinaryTreeNode* _right;
7972

8073
public:
74+
typedef ft::value_compare<Comp> value_compare;
75+
typedef Comp comp;
76+
8177
BinaryTreeNode(
8278
int* _val, BinaryTreeNode* _left = NUL, BinaryTreeNode* _right = NUL)
83-
: TreeNode(_val), _left(_left), _right(_right)
79+
: TreeNode<Comp>(_val), _left(_left), _right(_right)
8480
{
8581
}
8682

@@ -168,11 +164,13 @@ template <class Node> class BinaryTree
168164
typedef const int* pointer;
169165

170166
protected:
171-
pnode_t _root;
172-
size_t _sz;
173-
std::allocator<node_t> _a_node_t;
174-
allocator_type _a_t;
175-
value_compare _c;
167+
pnode_t _root;
168+
size_t _sz;
169+
std::allocator<node_t> _a_node_t;
170+
allocator_type _a_t;
171+
typename Node::value_compare _c;
172+
173+
typedef typename Node::comp comp;
176174

177175
public:
178176
size_t size() const
@@ -472,15 +470,16 @@ template <class Node> class BinarySearchTreeIterator
472470
}
473471
};
474472

475-
template <class Node = BinaryTreeNode>
473+
template <class Comp = less<int>, class Node = BinaryTreeNode<Comp> >
476474
class BinarySearchTree : public BinaryTree<Node>
477475
{
478476
protected:
479-
using typename BinaryTree<Node>::pnode_t;
480-
481477
public:
478+
using typename BinaryTree<Node>::pnode_t;
479+
using typename BinaryTree<Node>::node_t;
482480
using typename BinaryTree<Node>::value_type;
483481
using typename BinaryTree<Node>::size_type;
482+
using typename BinaryTree<Node>::comp;
484483

485484
typedef BinarySearchTreeIterator<Node> iterator;
486485
typedef ft::reverse_iterator<BinarySearchTreeIterator<Node> > reverse_iterator;

include/tree/RedBlackTree.hpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,18 @@ enum Color
1414
BLACK
1515
};
1616

17-
struct RBNode : public TreeNode
17+
template <class Comp = less<int> > struct RBNode : public TreeNode<Comp>
1818
{
19+
typedef ft::value_compare<Comp> value_compare;
20+
typedef Comp comp;
21+
1922
RBNode* _parent;
2023
RBNode* _left;
2124
RBNode* _right;
2225
Color _color;
2326

2427
RBNode(int* _val, RBNode* _left = NUL, RBNode* _right = NUL, RBNode* _parent = NUL)
25-
: TreeNode(_val), _parent(_parent), _left(_left), _right(_right),
28+
: TreeNode<Comp>(_val), _parent(_parent), _left(_left), _right(_right),
2629
_color(RED)
2730
{
2831
}
@@ -201,20 +204,30 @@ struct RBNode : public TreeNode
201204
}
202205
};
203206

204-
class RedBlackTree : public BinarySearchTree<RBNode>
207+
template <class Comp = less<int> >
208+
class RedBlackTree : public BinarySearchTree<Comp, RBNode<Comp> >
205209
{
210+
protected:
211+
using typename BinarySearchTree<Comp, RBNode<Comp> >::pnode_t;
212+
using typename BinarySearchTree<Comp, RBNode<Comp> >::node_t;
213+
214+
public:
215+
using typename BinarySearchTree<Comp, RBNode<Comp> >::value_type;
216+
using typename BinarySearchTree<Comp, RBNode<Comp> >::size_type;
217+
using typename BinarySearchTree<Comp, RBNode<Comp> >::comp;
218+
206219
public:
207220
RedBlackTree()
208221
{
209222
}
210223

211224
void insert(const value_type& val)
212225
{
213-
pnode_t node = BinarySearchTree::insert(val);
226+
pnode_t node = BinarySearchTree<Comp, RBNode<Comp> >::insert(val);
214227
if (node != NUL)
215228
rebalanceInsertion(node);
216-
if (hasRoot())
217-
ASSERT(getRoot().is(BLACK));
229+
if (this->hasRoot())
230+
ASSERT(this->getRoot().is(BLACK));
218231
}
219232

220233
void rebalanceInsertion(pnode_t node)
@@ -245,8 +258,8 @@ class RedBlackTree : public BinarySearchTree<RBNode>
245258
break;
246259
}
247260
}
248-
getRoot().set(BLACK);
249-
ASSERT(getRoot().is(BLACK));
261+
this->getRoot().set(BLACK);
262+
ASSERT(this->getRoot().is(BLACK));
250263
}
251264

252265
void handleCaseThreeInsertion(
@@ -305,7 +318,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
305318
// switch Y parent and X Parent
306319
pnode_t xParent = x->getParentAddr();
307320
if (xParent == NUL)
308-
setRoot(y);
321+
this->setRoot(y);
309322
else if (x->getPosition() == LEFT)
310323
xParent->setLeft(y);
311324
else
@@ -334,7 +347,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
334347

335348
void erase(const value_type& val)
336349
{
337-
pnode_t p = find(val);
350+
pnode_t p = this->find(val);
338351
pnode_t x = NUL;
339352
pnode_t pa = NUL;
340353
Position pos;
@@ -349,9 +362,9 @@ class RedBlackTree : public BinarySearchTree<RBNode>
349362
else
350363
handleCaseThreeDeletion(p, pa, x, pos);
351364

352-
setSize(size() - 1);
365+
this->setSize(this->size() - 1);
353366
rebalanceDeletion(p->getColor(), pa, x, pos);
354-
deleteNode(p);
367+
this->deleteNode(p);
355368
}
356369

357370
void rebalanceDeletion(Color clr, pnode_t pa, pnode_t x, Position pos)
@@ -453,7 +466,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
453466
ASSERT_NOT_NUL(node);
454467
ASSERT(node->hasRight());
455468
ASSERT(node->getRight().hasLeft());
456-
pnode_t succ = upper_bound(node);
469+
pnode_t succ = this->upper_bound(node);
457470
ASSERT(node != succ);
458471

459472
pnode_t parent = node->getParentAddr();
@@ -462,7 +475,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
462475
ASSERT(succ != right);
463476

464477
if (parent == NUL)
465-
setRoot(succ);
478+
this->setRoot(succ);
466479
else if (node->getPosition() == LEFT)
467480
parent->setLeft(succ);
468481
else
@@ -500,7 +513,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
500513
ASSERT_NOT_NUL(right);
501514

502515
if (parent == NUL)
503-
setRoot(right);
516+
this->setRoot(right);
504517
else if (node->getPosition() == LEFT)
505518
parent->setLeft(right);
506519
else
@@ -528,7 +541,7 @@ class RedBlackTree : public BinarySearchTree<RBNode>
528541

529542
pos = LEFT;
530543
if (parent == NUL)
531-
setRoot(left);
544+
this->setRoot(left);
532545
else if (node->getPosition() == LEFT)
533546
{
534547
parent->setLeft(left);

tests/stamim_tester/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "main.hpp"
2+
#include "functional.hpp"
23
#include "tree/BinarySearchTreeTest.hpp"
34
#include "tree/RedBlackTreeTest.hpp"
45

@@ -25,6 +26,13 @@ int main()
2526
test_vector();
2627
test_deque();
2728
test_list();
28-
test_bst<ft::BinarySearchTreeTest>();
29-
test_bst<ft::RedBlackTreeTest>();
29+
30+
test_bst<ft::BinarySearchTreeTest<> >();
31+
test_bst<ft::RedBlackTreeTest<> >();
32+
33+
test_bst<ft::BinarySearchTreeTest<ft::less<int> > >();
34+
test_bst<ft::RedBlackTreeTest<ft::less<int> > >();
35+
36+
test_bst<ft::BinarySearchTreeTest<ft::greater<int> > >();
37+
test_bst<ft::RedBlackTreeTest<ft::greater<int> > >();
3038
}

tests/stamim_tester/tree/BinarySearchTreeTest.hpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,26 @@
77
namespace ft
88
{
99

10-
class BinarySearchTreeTest : public BinarySearchTree<>
10+
template <class Comp = less<int> >
11+
class BinarySearchTreeTest : public BinarySearchTree<Comp>
1112
{
1213
// TODO: add check: traversal from the null element works
1314
public:
14-
void insert(const value_type& val)
15+
void insert(const typename BinarySearchTree<Comp>::value_type& val)
1516
{
16-
size_t i = size();
17+
size_t i = this->size();
1718
bool count = this->count(val) >= 1;
18-
BinarySearchTree::insert(val);
19+
BinarySearchTree<Comp>::insert(val);
1920
assert(isBinarySearchTree(*this));
2021
assert(isInOrderTraversalSorted(*this));
2122
assert(hasCorrectSize(*this, count ? i : i + 1));
2223
}
2324

24-
void erase(const value_type& val)
25+
void erase(const typename BinarySearchTree<Comp>::value_type& val)
2526
{
26-
size_t i = size();
27+
size_t i = this->size();
2728
bool count = this->count(val) >= 1;
28-
BinarySearchTree::erase(val);
29+
BinarySearchTree<Comp>::erase(val);
2930
assert(isBinarySearchTree(*this));
3031
assert(isInOrderTraversalSorted(*this));
3132
assert(hasCorrectSize(*this, count ? i - 1 : i));
@@ -52,7 +53,7 @@ class BinarySearchTreeTest : public BinarySearchTree<>
5253
{
5354
if (!tree.hasRoot())
5455
return true;
55-
return _isBST(tree, tree.getRoot(), INT_MIN, INT_MAX);
56+
return _isBST(tree, tree.getRoot(), tree._c.c.TEST_MIN, tree._c.c.TEST_MAX);
5657
}
5758

5859
struct BalancedTreeTest

0 commit comments

Comments
 (0)