-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinput_handler.cpp
More file actions
134 lines (117 loc) · 4.26 KB
/
input_handler.cpp
File metadata and controls
134 lines (117 loc) · 4.26 KB
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
#include "input_handler.h"
#include <cassert>
#include <iostream>
#include <limits> // for std::numeric_limits
#include <sstream>
#include <unordered_map>
#include <cstdlib>
//#include <string> // in case we want to use std::char_traits<char>::eof
InputHandler::InputHandler(std::unordered_map<std::string_view,char> dict,
char delimIn, char delimOut)
: m_translatedStream {}
, m_dict { dict }
, m_delimIn { delimIn }
, m_delimOut { delimOut } {}
std::istringstream& operator>>(std::istream& in, InputHandler& inputHandler)
{
// clean_sstream(m_translatedStream);
const char delimIn {inputHandler.m_delimIn};
const char delimOut {inputHandler.m_delimOut};
std::string currentWord {};
std::stringstream translatedWord {};
std::string translatedStrUnit {};
std::string translatedString {};
while (true)
{
// consider handling this also in production
assert(in && "InputHandler: in is in failstate\n");
in >> currentWord;
while(in.peek() == ' ') in.ignore(); // eat whitespace (but not '\n')
if (inputHandler.m_dict.contains(currentWord))
{
translatedWord << inputHandler.m_dict[currentWord];
translatedWord >> translatedStrUnit;
translatedString += translatedStrUnit + ' ';
}
else
{
in.ignore(std::numeric_limits<std::streamsize>::max(), delimIn);
break; // exit as soon as invalid input is encountered...
}
if (in.peek() == delimIn)
{
in.ignore();
break; // ... or if delimiter is reached
}
// restore translatedWord ostream
translatedWord.clear();
translatedWord.str("");
}
translatedString += delimOut; // add delimiter to translated string
inputHandler.m_translatedStream.str(std::move(translatedString));
// clean_istream(in);
return inputHandler.m_translatedStream;
}
std::ostream& operator<<(std::ostream& out, InputHandler& inputHandler)
{
// // doing as follows destroys the content, which we do not actually want
// std::string outstr {};
// std::getline(inputHandler.m_translatedStream, outstr);
// out << outstr;
// this creates a copy of the underlying string instead
out << inputHandler.m_translatedStream.str();
return out;
}
void InputHandler::clean_istream(std::istream& istream)
{
istream.clear();
istream.ignore(std::numeric_limits<std::streamsize>::max(), m_delimIn);
//
// // alternatively
// while (!istream.eof())
// istream.ignore();
// istream.clear();
//
// // if we do not want to end up with a failbit
// while (istream.peek() != std::char_traits<char>::eof())
// istream.get();
//
// // these are all less performant alternatives, although simpler to write
//
}
/* how the stream-based history should work
*
* - when undo is entered:
* + pop one character from undoHist
* + put one character into redoHist
*
* - when redo is entered:
* + pop one character from redoHist
* + put one character back into undoHist
*
* foo hello world hi there
*/
/* From learncpp.com:
* https://www.learncpp.com/cpp-tutorial/overloading-operators-using-member-functions/
*
* The following rules of thumb can help you determine which form is best for a
* given situation:
*
* - If you’re overloading assignment (=), subscript ([]), function call (()),
* or member selection (->), do so as a member function.
*
* - If you’re overloading a unary operator, do so as a member function.
*
* - If you’re overloading a binary operator that does not modify its left
* operand (e.g. operator+), do so as a normal function (preferred) or friend
* function.
*
* - If you’re overloading a binary operator that modifies its left operand, but
* you can’t add members to the class definition of the left operand
* (e.g. operator<<, which has a left operand of type ostream), do so as a
* normal function (preferred) or friend function.
*
* - If you’re overloading a binary operator that modifies its left operand
* (e.g. operator+=), and you can modify the definition of the left operand,
* do so as a member function.
*/