diff options
Diffstat (limited to 'src/common.h')
-rw-r--r-- | src/common.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 4b2683d..7f2dfc9 100644 --- a/src/common.h +++ b/src/common.h @@ -2,12 +2,15 @@ #include <iostream> #include <stdlib.h> +#include <string.h> #include <utility> struct line_view { const char* line; size_t length; + line_view(const char* s = nullptr) : line(s) { length = s == nullptr ? 0 : strlen(s); } + line_view(const char* s, size_t l) : line(s), length(l) {} friend std::ostream& operator<<(std::ostream& o, const line_view& lv) { for (size_t i = 0; i < lv.length; i++) { o << lv.line[i]; @@ -25,6 +28,22 @@ struct line_view { } return l[i] == '\0'; } + + bool contains(const char* s) { + size_t len = strlen(s); + const char* p = line; + while (p + len < line + length) { + if (*p == *s) { + line_view x{p, len}; + if (x == s) { + return true; + } else { + p++; + } + } + } + return false; + } }; line_view load_file(const char*); @@ -41,3 +60,35 @@ void per_line(line_view file, F&& f, Args&&... args) { } } while (offset < file.length); } + +template <typename F, typename... Args> +void per_char(line_view line, F&& f, Args&&... args) { + for (size_t i = 0; i < line.length; i++) { + if (!f(line.line[i], std::forward<Args>(args)...)) { + break; + } + } +} + +struct ascii_count { + int count[256]; + + ascii_count(line_view lv) : count{0} { + per_char(lv, [this](char c) { + count[static_cast<int>(c)] += 1; + return true; + }); + } + + int operator[](char c) const noexcept { return count[static_cast<int>(c)]; } + friend std::ostream& operator<<(std::ostream& o, const ascii_count& ac) { + for (size_t i = 0; i < 256; i++) { + if (ac.count[i] > 0) { + o << i << " -> " << ac.count[i] << "\n"; + } + } + return o; + } +}; + +bool is_repeated(const char* p1, const char* p2); |