cemplate

Simple C++ template engine
git clone git://git.dimitrijedobrota.com/cemplate.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commitb52130ffd3fd9d9efdfa7eddeadc59d0cf9ca65d
parenteb546a84db538077491c0b5e54fcb70f4dc22915
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateWed, 12 Mar 2025 13:47:48 +0100

Improve consistency

Diffstat:
Mexample/example.cpp|+--
Minclude/cemplate/cemplate.hpp|++++++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/cemplate.cpp|+++++++++++++++++++++----------

3 files changed, 109 insertions(+), 87 deletions(-)


diff --git a/example/example.cpp b/example/example.cpp

@@ -34,8 +34,7 @@ int main()

.function_decl("decl", "void")
.line_empty()
.line_value("static const test_class test = ")
.Initlist({"val11", "val12", {"val21", "val22"}, "val13"})
.declaration("static const test_class", "test", {"val11", "val12", {"val21", "val22"}, "val13"})
.namespace_close("cemplate");
// clang-format on

diff --git a/include/cemplate/cemplate.hpp b/include/cemplate/cemplate.hpp

@@ -51,83 +51,92 @@ std::string join(std::initializer_list<T> list,

return join(std::begin(list), std::end(list), delim, func);
}
class Program
struct param_t
{
param_t(const std::string& type, const std::string& name)
: m_value(type + " " + name)
{
}
operator std::string() const { return m_value; } // NOLINT
const auto& value() const { return m_value; }
private:
std::string m_value;
};
class InitlistElem;
class InitlistNode
{
public:
using s_t = const std::string&;
using l_t = const std::vector<std::string>&;
InitlistNode(std::initializer_list<InitlistElem> list);
explicit Program(std::ostream& ost)
: m_ost(ost)
template<typename InputItr, typename UnaryFunc>
InitlistNode(InputItr first, InputItr last, UnaryFunc func);
std::string format(uint64_t lvl) const;
operator std::string() const; // NOLINT
private:
std::vector<InitlistElem> m_values; // NOLINT
};
class InitlistElem
{
public:
InitlistElem(std::string value) // NOLINT
: m_value(std::move(value))
{
}
struct param_t
InitlistElem(std::string_view value) // NOLINT
: m_value(std::in_place_type<std::string>, value)
{
param_t(s_t type, s_t name)
: m_value(type + " " + name)
{
}
operator std::string() const { return m_value; } // NOLINT
const auto& value() const { return m_value; }
}
private:
std::string m_value;
};
InitlistElem(const char* value) // NOLINT
: m_value(value)
{
}
class InitlistElem;
InitlistElem(std::initializer_list<InitlistElem> list) // NOLINT
: m_value(std::in_place_type<InitlistNode>, list)
{
}
class InitlistNode
InitlistElem(InitlistNode list) // NOLINT
: m_value(std::move(list))
{
public:
InitlistNode(std::initializer_list<InitlistElem> list);
}
template<typename InputItr, typename UnaryFunc>
InitlistNode(InputItr first, InputItr last, UnaryFunc func);
const auto& value() const { return m_value; }
std::string format(uint64_t lvl) const;
private:
std::variant<std::string, InitlistNode> m_value;
};
operator std::string() const; // NOLINT
static auto indent(std::size_t lvl)
{
return std::string(lvl * 2, ' ');
}
private:
std::vector<InitlistElem> m_values; // NOLINT
};
std::string string(const std::string& value);
class InitlistElem
class Program
{
public:
explicit Program(std::ostream& ost)
: m_ost(ost)
{
public:
InitlistElem(std::string value) // NOLINT
: m_value(std::move(value))
{
}
InitlistElem(std::string_view value) // NOLINT
: m_value(std::in_place_type<std::string>, value)
{
}
InitlistElem(const char* value) // NOLINT
: m_value(value)
{
}
InitlistElem(std::initializer_list<InitlistElem> list) // NOLINT
: m_value(std::in_place_type<InitlistNode>, list)
{
}
InitlistElem(InitlistNode list) // NOLINT
: m_value(std::move(list))
{
}
const auto& value() const { return m_value; }
private:
std::variant<std::string, InitlistNode> m_value;
};
}
using s_t = const std::string&;
using l_t = const std::vector<std::string>&;
using p_t = const std::vector<param_t>&;
using i_t = const InitlistNode&;
// NOLINTBEGIN
Program& line_empty();

