summaryrefslogtreecommitdiff
path: root/2023/include/util.h
diff options
context:
space:
mode:
authorFederico Igne <undyamon@disroot.org>2023-12-05 20:21:12 +0100
committerFederico Igne <undyamon@disroot.org>2023-12-05 20:21:12 +0100
commitedb663db73a478adb90131e3e27af919b0a4ac37 (patch)
treeef1a04dd59d43474432d9ec2283398f22bf59a8e /2023/include/util.h
parent758342fa607708d70943b5ea74775d4cdb83b646 (diff)
downloadaoc-edb663db73a478adb90131e3e27af919b0a4ac37.tar.gz
aoc-edb663db73a478adb90131e3e27af919b0a4ac37.zip
feat(cpp): add common utils
Diffstat (limited to '2023/include/util.h')
-rw-r--r--2023/include/util.h92
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
9namespace util
10{
11
12/* TODO */
13constexpr char SPACE[] = " ";
14constexpr char COLON[] = ":";
15constexpr char SEMICOLON[] = ";";
16
17inline 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
23template<const char* delim, typename Accumulate>
24void 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 */
45template<typename T, typename CharT, typename Traits>
46std::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 */
77template<const char* keyword, typename CharT, typename Traits>
78std::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