Jinja2C++ Compatibility

Table of contents

  1. Current Jinja2 support
  2. Comparison with other implementations
    1. References
  3. Jinja2C++ performance

Current Jinja2 support

Currently, Jinja2C++ supports the limited number of Jinja2 features. By the way, Jinja2C++ is planned to be full jinja2 specification-conformant. The current support is limited to:

  • expressions. You can use every style of expressions: simple, filtered, conditional, and so on.
  • amost all Jinja2 filters (except of xmlattr and tojson)
  • big number of testers (eq, defined, ge, gt, iterable, le, lt, mapping, ne, number, sequence, string, undefined, in, even, odd, lower, upper)
  • limited number of functions (range, loop.cycle)
  • ‘if’ statement (with ‘elif’ and ‘else’ branches)
  • ‘for’ statement (with ‘else’ branch and ‘if’ part support)
  • ‘set’ statement (both single-line and block version)
  • ‘extends’/’block’ statements
  • ‘include’ statement
  • ‘import’/’from’ statements
  • ‘macro’/’call’ statements
  • ‘with’ statement
  • ‘raw’ statement
  • ‘do’ extension statement
  • ‘filter’ extension statement
  • recursive loops
  • space control

Jinja2 specifiecation implementation notes:

Comparison with other implementations

Feature Jinja2C++ Jinja2CppLight pantor::inja Python Jinja2
More information   see [1] see [2] see [3]
{{ / }} yes yes yes yes
{% / %} yes yes yes yes
{# / #} yes yes yes yes
Single-line statements no no yes yes
raw/endraw yes no no yes
Whitespace control yes no yes yes
Statements        
set yes no no yes
block set yes no no yes
if / endif yes yes yes yes
else yes no yes yes
elif yes no no yes
for / endfor yes yes yes yes
recursive for loop yes no no yes
conditional for loop yes no no yes
extends / block yes no no yes
import yes no no yes
include yes no yes yes
macro / endmacro yes no no yes
call yes no no yes
filter yes no no yes
do (extension) yes no no yes
with (extension) yes no no yes
i18n (extension) no no no yes
continue/break (extension) no no no yes
autoescape (extension) no no no yes
Expressions        
String literals yes yes yes yes
Integer numbers yes yes yes yes
Floating numbers yes yes yes yes
Lists ([1, 3, 4]) yes no no yes
Tuples ((1, "one", 3.14)) yes no no yes
Dicts ({'dict': 'of', 'key': 'and', 'value': 'pairs'}) yes no no yes
True / False yes no no yes
+ operator yes no no yes
- operator yes no no yes
/ operator yes no no yes
// operator yes no no yes
% operator yes no no yes
* operator yes no no yes
** operator yes no no yes
== operator yes yes yes yes
!= operator yes yes yes yes
> / < / >= / <= operators yes yes yes yes
and / or / not logical operators yes no yes yes
in operator yes no yes yes
is operator yes no no yes
| (filter application operator) yes no no yes
~ (string concatenation operator) yes no no yes
() (call operator) yes no yes yes
. (attribute access) yes no yes yes
[] (attribute access) yes no no yes
[] (arrays slicing) no no no yes
Filters        
abs yes no no yes
attr yes no no yes
batch yes no no yes
capitalize yes no no yes
center no no no yes
default yes no yes (as function) yes
dictsort yes no no yes
escape yes no no yes
filesizeformat no no no yes
first yes no yes (as function) yes
float yes no yes (as function) yes
forceescape no no no yes
format yes no no yes
groupby yes no no yes
indent no no no yes
int yes no yes (as function) yes
join yes no no yes
last yes no yes (as function) yes
length yes no yes (as function) yes
list yes no no yes
lower yes no yes (as function) yes
map yes no no yes
max yes no no yes
min yes no no yes
pprint yes no no yes
random yes no no yes
reject yes no no yes
rejectattr yes no no yes
replace yes no no yes
reverse yes no no yes
round yes no yes (as function) yes
safe no no no yes
select yes no no yes
selectattr yes no no yes
slice yes no no yes
sort yes no yes (as function) yes
string yes no yes (as function) yes
striptags no no no yes
sum yes no no yes
title yes no no yes
tojson no no no yes
trim yes no no yes
truncate yes no no yes
unique yes no no yes
upper yes no yes (as function) yes
urlencode yes no no yes
urlize yes no no yes
wordcount yes no no yes
wordwrap yes no no yes
Testers        
callable no no no yes
defined yes no yes (as function) yes
devisibleby no no yes (as function) yes
eq yes no no yes
escaped no no no yes
even yes no yes (as function) yes
ge yes no no yes
gt yes no no yes
in yes no no yes
iterable yes no no yes
le yes no no yes
lower yes no no yes
lt yes no no yes
mapping yes no yes (as function) yes
ne yes no no yes
none no no no yes
number yes no yes (as function) yes
odd yes no no yes
sameas no no no yes
sequence yes no yes (as function) yes
string yes no yes (as function) yes
undefined yes no no yes
upper yes no no yes
Global functions and classes        
range yes no yes (as function) yes
lipsum no no no yes
dict no no no yes
cycler no no no yes
joiner no no no yes
namespace no no no yes

References

  • [1] https://github.com/hughperkins/Jinja2CppLight
  • [2] https://github.com/pantor/inja
  • [3] https://jinja.palletsprojects.com/en/2.10.x/

Jinja2C++ performance

Template Python Jinja2C++ (MSVC build) Jinja2C++ (MinGW Build)
Hello World from Parser! (1 mln. iterations) 4.333 sec 1.883 sec 0.831 sec
{{ message }} from Parser! message=’Hello World!’ (1 mln. iterations) 5.083 2.188 1.082
{{ message }} from Parser! message=100500 (1 mln. iterations) 5.126 2.211 1.087
{{ message | upper }} from Parser! message=’Hello World!’ (1 mln. iterations) 5.583 3.559 1.850
{{ message }} from Parser! - {{number}} message=’Hello World!’, number=100500 (1 mln. iterations) 5.800 2.594 1.504
{% for i in range(20)%} {{i}} {%endfor%} (20 thsd. iterations) 2.485 2.917 1.966
{% for i in range(num)%} {{i}} {%endfor%} num=20 (20 thsd. iterations) 2.575 2.768 2.040
{% for i in range(20)%} {{i ~ "-" ~ loop.index}} {%endfor%} (20 thsd. iterations) 11.720 6.334 4.340
{% for i in range(20) if i is odd %} {{i}} {%endfor%} (20 thsd. iterations) 2.620 3.710 2.733