-
Notifications
You must be signed in to change notification settings - Fork 0
/
RBTs_iterator.hpp
148 lines (123 loc) · 4.16 KB
/
RBTs_iterator.hpp
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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* RBTs_iterator.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: graja <graja@student.42wolfsburg.de> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/26 08:02:45 by graja #+# #+# */
/* Updated: 2022/05/10 08:17:00 by graja ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef RBTS_ITERATOR_H
# define RBTS_ITERATOR_H
# include "iterator.hpp"
# include "utility.hpp"
namespace ft
{
template <typename Key, bool is_const>
class RBTs_iterator : public ft::iterator<std::bidirectional_iterator_tag, Key>
{
public:
typedef Key key_type;
typedef bool mapped_type;
typedef Key value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type & const_reference;
private:
typedef typename RBtree<key_type, mapped_type>::iter RBsnode;
typedef typename RBtree<key_type, mapped_type>::const_iter cRBsnode;
typedef typename choose<is_const, cRBsnode , RBsnode >::type RBs_type;
RBs_type _p;
RBs_type _first;
RBs_type _last;
public:
RBTs_iterator(void) :_p(NULL) {}
RBTs_iterator(RBs_type in, RBs_type f = NULL, RBs_type l = NULL) :
_p(in), _first(f), _last(l) {}
~RBTs_iterator(void) {}
template<typename fst, bool cval>
RBTs_iterator(const RBTs_iterator<fst, cval> & r) : _p(r.getPtr()) {}
RBs_type getPtr(void) const {return _p;}
RBs_type getf(void) const {return _first;}
RBs_type getl(void) const {return _last;}
RBTs_iterator(const RBTs_iterator & cpy) : _p(cpy._p), _first(cpy._first), _last(cpy._last) {}
RBTs_iterator & operator=(const RBTs_iterator & right)
{
this->_p = right._p;
this->_first = right._first;
this->_last = right._last;
return (*this);
}
RBTs_iterator & operator++()
{
RBs_type tmp;
if (!_p)
_p = _first;
else if (!_p->right_child)
{
tmp = _p->parent;
while (tmp && tmp->data->first < _p->data->first)
tmp = tmp->parent;
_p = tmp;
}
else if (!_p->right_child->left_child)
_p = (_p->right_child);
else if (_p->right_child->left_child)
{
tmp = _p->right_child->left_child;
while (tmp->left_child)
tmp = tmp->left_child;
_p = tmp;
}
return (*this);
}
RBTs_iterator operator++(int)
{RBTs_iterator tmp(*this); operator++(); return tmp;}
RBTs_iterator& operator--()
{
RBs_type tmp;
if (!_p)
_p = _last;
else if (!_p->left_child)
{
tmp = _p->parent;
while (tmp && tmp->data->first > _p->data->first)
tmp = tmp->parent;
_p = tmp;
}
else if (!_p->left_child->right_child)
_p = (_p->left_child);
else if (_p->left_child->right_child)
{
tmp = _p->left_child->right_child;
while (tmp->right_child)
tmp = tmp->right_child;
_p = tmp;
}
return (*this);
}
RBTs_iterator operator--(int)
{RBTs_iterator tmp(*this); operator--(); return tmp;}
key_type const operator*()
{
return ((_p->data->first));
}
key_type const operator->()
{
return ((_p->data).first);
}
//This has to be a template, because we have two iterators in
//one, only differing by the bool is_c which is actually pointing
//out if it is const or not. So we need this to compare one with
//the other or compiler will hit us straight in the face !
template <typename L, bool is_c>
bool operator==(const RBTs_iterator<L, is_c> & lhs) const
{return lhs.getPtr() == this->getPtr();}
template <typename L, bool is_c>
bool operator!=(const RBTs_iterator<L, is_c> & lhs) const
{return lhs.getPtr() != this->getPtr();}
};
} //end namespace
#endif