diff options
author | Federico Igne <undyamon@disroot.org> | 2023-12-05 20:21:12 +0100 |
---|---|---|
committer | Federico Igne <undyamon@disroot.org> | 2023-12-05 20:21:12 +0100 |
commit | edb663db73a478adb90131e3e27af919b0a4ac37 (patch) | |
tree | ef1a04dd59d43474432d9ec2283398f22bf59a8e /2023/include/util.h | |
parent | 758342fa607708d70943b5ea74775d4cdb83b646 (diff) | |
download | aoc-edb663db73a478adb90131e3e27af919b0a4ac37.tar.gz aoc-edb663db73a478adb90131e3e27af919b0a4ac37.zip |
feat(cpp): add common utils
Diffstat (limited to '2023/include/util.h')
-rw-r--r-- | 2023/include/util.h | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/2023/include/util.h b/2023/include/util.h new file mode 100644 index 0000000..1b5f1c5 --- /dev/null +++ b/2023/include/util.h | |||
@@ -0,0 +1,92 @@ | |||
1 | #ifndef UTIL_H | ||
2 | #define UTIL_H | ||
3 | |||
4 | #include <algorithm> | ||
5 | #include <cstring> | ||
6 | #include <stdexcept> | ||
7 | #include <string> | ||
8 | |||
9 | namespace util | ||
10 | { | ||
11 | |||
12 | /* TODO */ | ||
13 | constexpr char SPACE[] = " "; | ||
14 | constexpr char COLON[] = ":"; | ||
15 | constexpr char SEMICOLON[] = ";"; | ||
16 | |||
17 | inline void trim(std::string& str) | ||
18 | { | ||
19 | str.erase(str.begin(), std::find_if_not(str.cbegin(), str.cend(), ::isspace)); | ||
20 | str.erase(std::find_if_not(str.crbegin(), str.crend(), ::isspace).base(), str.end()); | ||
21 | } | ||
22 | |||
23 | template<const char* delim, typename Accumulate> | ||
24 | void accumulate(const std::string& str, Accumulate acc) | ||
25 | { | ||
26 | size_t pos{}; | ||
27 | std::string elem; | ||
28 | |||
29 | while ((pos = str.find(delim)) != std::string::npos) { | ||
30 | auto sub = str.substr(0, pos); | ||
31 | trim(sub); | ||
32 | acc(sub); | ||
33 | pos += std::strlen(delim); | ||
34 | } | ||
35 | } | ||
36 | /* ---- */ | ||
37 | |||
38 | /** @brief Discard element from stream by type. | ||
39 | * | ||
40 | * @tparam T the type of the element to discard. | ||
41 | * @param stream the input stream. | ||
42 | * | ||
43 | * @return the input stream. | ||
44 | */ | ||
45 | template<typename T, typename CharT, typename Traits> | ||
46 | std::basic_istream<CharT, Traits>& skip(std::basic_istream<CharT, Traits>& stream) | ||
47 | { | ||
48 | T discard; | ||
49 | return stream >> discard; | ||
50 | } | ||
51 | |||
52 | /** @brief Skip token in stream. | ||
53 | * | ||
54 | * @tparam keyword the token to skip. | ||
55 | * @param stream the input stream. | ||
56 | * | ||
57 | * @return the input stream. | ||
58 | * | ||
59 | * @note The token needs to be declared as a `const char[]`, but normally, | ||
60 | * string literals are `const char*`. | ||
61 | * | ||
62 | * ```cpp | ||
63 | * constexpr char RESULT[] = "Result:"; | ||
64 | * | ||
65 | * int main(int argc, char* argv[]) | ||
66 | * { | ||
67 | * int res; | ||
68 | * std::istringstream in{ "Result: 42"} | ||
69 | * in >> skip<RESULT> >> res; | ||
70 | * | ||
71 | * // ... | ||
72 | * | ||
73 | * return 0 | ||
74 | * } | ||
75 | * ``` | ||
76 | */ | ||
77 | template<const char* keyword, typename CharT, typename Traits> | ||
78 | std::basic_istream<CharT, Traits>& skip(std::basic_istream<CharT, Traits>& stream) | ||
79 | { | ||
80 | std::string word; | ||
81 | stream >> word; | ||
82 | if (word != keyword) | ||
83 | { | ||
84 | throw std::invalid_argument("Malformed input"); | ||
85 | } | ||
86 | |||
87 | return stream; | ||
88 | } | ||
89 | |||
90 | } // namespace util | ||
91 | |||
92 | #endif //UTIL_H | ||