Last active
November 22, 2017 20:28
-
-
Save DragonOsman/90f7caae90c35c4c31a2d47d89ece9b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <iostream> | |
#include <vector> | |
#include <list> | |
#include "Document.h" | |
std::istream &operator>>(std::istream &is, Document &d) | |
{ | |
char ch = ' '; | |
for ( ; is.get(ch);) | |
{ | |
d.line.back().push_back(ch); // add the character | |
} | |
if (ch == '\n') | |
{ | |
d.line.push_back(Line{}); // add another line | |
} | |
if (d.line.back().size()) | |
{ | |
d.line.push_back(Line{}); // add final empty line | |
} | |
return is; | |
} | |
Document::Text_iterator &Document::Text_iterator::operator++() | |
{ | |
++pos; // proceed to the next character | |
if (pos == (*ln).end()) | |
{ | |
++ln; // proceed to the next line | |
pos = (*ln).begin(); // bad if ln == line.end(); so make sure it isn't | |
} | |
return *this; | |
} | |
Document::Text_iterator Document::Text_iterator::operator++(int n) | |
{ | |
auto ret = *this; | |
pos += n; | |
if (pos == (*ln).end()) | |
{ | |
++ln; | |
pos = (*ln).begin(); | |
} | |
ret = *this; | |
return ret; | |
} | |
Document::Text_iterator Document::Text_iterator::find_txt(Document::Text_iterator first, Document::Text_iterator last, const std::string &s) | |
{ | |
if (s.size() == 0) | |
{ | |
return last; | |
} | |
char first_char = s[0]; | |
while (true) | |
{ | |
auto p = std::find(first, last, first_char); | |
if (p == last || match(p, last, s)) | |
{ | |
return p; | |
} | |
first = ++p; | |
} | |
} | |
bool Document::Text_iterator::match(Document::Text_iterator first, Document::Text_iterator last, const std::string &str) | |
{ | |
if (str.empty()) | |
{ | |
return false; | |
} | |
for (char i = 0, j = *first; i < str.length(), j != *last; ++i, ++j) | |
{ | |
if (i != j) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DOCUMENT_H | |
#define DOCUMENT_H | |
#include <list> | |
#include <iostream> | |
#include <vector> | |
#include <iterator> | |
using Line = std::vector<char>; | |
struct Document | |
{ | |
std::list<Line> line; | |
class Text_iterator : public std::iterator<std::bidirectional_iterator_tag, Line, Line, Line*, Line&> | |
// keep track of line and character position within a line | |
{ | |
std::list<Line>::iterator ln; | |
Line::iterator pos; | |
public: | |
// start iterator at line ll's character position pp | |
Text_iterator(std::list<Line>::iterator ll, Line::iterator pp) | |
: ln{ ll }, pos{ pp } {} | |
char &operator*() { return *pos; } | |
Text_iterator &operator++(); | |
Text_iterator operator++(int n); | |
bool operator==(const Text_iterator &other) { return ln == other.ln && pos == other.pos; } | |
bool operator!=(const Text_iterator &other) { return !(*this == other); } | |
Text_iterator find_txt(Text_iterator first, Text_iterator last, const std::string &s); | |
bool match(Text_iterator first, Text_iterator last, const std::string &str); | |
}; | |
Document() { line.push_back(Line{}); } | |
Text_iterator begin() { return Text_iterator(line.begin(), (*line.begin()).begin()); } | |
Text_iterator end() | |
{ | |
auto last = line.end(); | |
--last; // we know know that the document is not empty | |
return Text_iterator(last, (*last).end()); | |
} | |
}; | |
std::istream &operator>>(std::istream &is, Document &d); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <list> | |
#include <vector> | |
#include "Document.h" | |
void print(Document &d); | |
void erase_line(Document &d, int n); | |
template<typename Iter> | |
void advance(Iter &p, int n); | |
int main() | |
{ | |
std::string str{ "hello world" }; | |
Document doc; | |
for (int i = 0; i < str.length(); ++i) | |
{ | |
doc.line.back().push_back(str[i]); | |
} | |
Document::Text_iterator it = doc.begin(); | |
auto matched = it.find_txt(it, doc.end(), "hello"); | |
if (matched != doc.end()) | |
{ | |
std::cout << "Found\n"; | |
} | |
} | |
void print(Document &d) | |
{ | |
for (auto p : d) | |
{ | |
std::cout << p; | |
} | |
} | |
void erase_line(Document &d, int n) | |
{ | |
if (n < 0 || n >= d.line.size() - 1) | |
{ | |
return; | |
} | |
auto p = d.line.begin(); | |
advance(p, n); | |
d.line.erase(p); | |
} | |
template<typename Iter> | |
void advance(Iter &p, int n) | |
{ | |
while (n > 0) | |
{ | |
++p; | |
--n; | |
} | |
if (n < 0) | |
{ | |
while (n < 0) | |
{ | |
--p; | |
++n; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment