A Template Engine for Modern C++

Overview

CI Status Documentation Status Github Releases Github Issues GitHub License

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, loops, conditions, includes, callbacks, and comments you need, nested and combined as you like. Inja uses the wonderful json library by nlohmann for data input. Most importantly, inja needs only two header files, which is (nearly) as trivial as integration in C++ can get. Of course, everything is tested on all relevant compilers. Here is what it looks like:

json data;
data["name"] = "world";

inja::render("Hello {{ name }}!", data); // Returns "Hello world!"

Integration

Inja is a headers only library, which can be downloaded from the releases or directly from the include/ or single_include/ folder. Inja uses nlohmann/json.hpp (>= v3.8.0) as its single dependency, so make sure it can be included from inja.hpp. json can be downloaded here. Then integration is as easy as:

#include <inja.hpp>

// Just for convenience
using namespace inja;
using json = nlohmann::json;

If you are using the Meson Build System, then you can wrap this repository as a subproject.

If you are using Conan to manage your dependencies, have a look at this repository. Please file issues here if you experience problems with the packages.

You can also integrate inja in your project using Hunter, a package manager for C++.

If you are using vcpkg on your project for external dependencies, then you can use the inja package. Please see the vcpkg project for any issues regarding the packaging.

If you are using cget, you can install the latest development version with cget install pantor/inja. A specific version can be installed with cget install pantor/[email protected].

On macOS, you can install inja via Homebrew and brew install inja.

If you are using conda, you can install the latest version from conda-forge with conda install -c conda-forge inja.

Tutorial

This tutorial will give you an idea how to use inja. It will explain the most important concepts and give practical advices using examples and executable code. Beside this tutorial, you may check out the documentation.

Template Rendering

The basic template rendering takes a template as a std::string and a json object for all data. It returns the rendered template as an std::string.

json data;
data["name"] = "world";

render("Hello {{ name }}!", data); // Returns std::string "Hello world!"
render_to(std::cout, "Hello {{ name }}!", data); // Writes "Hello world!" to stream

For more advanced usage, an environment is recommended.

Environment env;

// Render a string with json data
std::string result = env.render("Hello {{ name }}!", data); // "Hello world!"

// Or directly read a template file
Template temp = env.parse_template("./templates/greeting.txt");
std::string result = env.render(temp, data); // "Hello world!"

data["name"] = "Inja";
std::string result = env.render(temp, data); // "Hello Inja!"

// Or read the template file (and/or the json file) directly from the environment
result = env.render_file("./templates/greeting.txt", data);
result = env.render_file_with_json_file("./templates/greeting.txt", "./data.json");

// Or write a rendered template file
env.write(temp, data, "./result.txt");
env.write_with_json_file("./templates/greeting.txt", "./data.json", "./result.txt");

The environment class can be configured to your needs.

// With default settings
Environment env_default;

// With global path to template files and where files will be saved
Environment env_1 {"../path/templates/"};

// With separate input and output path
Environment env_2 {"../path/templates/", "../path/results/"};

// With other opening and closing strings (here the defaults)
env.set_expression("{{", "}}"); // Expressions
env.set_comment("{#", "#}"); // Comments
env.set_statement("{%", "%}"); // Statements {% %} for many things, see below
env.set_line_statement("##"); // Line statements ## (just an opener)

Variables

Variables are rendered within the {{ ... }} expressions.

json data;
data["neighbour"] = "Peter";
data["guests"] = {"Jeff", "Tom", "Patrick"};
data["time"]["start"] = 16;
data["time"]["end"] = 22;

// Indexing in array
render("{{ guests.1 }}", data); // "Tom"

// Objects
render("{{ time.start }} to {{ time.end + 1 }}pm", data); // "16 to 23pm"

If no variable is found, valid JSON is printed directly, otherwise an inja::RenderError is thrown.

Statements

Statements can be written either with the {% ... %} syntax or the ## syntax for entire lines. Note that ## needs to start the line without indentation. The most important statements are loops, conditions and file includes. All statements can be nested.

