cemplateSimple C++ template engine |
git clone git://git.dimitrijedobrota.com/cemplate.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
cemplate.cpp (4865B)
0 #include <format>
1 #include <iostream>
3 #include "cemplate/cemplate.hpp"
5 namespace
6 {
8 void warning(const std::string& message, const std::string& addition) // NOLINT
9 {
10 std::cerr << "Warning: " << message;
11 if (!addition.empty()) {
12 std::cerr << " - " + addition;
13 }
14 std::cerr << '\n' << std::flush;
15 }
17 } // namespace
19 namespace cemplate
20 {
22 std::string string(const std::string& value)
23 {
24 return std::format(R"("{}")", value);
25 }
27 std::string call(s_t func, l_t args)
28 {
29 return std::format(
30 "{}({})", func, join(std::begin(args), std::end(args), ", "));
31 }
33 std::string template_def(s_t var, l_t params)
34 {
35 return std::format(
36 "{}<{}>", var, join(std::begin(params), std::end(params), ", "));
37 }
39 Program& Program::line_empty()
40 {
41 m_ost << "\n";
42 return *this;
43 }
45 Program& Program::line_value(s_t value)
46 {
47 m_ost << indent() << value;
48 return *this;
49 }
51 Program& Program::value(s_t value)
52 {
53 m_ost << value;
54 return *this;
55 }
57 Program& Program::pragma(s_t value)
58 {
59 m_ost << std::format("#pragma {}\n", value);
60 return *this;
61 }
63 Program& Program::include(s_t header)
64 {
65 m_ost << std::format("#include <{}>\n", header);
66 return *this;
67 }
69 Program& Program::includeL(s_t header)
70 {
71 m_ost << std::format("#include \"{}\"\n", header);
72 return *this;
73 }
75 Program& Program::comment(s_t value)
76 {
77 m_ost << std::format("{}// {}\n", indent(), value);
78 return *this;
79 }
81 Program& Program::multilineComment(l_t values)
82 {
83 m_ost << std::format(
84 "{}/* {}\n*/\n",
85 indent(),
86 join(std::begin(values), std::end(values), "\n" + indent() + " "));
87 return *this;
88 }
90 Program& Program::call(s_t func, s_t args)
91 {
92 m_ost << std::format("{}{}({});\n", indent(), func, args);
93 return *this;
94 }
96 Program& Program::call(s_t func, l_t args)
97 {
98 const std::string val = join(std::begin(args), std::end(args), ", ");
99 return call(func, val);
100 }
102 Program& Program::ret(s_t value)
103 {
104 m_ost << std::format("{}return {};\n", indent(), value);
105 return *this;
106 }
108 Program& Program::declaration(s_t type, s_t name, s_t value)
109 {
110 m_ost << std::format("{}{} {} = {};\n", indent(), type, name, value);
111 return *this;
112 }
114 Program& Program::declaration(s_t type, s_t name, i_t value)
115 {
116 m_ost << std::format("{}{} {} = {{\n{}{}}};\n",
117 indent(),
118 type,
119 name,
120 value.format(m_indent + 1),
121 indent());
122 return *this;
123 }
125 Program& Program::require(s_t value)
126 {
127 m_ost << std::format(
128 "{}requires {}\n", ::cemplate::indent(m_indent + 1), value);
129 return *this;
130 }
132 Program& Program::template_decl(l_t params)
133 {
134 m_ost << std::format("{}template <{}>\n",
135 indent(),
136 join(std::begin(params), std::end(params), ", "));
137 return *this;
138 }
140 Program& Program::function_decl(s_t name, s_t ret, l_t params)
141 {
142 m_ost << std::format("{} {}({});\n",
143 ret,
144 name,
145 join(std::begin(params), std::end(params), ", "));
146 return *this;
147 }
149 std::string InitlistNode::format(uint64_t lvl) const
150 {
151 const auto eval = []<typename T>(const T& val, std::uint64_t llvl)
152 {
153 if constexpr (std::is_same_v<T, std::string>) {
154 return std::format("{}{},\n", indent(llvl), val);
155 } else {
156 return std::format(
157 "{}{{\n{}{}}},\n", indent(llvl), val.format(llvl + 1), indent(llvl));
158 }
159 };
161 std::string res;
163 for (const auto& elem : m_values) {
164 std::visit([&](const auto& val) { res += eval(val, lvl + 1); },
165 elem.value());
166 }
168 return res;
169 }
171 Program& Program::function_open(s_t name, s_t ret, l_t params)
172 {
173 if (!m_function_last.empty()) {
174 warning("opening, but function is not closed", m_function_last);
175 }
177 m_function_last = name;
178 m_indent++;
179 m_ost << std::format("{} {}({})\n{{\n",
180 ret,
181 name,
182 join(std::begin(params), std::end(params), ", "));
183 return *this;
184 }
186 Program& Program::function_close(s_t name)
187 {
188 if (m_function_last != name) {
189 warning("closing, but function is not closed", m_function_last);
190 }
192 m_function_last.clear();
193 m_indent--;
194 m_ost << "}\n\n";
195 return *this;
196 }
198 Program& Program::namespace_open(s_t name)
199 {
200 if (m_namespace_seen.contains(name)) {
201 warning("nesting namespaces of the same name", name);
202 }
204 m_namespace_seen.insert(name);
205 m_namespace_stack.push(name);
207 m_ost << std::format("namespace {}\n{{\n\n", name);
208 return *this;
209 }
211 Program& Program::namespace_close(s_t name)
212 {
213 if (m_namespace_stack.empty() || m_namespace_stack.top() != name) {
214 warning("closing unproper namespace", name);
215 }
217 m_namespace_seen.erase(name);
218 m_namespace_stack.pop();
219 m_ost << std::format("\n}} // namespace {}\n\n", name);
220 return *this;
221 }
223 } // namespace cemplate