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> 2 3 #include "cemplate/cemplate.hpp" 4 5 namespace 6 { 7 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 } 16 17 } // namespace 18 19 namespace cemplate 20 { 21 22 std::string string(const std::string& value) 23 { 24 return std::format(R"("{}")", value); 25 } 26 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 } 32 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 } 38 39 Program& Program::line_empty() 40 { 41 m_ost << "\n"; 42 return *this; 43 } 44 45 Program& Program::line_value(s_t value) 46 { 47 m_ost << indent() << value; 48 return *this; 49 } 50 51 Program& Program::value(s_t value) 52 { 53 m_ost << value; 54 return *this; 55 } 56 57 Program& Program::pragma(s_t value) 58 { 59 m_ost << std::format("#pragma {}\n", value); 60 return *this; 61 } 62 63 Program& Program::include(s_t header) 64 { 65 m_ost << std::format("#include <{}>\n", header); 66 return *this; 67 } 68 69 Program& Program::includeL(s_t header) 70 { 71 m_ost << std::format("#include \"{}\"\n", header); 72 return *this; 73 } 74 75 Program& Program::comment(s_t value) 76 { 77 m_ost << std::format("{}// {}\n", indent(), value); 78 return *this; 79 } 80 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 } 89 90 Program& Program::call(s_t func, s_t args) 91 { 92 m_ost << std::format("{}{}({});\n", indent(), func, args); 93 return *this; 94 } 95 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 } 101 102 Program& Program::ret(s_t value) 103 { 104 m_ost << std::format("{}return {};\n", indent(), value); 105 return *this; 106 } 107 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 } 113 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 } 124 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 } 131 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 } 139 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 } 148 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 }; 160 161 std::string res; 162 163 for (const auto& elem : m_values) { 164 std::visit([&](const auto& val) { res += eval(val, lvl + 1); }, 165 elem.value()); 166 } 167 168 return res; 169 } 170 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 } 176 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 } 185 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 } 191 192 m_function_last.clear(); 193 m_indent--; 194 m_ost << "}\n\n"; 195 return *this; 196 } 197 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 } 203 204 m_namespace_seen.insert(name); 205 m_namespace_stack.push(name); 206 207 m_ost << std::format("namespace {}\n{{\n\n", name); 208 return *this; 209 } 210 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 } 216 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 } 222 223 } // namespace cemplate