@@ -148,6 +157,7 @@ public:

Program& ret(s_t value);
Program& declaration(s_t type, s_t name, s_t value);
Program& declaration(s_t type, s_t name, i_t value);
Program& require(s_t value);
Program& template_decl(l_t params);

@@ -156,26 +166,31 @@ public:

Program& function_decl(s_t name, s_t ret, l_t params = {});
Program& function_open(s_t name, s_t ret, l_t params = {});
Program& function_close(s_t name);
Program& namespace_open(s_t name);
Program& namespace_close(s_t name);
// NOLINTEND
Program& function_open(s_t name, s_t ret, const std::vector<param_t>& params)
Program& function_open(s_t name, s_t ret, p_t params)
{
return function_open(
name,
ret,
std::vector<std::string>(std::begin(params), std::end(params)));
}
Program& function_close(s_t name);
Program& namespace_open(s_t name);
Program& namespace_close(s_t name);
Program& Initlist(const InitlistNode& node);
// NOLINTEND
Program& function_decl(s_t name, s_t ret, p_t params)
{
return function_decl(
name,
ret,
std::vector<std::string>(std::begin(params), std::end(params)));
}
private:
static auto indent(std::size_t lvl) { return std::string(lvl * 2, ' '); }
std::string indent() const { return indent(m_indent); }
std::string indent() const { return ::cemplate::indent(m_indent); }
std::size_t m_indent = 0;

@@ -190,16 +205,13 @@ private:

std::ostream& m_ost; // NOLINT
};
inline Program::InitlistNode::InitlistNode(
std::initializer_list<InitlistElem> list)
inline InitlistNode::InitlistNode(std::initializer_list<InitlistElem> list)
: m_values(list)
{
}
template<typename InputItr, typename UnaryFunc>
Program::InitlistNode::InitlistNode(InputItr first,
InputItr last,
UnaryFunc func)
InitlistNode::InitlistNode(InputItr first, InputItr last, UnaryFunc func)
{
m_values.reserve(last - first);
std::for_each(

diff --git a/source/cemplate.cpp b/source/cemplate.cpp

@@ -20,6 +20,11 @@ void warning(const std::string& message, const std::string& addition) // NOLINT

namespace cemplate
{
std::string string(const std::string& value)
{
return std::format(R"("{}")", value);
}
Program& Program::line_empty()
{
m_ost << "\n";

@@ -40,7 +45,7 @@ Program& Program::value(s_t value)

Program& Program::string(s_t value)
{
m_ost << std::format(R"("{}")", value);
m_ost << ::cemplate::string(value);
return *this;
}

@@ -92,7 +97,7 @@ Program& Program::statement(s_t content)

Program& Program::ret(s_t value)
{
m_ost << std::format("{}m_ost << {};\n", indent(), value);
m_ost << std::format("{}return {};\n", indent(), value);
return *this;
}

@@ -102,9 +107,21 @@ Program& Program::declaration(s_t type, s_t name, s_t value)

return *this;
}
Program& Program::declaration(s_t type, s_t name, i_t value)
{
m_ost << std::format("{}{} {} = {{\n{}{}}};\n",
indent(),
type,
name,
value.format(m_indent + 1),
indent());
return *this;
}
Program& Program::require(s_t value)
{
m_ost << std::format("{}requires {}\n", indent(m_indent + 1), value);
m_ost << std::format(
"{}requires {}\n", ::cemplate::indent(m_indent + 1), value);
return *this;
}

@@ -132,7 +149,7 @@ Program& Program::function_decl(s_t name, s_t ret, l_t params)

return *this;
}
std::string Program::InitlistNode::format(uint64_t lvl) const
std::string InitlistNode::format(uint64_t lvl) const
{
const auto eval = []<typename T>(const T& val, std::uint64_t llvl)
{

@@ -154,12 +171,6 @@ std::string Program::InitlistNode::format(uint64_t lvl) const

return res;
}
Program& Program::Initlist(const InitlistNode& node)
{
m_ost << std::format("{{\n{}{}}}", node.format(m_indent + 1), indent());
return *this;
}
Program& Program::function_open(s_t name, s_t ret, l_t params)
{
if (!m_function_last.empty()) {