-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathU.h
256 lines (182 loc) · 6.32 KB
/
U.h
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// Name: Maxwell You
// Date: 2017-04-29
// Purpose: Overload operators
#ifndef U_H
#define U_H
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <string>
#include <vector>
class UIter;
class U {
public:
// typedef UIter as iterator
typedef UIter iterator;
// Ctors
U();
U(const U &rhs);
U(std::string filename);
// Templated iterator ctor
template <typename T>
U(T it1, T it2) {
while (it1 != it2) {
charsRead += *it1;
++it1;
}
createUTFVect();
}
// Assignment operator=
const U &operator=(const U &rhs);
// Dtor
~U();
// Error check ifstream for failure
void streamFail(std::ifstream &in, int byteNum, std::string filename) const;
// Error check for invalid continuation byte
void contByteFail(int byte) const;
// Determines byte length of character
int bytes(int index) const;
// Modified convUTF for reading from a stream and checking valid chars
void readUTF(int byte1, std::ifstream &in, std::string filename);
// Create vector to hold UTF8 chars from accumulated string
void createUTFVect();
// Read characters from an input file
void readfile(std::string filename);
// Adds string to accumulated string
void append(std::string extra);
// State how many characters read thus far
int size() const;
// Get all chars read thus far
std::string get() const;
// Get char at index
std::string get(int index) const;
// Get chars from start to end
std::string get(int start, int end) const;
// Convert UTF8 encoding to Unicode
int convUTF(int byte1, std::string charac) const;
// Return the Unicode codepoint at the index in the accumulated string
int codepoint(int index) const;
// Return true if accumulated string is empty
bool empty() const;
// Removes all data from the obj
void clear();
// Operator Overloading
// Assignment
U &operator=(const std::string & s);
// Append
// u += s
U & operator+=(const std::string & s);
// u += u
U & operator+=(const U & rhs);
// Concatenation
// u + u
const U operator+(const U & rhs) const;
// u + s
const U operator+(const std::string & s) const;
// s + u
friend const U operator+(const std::string & s, const U & rhs);
// Subscripting
// u[index]
std::string operator[](int index) const;
// Send a U to the output stream
// cout << u
friend std::ostream & operator<<(std::ostream & out, const U & rhs);
// Boolean evaluation
operator bool() const;
// Comparison
// u == u
bool operator==(const U & rhs) const;
// u == s
bool operator==(const std::string & s) const;
// s == u
friend bool operator==(const std::string & s, const U & rhs);
// u != u
bool operator!=(const U & rhs) const;
// u != s
bool operator!=(const std::string & s) const;
// s != u
friend bool operator!=(const std::string & s, const U & rhs);
// Iterator methods
// Returns iterator "pointing" to beginning of accumulated string
iterator begin() const;
// Returns iterator "pointing" to one index past accumulated string
iterator end() const;
// Returns first int codepoint by value
int front() const;
// Returns last int codepoint by value
int back() const;
private:
std::string charsRead; // stores all characters read thus far
std::vector<std::string> charsReadVect; // stores UTF8 characters in each index
};
// s + u
const U operator+(const std::string & s, const U & rhs);
// cout << u
std::ostream & operator<<(std::ostream & out, const U & rhs);
// s == u
bool operator==(const std::string & s, const U & rhs);
// s != u
bool operator!=(const std::string & s, const U & rhs);
class UIter {
public:
// Ctors
// Default ctor
UIter(const U *u = nullptr, int i = 0) : parent(u), index(i) { }
// Copy ctor
UIter(const UIter & rhs) = default; // use default b/c it will copy class members already
// Assignment operator
UIter & operator=(const UIter & rhs) = default; // use default b/c it will copy class members already
// Dtor
~UIter() = default; // TODO check for memory leaks later
// Indirection
int operator*() const {
if (!parent) // if this iterator is not associated with a U object
throw std::string("Attempting to indirect uninitialized iterator");
if (index == parent->size()) // if the index of the current iterator is one past the elements
throw std::string("Attempting to indirect end() iterator");
return parent->codepoint(index); // use codepoint of the U obj and the current iterator's index to get codepoint
}
// operator==
bool operator==(const UIter & rhs) const {
if (!parent || !rhs.parent) // both iterators must not be nullptr
throw std::string("Attempting to compare uninitialized iterator");
if (parent != rhs.parent) // both iterators must be associated with the same U object
throw std::string("Attempting to compare iterators from different U objects");
return index == rhs.index; // compare indices of the iterators
}
bool operator!=(const UIter & rhs) const {
return !(*this == rhs); // negate the result of operator==
}
UIter & operator++() { // pre-incr b/c no dummy int arg
if (!parent) // if iterator is uninitialized
throw std::string("Attempting to increment uninitialized iterator");
if (index == parent->size()) // can't incr if iterator is already at end (one past last item)
throw std::string("Attempting to increment end() iterator");
++index; // incr the index
return *this; // return the altered iter
}
UIter operator++(int) { // post-incr b/c of dummy int arg
const auto save = *this; // save the state
++*this; // incr the iter
return save; // return the prev state
}
UIter & operator--() { // pre-decr b/c no dummy int arg
if (!parent) // if iterator is uninitialized
throw std::string("Attempting to decrement uninitialized iterator");
if (index == 0) // can't decr if iterator is at beginning
throw std::string("Attempting to decrement begin() iterator");
--index; // decrement the index
return *this; // return the altered iter
}
UIter operator--(int) { // post-decr b/c of dummy int arg
const auto save = *this; // save the state
--*this; // decr the iter
return *this; // return the prev state
}
private:
const U *parent; // parent U
int index; // index into accumulated string
};
#endif