summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2023/flake.nix7
-rw-r--r--2023/include/util.h92
2 files changed, 96 insertions, 3 deletions
diff --git a/2023/flake.nix b/2023/flake.nix
index ddf0408..9971fc1 100644
--- a/2023/flake.nix
+++ b/2023/flake.nix
@@ -56,7 +56,7 @@
56 #include <iostream> 56 #include <iostream>
57 #include <fstream> 57 #include <fstream>
58 58
59 int main(void) 59 int main(int argc, char* argv[])
60 { 60 {
61 int answer{}; 61 int answer{};
62 62
@@ -81,6 +81,7 @@
81 81
82 cat << EOF >> Makefile 82 cat << EOF >> Makefile
83 CXXFLAGS := -std=c++17 83 CXXFLAGS := -std=c++17
84 CPPFLAGS := -I../include
84 EXE := part1 part2 85 EXE := part1 part2
85 86
86 .PHONY: all clean configure 87 .PHONY: all clean configure
@@ -91,13 +92,13 @@
91 bear -- \$(MAKE) all 92 bear -- \$(MAKE) all
92 93
93 %.o: %.cpp 94 %.o: %.cpp
94 \$(CXX) -c \$(CXXFLAGS) $< -o $@ 95 \$(CXX) -c \$(CPPFLAGS) \$(CXXFLAGS) \$< -o \$@
95 96
96 clean: 97 clean:
97 rm -rf \$(EXE) src/*.o compile_commands.json 98 rm -rf \$(EXE) src/*.o compile_commands.json
98 99
99 %: src/%.o 100 %: src/%.o
100 \$(CXX) $^ -o $@ 101 \$(CXX) \$^ -o \$@
101 EOF 102 EOF
102 ''; 103 '';
103 } 104 }
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