Loops

// Combining loops and line statements
render(R"(Guest List:
## for guest in guests
	{{ loop.index1 }}: {{ guest }}
## endfor )", data)

/* Guest List:
	1: Jeff
	2: Tom
	3: Patrick */

In a loop, the special variables loop/index (number), loop/index1 (number), loop/is_first (boolean) and loop/is_last (boolean) are defined. In nested loops, the parent loop variables are available e.g. via loop/parent/index. You can also iterate over objects like {% for key, value in time %}.

Conditions

Conditions support the typical if, else if and else statements. Following conditions are for example possible:

// Standard comparisons with a variable
render("{% if time.hour >= 20 %}Serve{% else if time.hour >= 18 %}Make{% endif %} dinner.", data); // Serve dinner.

// Variable in list
render("{% if neighbour in guests %}Turn up the music!{% endif %}", data); // Turn up the music!

// Logical operations
render("{% if guest_count < (3+2) and all_tired %}Sleepy...{% else %}Keep going...{% endif %}", data); // Sleepy...

// Negations
render("{% if not guest_count %}The End{% endif %}", data); // The End

Includes

You can either include other in-memory templates or from the file system.

// To include in-memory templates, add them to the environment first
inja::Template content_template = env.parse("Hello {{ neighbour }}!");
env.include_template("content", content_template);
env.render("Content: {% include \"content\" %}", data); // "Content: Hello Peter!"

// Other template files are included relative from the current file location
render("{% include \"footer.html\" %}", data);

// You can disable to search for templates in the file system via
env.set_search_included_templates_in_files(false);

Inja will throw an inja::RenderError if an included file is not found. To disable this error, you can call env.set_throw_at_missing_includes(false).

Assignments

Variables can also be defined within the template using the set statment.

render("{% set new_hour=23 %}{{ new_hour }}pm", data); // "23pm"

Functions

A few functions are implemented within the inja template syntax. They can be called with

// Upper and lower function, for string cases
render("Hello {{ upper(neighbour) }}!", data); // "Hello PETER!"
render("Hello {{ lower(neighbour) }}!", data); // "Hello peter!"

// Range function, useful for loops
render("{% for i in range(4) %}{{ loop.index1 }}{% endfor %}", data); // "1234"
render("{% for i in range(3) %}{{ at(guests, i) }} {% endfor %}", data); // "Jeff Tom Patrick "

// Length function (please don't combine with range, use list directly...)
render("I count {{ length(guests) }} guests.", data); // "I count 3 guests."

// Get first and last element in a list
render("{{ first(guests) }} was first.", data); // "Jeff was first."
render("{{ last(guests) }} was last.", data); // "Patir was last."

// Sort a list
render("{{ sort([3,2,1]) }}", data); // "[1,2,3]"
render("{{ sort(guests) }}", data); // "[\"Jeff\", \"Patrick\", \"Tom\"]"

// Round numbers to a given precision
render("{{ round(3.1415, 0) }}", data); // 3
render("{{ round(3.1415, 3) }}", data); // 3.142

// Check if a value is odd, even or divisible by a number
render("{{ odd(42) }}", data); // false
render("{{ even(42) }}", data); // true
render("{{ divisibleBy(42, 7) }}", data); // true

// Maximum and minimum values from a list
render("{{ max([1, 2, 3]) }}", data); // 3
render("{{ min([-2.4, -1.2, 4.5]) }}", data); // -2.4

// Convert strings to numbers
render("{{ int(\"2\") == 2 }}", data); // true
render("{{ float(\"1.8\") > 2 }}", data); // false

// Set default values if variables are not defined
render("Hello {{ default(neighbour, \"my friend\") }}!", data); // "Hello Peter!"
render("Hello {{ default(colleague, \"my friend\") }}!", data); // "Hello my friend!"

// Check if a key exists in an object
render("{{ exists(\"guests\") }}", data); // "true"
render("{{ exists(\"city\") }}", data); // "false"
render("{{ existsIn(time, \"start\") }}", data); // "true"
render("{{ existsIn(time, neighbour) }}", data); // "false"

// Check if a key is a specific type
render("{{ isString(neighbour) }}", data); // "true"
render("{{ isArray(guests) }}", data); // "true"
// Implemented type checks: isArray, isBoolean, isFloat, isInteger, isNumber, isObject, isString,

Whitespace Control

In the default configuration, no whitespace is removed while rendering the file. To support a more readable template style, you can configure the environment to control whitespaces before and after a statement automatically. While enabling set_trim_blocks removes the first newline after a statement, set_lstrip_blocks strips tabs and spaces from the beginning of a line to the start of a block.

Environment env;
env.set_trim_blocks(true);
env.set_lstrip_blocks(true);

With both trim_blocks and lstrip_blocks enabled, you can put statements on their own lines. Furthermore, you can also strip whitespaces for both statements and expressions by hand. If you add a minus sign (-) to the start or end, the whitespaces before or after that block will be removed:

render("Hello       {{- name -}}     !", data); // "Hello Inja!"
render("{% if neighbour in guests -%}   I was there{% endif -%}   !", data); // Renders without any whitespaces

Stripping behind a statement or expression also removes any newlines.

Callbacks

You can create your own and more complex functions with callbacks. These are implemented with std::function, so you can for example use C++ lambdas. Inja Arguments are a vector of json pointers.

Environment env;

/*
 * Callbacks are defined by its:
 * - name,
 * - (optional) number of arguments,
 * - callback function.
 */
env.add_callback("double", 1, [](Arguments& args) {
	int number = args.at(0)->get<int>(); // Adapt the index and type of the argument
	return 2 * number;
});

// You can then use a callback like a regular function
env.render("{{ double(16) }}", data); // "32"

// Inja falls back to variadic callbacks if the number of expected arguments is omitted.
env.add_callback("argmax", [](Arguments& args) {
  auto result = std::max_element(args.begin(), args.end(), [](const json* a, const json* b) { return *a < *b;});
  return std::distance(args.begin(), result);
});
env.render("{{ argmax(4, 2, 6) }}", data); // "2"
env.render("{{ argmax(0, 2, 6, 8, 3) }}", data); // "3"

// A callback without argument can be used like a dynamic variable:
std::string greet = "Hello";
env.add_callback("double-greetings", 0, [greet](Arguments args) {
	return greet + " " + greet + "!";
});
env.render("{{ double-greetings }}", data); // "Hello Hello!"

You can also add a void callback without return variable, e.g. for debugging:

env.add_void_callback("log", 1, [greet](Arguments args) {
	std::cout << "logging: " << args[0] << std::endl;
});
env.render("{{ log(neighbour) }}", data); // Prints nothing to result, only to cout...

Comments

Comments can be written with the {# ... #} syntax.

render("Hello{# Todo #}!", data); // "Hello!"

Exceptions

Inja uses exceptions to handle ill-formed template input. However, exceptions can be switched off with either using the compiler flag -fno-exceptions or by defining the symbol INJA_NOEXCEPTION. In this case, exceptions are replaced by abort() calls.

Supported compilers

Inja uses string_view from C++17, but includes the polyfill from martinmoene. This way, the minimum version is C++11. Currently, the following compilers are tested:

  • GCC 4.8 - 9 (and possibly later)
  • Clang 3.5 - 9 (and possibly later)
  • Microsoft Visual C++ 2016 - 2019 (and possibly later)

The unit tests fail to compile with GCC 4.8 but should just work fine. A complete list of supported compiler / os versions can be found in the CI definition.

Comments
  • Callback for in-memory includes?

    Callback for in-memory includes?

    Hi there,

    As first let me thanks for great work you did on Inja. It's the best of templating libraries for C++ I tried. I 'm just integrating your library to my projects and have a question.

    I have a system where I need to generate several templates and then merge it into one result. Because it's not stored in FileSystem I'm doing that in memory.

    Unfortunately, I didn't find an alternative for{% include "footer.html" %} for in-memory templates.

    Would be great to have some callback where I can call {% include "identifier" } which get data from the app and put it back to generated result.

    Currently, I doing that via variables {{ templates.xxx }} but it doesn't seem to be an optimal way because such variables can be very large.

    Is there any way how to do that better? And if not, would you be so kind and add this feature?

    Thanks!

    enhancement 
    opened by ludekvodicka 14
  • Performance problem of inja

    Performance problem of inja

    When I try to render 200 data with inja, the inja processing takes a long time. It takes about 9 seconds. I hope inja can improve the performance problem.

    opened by xmh0511 13
  • Add a hunter package

    Add a hunter package

    Hi, would you be interested in having your library added to the hunter package management? I could file a PR to make this repository comply with the format required by https://github.com/ruslo/hunter . You can see my current changes here https://github.com/pantor/inja/compare/master...jowr:hunter

    opened by jowr 11
  • Segmentation fault: 11 on OS X

    Segmentation fault: 11 on OS X

    Hi,

    my tests just reveal strange error on OSX (I have several multi platform app on Win/Lin/OSX).

    I have these two tests to ensure Inja is working fine in my apps:

    AX_TEST_CASE(inja_callback7)
    {
    	inja::Environment env = inja::Environment();
    	env.add_callback("fce", 0, [&env](inja::Parsed::Arguments /*args*/, const axJson &/*data*/) {return 42; });
    
    	nlohmann::json data;
    	InjaStringType res = env.render("{{ fce }}", data);
    	TEST_CHECK_EQUAL(res, "42");
    }
    
    
    AX_TEST_CASE(inja_callback8)
    {
    	inja::Environment env = inja::Environment();
    	env.add_callback("fce", 0, [&env](inja::Parsed::Arguments /*args*/, const axJson &/*data*/) {return 42;});
    
    	nlohmann::json data;
    	InjaStringType res = env.render("{{ fce() }}", data);
    	TEST_CHECK_EQUAL(res, "42");
    }
    

    First test (callback7) works on any platform without any issues. Second test (callback8) works on Win32/64 as same as Linux 32/64 but on OSX this test ends with Segmentation fault: 11 without any additional info.

    The only difference is in () for zero argument callback.

    Do you have any idea what can be wrong? I will try to debug it but my primary development environment is Windows so I'm not sure if I will be able to detect the issue by myself.

    opened by ludekvodicka 9
  • existsIn with condition

    existsIn with condition

    I used to be able to test for the existence of a key then evaluate the value with one if statement, like this: ## if existsIn(column, "primary_key") and column/primary_key However, that no longer seems to work now and I have to separate the two conditions, like this:

    ## if existsIn(column, "primary_key")
    ## if column/primary_key
    

    Is that expected behavior, or am I doing something wrong?

    enhancement 
    opened by gi9obru0etuPlc6wozls 8
  • Could you improve the performance of inja?

    Could you improve the performance of inja?

    Hi all, I tested the performance of inja, i found render is much more slower than parse.

    env.parse(str); //166ms
    env.render(str, t); //1216ms
    

    so could you improve the performance of render?

    opened by qicosmos 7
  • How to test for not last item?

    How to test for not last item?

    I'm trying to find a way how to test "it's not last item" but without success

    {% for i in items %}
       {% if not(is_last) %} .... doesn't work, throws "[inja.exception.render_error] unknown function in renderer: "
       {% if is_last ==0 %} doesn't work too, throws "[inja.exception.render_error] variable '/is_last==0' not found"
    {% endfor %}
    

    For now I introduced new variable not_last to solve it.

    data_loop["not_last"] = (i != list.size() - 1);

    But I'm curious what is the correct way. Thanks

    opened by ludekvodicka 6
  • Informative error messages: Add line numbers

    Informative error messages: Add line numbers

    Hi @pantor , thanks for the great library!

    I am trying it for a ~100 lines template, and I am experiencing errors such as:

     what():  Unknown function in renderer.
    

    or

     what(): Unknown loop statement.
    

    Do you think there is a way to enrich this error with some information that would help to debug the problem, for example the line number in the original template file? Thanks in advance.

    enhancement 
    opened by traversaro 6
  • Add support for switching to nonstd::string_view

    Add support for switching to nonstd::string_view

    I currently use c++11 for my project. There is no string_view support. I've change all std::string_view to nonstd::string_view and works well. I wonder if we can add this feature to inja, simply enable it by a macro. Then inja can support c++11 as well.

    https://github.com/martinmoene/string-view-lite

    wontfix 
    opened by xiaozhuai 5
  •  How to use double loop

    How to use double loop

    hi,

    I have a problem to use double loop.

    If the json object like this:

    {
    	"data_list": [{
    			"name": "data1",
    			"values": ["Jeff", "Tom", "Patrick"]
    		},
    		{
    			"name": "data2",
    			"values": ["Jeff2", "Tom2", "Patrick2"]
    		}
    	]
    }
    
    json data_list;
    
    json data1;
    data1["name"] = "data1";
    data1["values"] =  {"Jeff", "Tom", "Patrick"};
    
    json data2;
    data2["name"] = "data2";
    data2["values"] =  {"Jeff2", "Tom2", "Patrick2"};
    
    data_list.push_back(data1);
    data_list.push_back(data2);
    

    There is an error when I use the follow code to print something.

    {%  for data in data_list %}
    {%  for value in data.values%}
    {{ value }}
    {%  end for %}
    {%  endfor %}
    

    Thanks!

    opened by xbotao 5
  • Having trouble with more than one

    Having trouble with more than one "or" in statement

    if not loop/is_last or exists("Pump_Stop_Event") or exists("Other_Event_Crew") or exists("Image_Quality")

    the line above fails to parse with "[inja.exception.parser_error] (at 102:54) expected line statement close, got 'or'

    seems to work fine with a single "or." Perhaps I am missing something here?

    opened by erictorgerson 5
  • Whitespace control after loops acts strangely

    Whitespace control after loops acts strangely

    Given this template:

    {% for M in ["doc", "bat", "foo"] -%}
    {% if loop.is_first -%}
      : {# -#}
        {%- endif -%}
        {{M}}_({{M}})
    {% endfor -%}
    {
    }
    

    I get this output:

      : doc_(doc)
      bat_(bat)
      foo_(foo)
      {
      }
    

    I am trying to get this output (an aligned init list):

      : doc_(doc)
        bat_(bat)
        foo_(foo)
      {
      }
    

    I believe this is a bug but it could also be a misunderstanding of inja. Can you help me out? In the case where I get it to indent it will also indent the opening {.

    This template produces that output. The endfor line is simply indented.

    {% for M in ["doc", "bat", "foo"] -%}
    {% if loop.is_first -%}
      : {# -#}
        {%- endif -%}
        {{M}}_({{M}})
      {% endfor -%}
    {
    }
    

    And its output:

      : doc_(doc)
        bat_(bat)
        foo_(foo)
        {
      }
    
    

    Are these bugs or expected behavior?

    opened by devlpr 0
  • Support strings with escaped backslash

    Support strings with escaped backslash

    Inja currently supports certain "special" characters in strings like " or LF via backslash escapeing (\" or \n). When wanting a plain backslash, the string then should be \\.

    But when using this the following error occurs:

    terminate called after throwing an instance of 'nlohmann::detail::parse_error'
      what():  [json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - invalid literal; last read: '"\\")'; expected end of input
    [1]    288226 IOT instruction (core dumped)  ./test.run
    

    example:

    #include <inja/inja.hpp>
    
    int main() {
        inja::Environment env;
        env.add_callback("echo", 1, [] (inja::Arguments& args) {
            return args.at(0)->get<std::string>();
        });
    
        // render the template {{ echo("\\") }}
        inja::json data;
        env.render(R"({{ echo("\\") }})", data);
    }
    
    opened by Mai-Lapyst 0
  • Documentation does not reflect the released version

    Documentation does not reflect the released version

    I install inja with conan. The latest version there is 3.3.0.

    So, I opened the docs at https://pantor.github.io/inja/ where the header clearly says it's the documentation for 3.3.0. I read about include_callback in the documentation, used it in my code, but then couldn't build it since the code is not there.

    The problem is that the documentation is built from master and not from the latest release tag.

    opened by GooRoo 0
  • Using alternative JSON library

    Using alternative JSON library

    How much effort would it be to modify inja to support another JSON library such as boost::json? Is this doable with minimal efforts or would this be a major undertaking?

    opened by Tectu 0
  • Validate template method to check if template can be parsed

    Validate template method to check if template can be parsed

    I am considering using Inja for a project because it's a very nice C++ templating tool. However, the project takes in user-generated content, which means a high possibility of invalid templates. This makes handling exceptions being thrown very cumbersome each time a user passing in an invalid template.

    Would it be possible to create a method that validates the templates and returns even a simple boolean (where it failed would be ideal, but not necessary)? This way, I could validate the template before trying to parse and render it?

    opened by chaseadams509 0
  • Refer the root object by single dot

    Refer the root object by single dot

    This closes #234.

    When I have a list of items (could be objects as well) in the json data file.

    [
        "item1", "item2","item3"
    ]
    

    Now when trying to use them in a loop like

    ## for item in .
    {{ item }}
    ## endfor
    

    Consideration: Is "." appropriate to refer the root document? If not, I'll make another pull request. Note: This is ad-hoc fix. "." cannot be set as the second or later argument. It may be fixed by #247 though I have not confirmed it.

    opened by kubo 0
Releases(v3.3.0)
  • v3.3.0(Jul 28, 2021)

    :zap: Improvements

    • Added template inheritance features like extends and blocks.
    • Added short circuit evaluation for logical expressions.
    • Added join function (#204).

    :bug: Bug Fixes

    • Fixed the round function with precision 0 (#207).
    • Fixed a bug when compiling with INJA_NOEXCEPTION.

    :hammer: Further Changes

    • Added instructions for conda-forge (#187).
    • Fixed several compiler warnings (e.g. #197).
    Source code(tar.gz)
    Source code(zip)
  • v3.2.0(Jan 29, 2021)

    :bug: Bug Fixes

    • Do not install nlohmann json if an external version is used (#177, thanks @matusnovak).
    • Fixed issues with variable names starting with $ or @ (#185).

    :zap: Improvements

    • Added the INJA_NOEXCEPTION macro that disables throwing exceptions throughout inja (#181).

    :hammer: Further Changes

    • Improve Readme examples and vectorize logo.
    • Fixed compiler warnings for unused size variable (#183).
    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Sep 28, 2020)

    First and foremost, this update improves the performance of template rendering, in particular of loops and variable printing.

    :zap: Improvements

    • Added assignment statements to set a variable within a template.
    • Added whitespace control for expressions (#162, thanks to @tindy2013).
    • Added void callbacks without return values, e.g. for debugging purposes.

    :bug: Bug Fixes

    • Fixed an issue of parsing nested functions (#159, thanks to @DeiRex75).
    • Fixed use of parenthesis in combination with logic operators (#155, thanks to @DeiRex75).
    • Fixed an issue with loop data in the render_to function (#165, thanks to @fishjump)

    :hammer: Further Changes

    • Integrated Codacity into CI and fixed several static analyzer issues.
    • Fixed several compiler warnings (#169, thanks to @tindy2013).
    Source code(tar.gz)
    Source code(zip)
    inja.hpp(126.26 KB)
  • v3.0.0(Jul 26, 2020)

    Time for a new major version of inja! 🎉

    ⚡️ Improvements

    • A new core parser and renderer based on an abstract syntax tree (fixing #149), allowing for:
      • Complex expressions of functions, logic expressions and statements.
      • Mathematical functions in templates.
      • Variadic callbacks with unknown number of arguments.
    • Show parsing and render error positions in template (#134, thanks to @sabelka).
    • Performance improvements, in particular for large json data (#146, thanks to @craigpepper) and large template files.
    • Update nlohmann/json to version 3.8.0 (#144, also thanks to @craigpepper).
    • Support for GCC 4.8 (#150, thanks to @rafadesu)

    🔨 Further Changes

    • Move all CI to GitHub Actions.
    • Switching from Catch to Doctest as our testing framework with much better build times.

    🔥 Breaking Changes

    • We've removed the json pointer style for variables in templates.
    • We now require nlohmann/json with a minimum version of 3.8.0.
    Source code(tar.gz)
    Source code(zip)
    inja.hpp(122.52 KB)
  • v2.2.0(Dec 27, 2019)

    We've got a round of fixes and cool improvements for this release.

    ⚡️ Improvements

    • Add whitespace control (#116, thanks to @jpcima).
    • Added new functions: select element at position, string length.
    • Throw exception if file cannot be opened (#117, thanks to @thomastrapp).
    • Bump to newer nlohmann/json (#107, thanks to @JehandadKhan).

    🐛 Bug Fixes

    • Fixed scope when including templates (#118, thanks to @thomastrapp).
    • Fixed Visual Studio compiler warnings (#119, thanks to @Dodzey).

    🔨 Further Changes

    • Much improved CI (#124), in particular for Visual Studio (#125, #128, thanks to @kzeslaf).
    • Move doxygen generation to GitHub CI.
    Source code(tar.gz)
    Source code(zip)
    inja.hpp(106.75 KB)
  • v2.1.0(Feb 16, 2019)

    ✨ Further Improvements

    There are a couple of great improvements for inja in this release:

    • We've added a first API documentation.
    • Thanks to @gracicot and @mhhollomon, we improved cmake and meson target exports (#83, #86).
    • I've added a string_view polyfill for C++11 to C++14.
    • You can now use cget for installing inja (#88). Thanks @pfultz2!
    • Warnings in appveyor has been cleaned.

    🔥 And a small breaking change in the development pipeline: The CMake option for disabling tests has been renamed from BUILD_TEST to BUILD_TESTING.

    Source code(tar.gz)
    Source code(zip)
    inja.hpp(97.05 KB)
  • v2.0.1(Jan 14, 2019)

    This release fixes a memory bug when including templates (#78, #68). Additionally, you can now use render_to without creating an environment and render to general ostreams (#76).

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Dec 23, 2018)

    Finally, this is the next major version of Inja. After reworking most of its internals, Inja is now up to two orders of magnitude faster than v1! (#67)

    ✨Further Improvements

    • We've added type checks as builtin functions (#64).
    • Loop variables are now supported in inja templates (#52).
    • Include in-memory templates (#47).
    • Inja is now easier to integrate either with the vcpkg (#45) or conan (#43) package manager.

    🔥 Breaking Changes

    Inja now requires string_view from C++17.

    Source code(tar.gz)
    Source code(zip)
    inja.hpp(59.00 KB)
  • v1.0.0(Mar 12, 2018)

    This is the first stable release of inja! 🎉

    Major improvements over the last released version are:

    • Added callbacks (#5, #15)
    • New functions: min, max, sort, first, last, conversion to string and number (#22)
    • Added loops over std::map / json objects
    • Fixed lots of errors and warnings (#18)
    • Better error messages
    • More tests and compilers with CI, additional testing with meson
    • Updated dependencies to JSON 3.1 and Catch 2.1
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Nov 14, 2017)

  • v0.1.1(Nov 16, 2017)

Windows kernel hacking framework, driver template, hypervisor and API written on C++

Windows kernel hacking framework, driver template, hypervisor and API written on C++

Александр 1.3k Nov 29, 2022
A universal type for non-type template parameters for C++20 or later.

uninttp A universal type for non-type template parameters for C++20 or later. Installation: uninttp (Universal Non-Type Template Parameters) is a head

null 16 Dec 24, 2021
The lightweight and modern Map SDK for Android and iOS

Open Mobile Maps The lightweight and modern Map SDK for Android (6.0+) and iOS (10+) openmobilemaps.io Getting started Readme Android Readme iOS Featu

Open Mobile Maps 94 Nov 17, 2022
An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples

rootkit-arsenal-guacamole An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples All projects have been por

Matteo Malvica 51 Nov 6, 2022
Mustache text templates for modern C++

About Mustache implementation for modern C++ (requires C++11) Header only Zero dependencies Templated string type for compatibility with any STL-like

Kevin Wojniak 308 Nov 19, 2022
Pretty Printer for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include pprint.hpp and you're good to go. #include <pprint.hpp> To start p

Pranav 880 Nov 23, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Microsoft 7.1k Dec 1, 2022
LibOS is a modern C++17 library that makes OS-specific features cross-platform.

LibOS is a modern C++17 library that makes OS-specific features cross-platform. Ever tried to get Windows version after Windows 8? Or to send ke

Gavrilikhin Daniil 27 Sep 13, 2022
A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.

mp-units - A Units Library for C++ The mp-units library is the subject of ISO standardization for C++23/26. More on this can be found in ISO C++ paper

Mateusz Pusz 661 Nov 27, 2022
The most powerful and customizable binary pattern scanner written on modern C++

Sig The most powerful and customizable binary pattern scanner written on modern C++ ✔ Capabilities: Support for all common pattern formats: Pattern +

Александр 144 Nov 11, 2022
tiny recursive descent expression parser, compiler, and evaluation engine for math expressions

TinyExpr TinyExpr is a very small recursive descent parser and evaluation engine for math expressions. It's handy when you want to add the ability to

Lewis Van Winkle 1.2k Nov 29, 2022
CE-Plugin - 📃 Support Version Cheat Engine 6.5~Higher

?? Support Version Cheat Engine 6.5~Higher ?? Preview ❄️ Reference & Thanks Cheat Engine[Debugger with plugin] Unicorn[CPU emulator framework] Capston

kanren3 1 Jul 25, 2022
A Header-Only Engine that tries to use SFML in a deeper level

⚙️ SFML-Low-Level-Engine ⚙️ A header-only library that tries to use SFML at a deeper level ?? Instalation Download the source code and put the GLD fol

!Gustavo! 4 Aug 27, 2021
libddwaf is Datadog's implementation of a WAF engine

Datadog's WAF libddwaf is Datadog's implementation of a WAF engine, with a goal of low performance and memory overhead, and embeddability in a wide va

Datadog, Inc. 13 Nov 15, 2022
This library support run-time type casting faster than dynamic_cast ( similar to unreal engine's CastTo )

Fast Runtime Type Casting This library give you C++ Fast Runtime Type Casting faster than dynamic_cast ( similar to Unreal Engine's CastTo, IsChildOf

SungJinKang 7 Jun 11, 2022
A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

pantor 1.2k Nov 24, 2022
This is a C plus plus coding template for Compitative programming. This template is very optimized for the Online Judgment

C-plusplus-compitative-Programming-Template Tech We Used C++ Features Easy to compile Easy debug facility Analysised and optimized base template Steps

Alan Binu 15 Jan 27, 2022
FSD-Template - A template UE4.25 project for BP modding.

FSD-Template Project generated by Archengius' UE4 Template Generator. Reflected C++ classes generated by CheatingMuppet & Archengius' UE4SS UHT Genera

null 16 Nov 22, 2022
🚀 Kick-start your C++! A template for modern C++ projects using CMake, CI, code coverage, clang-format, reproducible dependency management and much more.

ModernCppStarter Setting up a new C++ project usually requires a significant amount of preparation and boilerplate code, even more so for modern C++ p

Lars Melchior 3k Nov 29, 2022
A template for modern C++ projects using CMake, Clang-Format, CI, unit testing and more, with support for downstream inclusion.

Modern C++ Template A quick C++ template for modern CMake projects, aimed to be an easy to use starting point. This is my personal take on such a type

Filip Dutescu 1.2k Nov 22, 2022