-
Notifications
You must be signed in to change notification settings - Fork 0
/
input_iterator.hpp
104 lines (101 loc) · 3.11 KB
/
input_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
//
// Created by joachim on 3/9/22.
//
#ifndef FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP
# define FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP
#include <stdlib.h>
#include <set>
#include <exception>
#include <iterator>
/**
* this class downgrade any iterator satisfying the input iterator
* requirement to the most basic input iterator
* @tparam base_it the iterator to downgrade
* @warning an incrementation invalidate all copies
*/
template <class base_it>
class input_iterator
{
base_it it;
bool valid;
public:
typedef typename base_it::value_type value_type;
typedef typename base_it::pointer pointer;
typedef typename base_it::reference reference;
typedef typename base_it::difference_type difference_type;
typedef typename std::input_iterator_tag iterator_category;
std::set<input_iterator*> equivalents;
input_iterator() : it(), valid(true), equivalents() {}
input_iterator(const base_it it) : it(it), valid(true), equivalents() {}
input_iterator(const input_iterator &src) : it(src.it), valid(src.valid), equivalents(src.equivalents) {
if (valid)
{
this->equivalents.insert((input_iterator *)&src);
for (typename std::set<input_iterator *>::iterator i = this->equivalents.begin();
i != this->equivalents.end(); i++)
(*i)->equivalents.insert(this);
}
}
~input_iterator()
{
for (typename std::set<input_iterator *>::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++)
(*i)->equivalents.erase(this);
this->equivalents.clear();
}
input_iterator &operator=(input_iterator const & src) {
for (typename std::set<input_iterator *>::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++)
(*i)->equivalents.erase(this);
this->equivalents.clear();
this->it = src.it;
this->valid = src.valid;
if (valid) {
this->equivalents.insert((input_iterator*)&src);
for (typename std::set<input_iterator *>::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++)
(*i)->equivalents.insert(this);
}
return (*this);
}
class invalid_inputit : public std::exception
{
const char * what() const throw()
{
return ("an invalidated input iterator was used");
}
};
friend bool operator==(input_iterator const &l, input_iterator const &r){
return (l.it == r.it);
}
friend bool operator!=(input_iterator const &l, input_iterator const &r){
return (l.it != r.it);
}
const typename base_it::value_type &operator*() const {
if (!this->valid)
throw invalid_inputit();
return (*it);
}
const typename base_it::pointer operator->() const {
if (!this->valid)
throw invalid_inputit();
return (&*it);
}
input_iterator &operator++() {
if (!this->valid)
throw invalid_inputit();
for (typename std::set<input_iterator *>::iterator i = this->equivalents.begin(); i != this->equivalents.end(); i++)
{
(*i)->valid = false;
(*i)->equivalents.clear();
}
this->equivalents.clear();
++(this->it);
return(*this);
}
input_iterator operator++(int) {
if (!this->valid)
throw invalid_inputit();
input_iterator ret(*this);
++(*this);
return(ret);
}
};
#endif //FT_CONTAINERS_MONKEY_TESTER_INPUT_ITERATOR_HPP