Jinja2 C++ (and for C++) almost full-conformance template engine implementation

Jinja2С++

Language Standard Standard Standard Coverage Status Codacy Badge Github Releases Github Issues GitHub License conan.io Gitter Chat

C++ implementation of the Jinja2 Python template engine. This library brings support of powerful Jinja2 template features into the C++ world, reports dynamic HTML pages and source code generation.

Introduction

Main features of Jinja2C++:

  • Easy-to-use public interface. Just load templates and render them.
  • Conformance to Jinja2 specification
  • Full support of narrow- and wide-character strings both for templates and parameters.
  • Built-in reflection for the common C++ types, nlohmann and rapid JSON libraries.
  • Powerful full-featured Jinja2 expressions with filtering (via '|' operator) and 'if'-expressions.
  • Control statements (set, for, if, filter, do, with).
  • Templates extension, including and importing
  • Macros
  • Rich error reporting.
  • Shared template environment with templates cache support

For instance, this simple code:

#include <jinja2cpp/template.h>

std::string source = R"(
{{ ("Hello", 'world') | join }}!!!
{{ ("Hello", 'world') | join(', ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') | lower }}!!!
)";

Template tpl;
tpl.Load(source);

std::string result = tpl.RenderAsString({}).value();

produces the result string:

Helloworld!!!
Hello, world!!!
Hello; world!!!
hello; world!!!

Getting started

To use Jinja2C++ in your project you have to:

  • Clone the Jinja2C++ repository
  • Build it according to the instructions
  • Link to your project.

Usage of Jinja2C++ in the code is pretty simple:

  1. Declare the jinja2::Template object:
jinja2::Template tpl;
  1. Populate it with template:
tpl.Load("{{ 'Hello World' }}!!!");
  1. Render the template:
std::cout << tpl.RenderAsString({}).value() << std::endl;

and get:

Hello World!!!

That's all!

More detailed examples and features description can be found in the documentation: https://jinja2cpp.dev/docs/usage

Current Jinja2 support

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

  • expressions. You can use almost every expression style: simple, filtered, conditional, and so on.
  • the big number of filters (sort, default, first, last, length, max, min, reverse, unique, sum, attr, map, reject, rejectattr, select, selectattr, pprint, dictsort, abs, float, int, list, round, random, trim, title, upper, wordcount, replace, truncate, groupby, urlencode, capitalize, escape, tojson, striptags, center, xmlattr)
  • the big number of testers (eq, defined, ge, gt, iterable, le, lt, mapping, ne, number, sequence, string, undefined, in, even, odd, lower, upper)
  • the number of functions (range, loop.cycle)
  • 'if' statement (with 'elif' and 'else' branches)
  • 'for' statement (with 'else' branch and 'if' part support)
  • 'include' statement
  • 'import'/'from' statements
  • 'set' statement (both line and block)
  • 'filter' statement
  • 'extends'/'block' statements
  • 'macro'/'call' statements
  • 'with' statement
  • 'do' extension statement
  • recursive loops
  • space control and 'raw'/'endraw' blocks

Full information about Jinja2 specification support and compatibility table can be found here: https://jinja2cpp.dev/docs/j2_compatibility.html.

Supported compilers

Compilation of Jinja2C++ tested on the following compilers (with C++14 and C++17 enabled features):

  • Linux gcc 5.5 - 9.0
  • Linux clang 5.0 - 9
  • MacOS X-Code 9
  • MacOS X-Code 10
  • MacOS X-Code 11 (C++14 in default build, C++17 with externally-provided boost)
  • Microsoft Visual Studio 2015 - 2019 x86, x64
  • MinGW gcc compiler 7.3
  • MinGW gcc compiler 8.1

Note: Support of gcc version >= 9.x or clang version >= 8.0 depends on the version of the Boost library provided.

Build status

Compiler Status
MSVC 2015 (x86, x64), MinGW 7 (x64), MinGW 8 (x64) Build status
X-Code 9, 10, 11 Build Status
MSVC 2017 (x86, x64), MSVC 2019 (x86, x64), C++14/C++17
g++ 5, 6, 7, 8, 9, 10, 11 clang 5, 6, 7, 8, 9, 10, 11, 12 C++14/C++17/C++20

Build and install

Jinja2C++ has several external dependencies:

Examples of build scripts and different build configurations could be found here: https://github.com/jinja2cpp/examples-build

In simplest case to compile Jinja2C++ you need:

  1. Install CMake build system (at least version 3.0)
  2. Clone jinja2cpp repository:
> git clone https://github.com/flexferrum/Jinja2Cpp.git
  1. Create build directory:
> cd Jinja2Cpp
> mkdir build
  1. Run CMake and build the library:
> cd build
> cmake .. -DCMAKE_INSTALL_PREFIX=<path to install folder>
> cmake --build . --target all

"Path to install folder" here is a path to the folder where you want to install Jinja2C++ lib.

  1. Install library:
> cmake --build . --target install

In this case, Jinja2C++ will be built with internally-shipped dependencies and install them respectively. But Jinja2C++ supports builds with externally-provided deps.

Usage with conan.io dependency manager

Jinja2C++ can be used as conan.io package. In this case, you should do the following steps:

  1. Install conan.io according to the documentation ( https://docs.conan.io/en/latest/installation.html )
  2. Add a reference to Jinja2C++ package (jinja2cpp/1.1.0) to your conanfile.txt, conanfile.py or CMakeLists.txt. For instance, with the usage of conan-cmake integration it could be written this way:
include (../../cmake/conan.cmake)
if (NOT MSVC)
    set (CONAN_SETTINGS SETTINGS compiler.libcxx=libstdc++11)
endif ()

conan_cmake_run(REQUIRES 
                    jinja2cpp/1.1.0
                    gtest/[email protected]/stable
                BASIC_SETUP
                ${CONAN_SETTINGS}
                OPTIONS 
                    jinja2cpp:shared=False
                    gtest:shared=False
                BUILD missing)
                
set (TARGET_NAME jinja2cpp_build_test)

add_executable (${TARGET_NAME} main.cpp)

target_link_libraries (${TARGET_NAME} ${CONAN_LIBS})
set_target_properties (${TARGET_NAME} PROPERTIES
            CXX_STANDARD 14
            CXX_STANDARD_REQUIRED ON)

Additional CMake build flags

You can define (via -D command-line CMake option) the following build flags:

  • JINJA2CPP_BUILD_TESTS (default TRUE) - to build or not to Jinja2C++ tests.
  • JINJA2CPP_STRICT_WARNINGS (default TRUE) - Enable strict mode compile-warnings(-Wall -Werror, etc).
  • JINJA2CPP_MSVC_RUNTIME_TYPE (default /MD) - MSVC runtime type to link with (if you use Microsoft Visual Studio compiler).
  • JINJA2CPP_DEPS_MODE (default "internal") - modes for dependency handling. Following values possible:
    • internal In this mode Jinja2C++ build script uses dependencies (include boost) shipped as subprojects. Nothing needs to be provided externally.
    • external-boost In this mode Jinja2C++ build script uses only boost as an externally-provided dependency. All other dependencies are taken from subprojects.
    • external In this mode all dependencies should be provided externally. Paths to boost, nonstd-* libs, etc. should be specified via standard CMake variables (like CMAKE_PREFIX_PATH or libname_DIR)
    • conan-build Special mode for building Jinja2C++ via conan recipe.

Build with C++17 standard enabled

Jinja2C++ tries to use standard versions of std::variant, std::string_view and std::optional if possible.

Acknowledgments

Thanks to @manu343726 for CMake scripts improvement, bug hunting, and fixing and conan.io packaging.

Thanks to @martinmoene for the perfectly implemented xxx-lite libraries.

Thanks to @vitaut for the amazing text formatting library.

Thanks to @martinus for the fast hash maps implementation.

Changelog

Version 1.1.0

Changes and improvements

  • batch filter added
  • slice filter added
  • format filter added
  • tojson filter added
  • striptags filter added
  • center filter added
  • xmlattr filter added
  • raw/endraw tags added
  • repeat string operator added (e. g. 'a' * 5 will produce 'aaaaa')
  • support for templates metadata (meta/endmeta tags) added
  • -fPIC flag added to Linux build configuration

Fixed bugs

  • Fix behavior of lstripblock/trimblocks global settings. Now it fully corresponds to the origina jinja2
  • Fix bug with rendering parent block content if child doesn't override this block
  • Fix compilation issues with user-defined callables with number of arguments more than 2
  • Fix access to global Jinja2 functions from included/extended templates
  • Fix point of evaluation of macro params
  • Fix looping over the strings
  • Cleanup warnings

Breaking changes

  • From now with C++17 standard enabled Jinja2C++ uses standard versions of types variant, string_view and optional

Version 1.0.0

Changes and improvements

  • default attribute added to the map filter (#48)
  • escape sequences support added to the string literals (#49)
  • arbitrary ranges, generated sequences, input iterators, etc. now can be used with GenericList type (#66)
  • nonstd::string_view is now one of the possible types for the Value
  • filter tag support added to the template parser (#44)
  • escape filter support added to the template parser (#140)
  • capitalize filter support added to the template parser (#137)
  • the multiline version of set tag added to the parser (#45)
  • added built-in reflection for nlohmann JSON and RapidJSON libraries (#78)
  • loop.depth and loop.depth0 variables support added
  • {fmt} is now used as a formatting library instead of iostreams
  • robin hood hash map is now used for internal value storage
  • rendering performance improvements
  • template cache implemented in TemplateEnv
  • user-defined callables now can accept global context via *context special param
  • MinGW, clang >= 7.0, XCode >= 9, gcc >= 7.0 are now officially supported as a target compilers (#79)

Fixed bugs

  • Fixed pipe (|) operator precedence (#47)
  • Fixed bug in internal char <-> wchar_t converter on Windows
  • Fixed crash in parsing endblock tag
  • Fixed scope control for include and for tags
  • Fixed bug with macros call within expression context

Breaking changes

  • MSVC runtime type is now defined by JINJA2CPP_MSVC_RUNTIME_TYPE CMake variable

Version 0.9.2

Major changes

Minor changes

  • Render-time error handling added
  • Dependency management mode added to the build script
  • Fix bugs with error reporting during the parse time
  • Upgraded versions of external dependencies

Breaking changes

  • RenderAsString method now returns nonstd::expected instead of regular std::string
  • Templates with import, extends and include generate errors if parsed without TemplateEnv set
  • Release bundles (archives) are configured with external dependency management mode by default

Version 0.9.1

  • applymacro filter added which allows applying arbitrary macro as a filter
  • dependencies to boost removed from the public interface
  • CMake scripts improved
  • Various bugs fixed
  • Improve reflection
  • Warnings cleanup

Version 0.9

  • Support of 'extents'/'block' statements
  • Support of 'macro'/'call' statements
  • Rich error reporting
  • Support for recursive loops
  • Support for space control before and after control blocks
  • Improve reflection

Version 0.6

Owner
Jinja2C++ project
Jinja2 template engine port for the C++ world
Jinja2C++ project
Comments
  • Error when running

    Error when running "cmake --build . --target all" (actually it's --target ALL_BUILD)

    [Note: When I build Jinja2Cpp project files for VS2017, the project files include ALL_BUILD.vcxproj and INSTALL.vcxproj; there's no "install.vcxproj" or "all.vcxproj"; running the command cmake --build . --target install gave an error saying that there's no file called "all.vcxproj".]

    When I ran the command cmake --build . --target ALL_BUILD, it seemed to run fine and was building it, but then it tried to find and link against libboost_filesystem-vc141-mt-gd-1_64.lib and stopped with a linker error. Is there a way to fix this? Also, is there a way to tell it to use my existing Boost 1.68.0 installation (since it should be able to find and use that easily if configured (right?))?

    Also, I want to generate code for both debug and release configurations. What CMake flags should I use for that?

  • Strange

    Strange "Incomplete type" error

    I got this error when trying to compile my code using g++ on my Bionic Beaver VM (I decided I'll try to compile the code directly on there and then put the executable into the Dockerfile):

    In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                     from /usr/include/c++/7/bits/char_traits.h:39,
                     from /usr/include/c++/7/string:40,
                     from /usr/local/boost_1_68_0/boost/utility/string_view_fwd.hpp:21,
                     from /usr/local/boost_1_68_0/boost/utility/string_view.hpp:22,
                     from /usr/local/boost_1_68_0/boost/beast/core/string.hpp:15,
                     from /usr/local/boost_1_68_0/boost/beast/core/file_base.hpp:14,
                     from /usr/local/boost_1_68_0/boost/beast/core/type_traits.hpp:14,
                     from /usr/local/boost_1_68_0/boost/beast/core/bind_handler.hpp:14,
                     from /usr/local/boost_1_68_0/boost/beast/core.hpp:15,
                     from currency_converter.cpp:17:
    /usr/include/c++/7/bits/stl_pair.h: In instantiation of ‘struct std::pair<const std::__cxx11::basic_string<char>, jinja2::Value>’:
    /usr/include/c++/7/ext/aligned_buffer.h:85:34:   required from ‘struct __gnu_cxx::__aligned_buffer<std::pair<const std::__cxx11::basic_string<char>, jinja2::Value> >’
    /usr/include/c++/7/bits/hashtable_policy.h:248:43:   required from ‘struct std::__detail::_Hash_node_value_base<std::pair<const std::__cxx11::basic_string<char>, jinja2::Value> >’
    /usr/include/c++/7/bits/hashtable_policy.h:279:12:   required from ‘struct std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, jinja2::Value>, true>’
    /usr/include/c++/7/bits/hashtable_policy.h:2007:60:   required from ‘struct std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, jinja2::Value>, true> > >’
    /usr/include/c++/7/bits/hashtable.h:173:11:   required from ‘class std::_Hashtable<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, jinja2::Value>, std::allocator<std::pair<const std::__cxx11::basic_string<char>, jinja2::Value> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char> >, std::hash<std::__cxx11::basic_string<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >’
    /usr/include/c++/7/bits/unordered_map.h:104:18:   [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
    /usr/include/c++/7/type_traits:1129:12:   required from ‘struct std::is_constructible<nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value>, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> > >, const nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > >, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > > >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > > > >&>’
    /usr/include/c++/7/type_traits:1141:12:   required from ‘struct std::__is_copy_constructible_impl<nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value>, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> > >, true>’
    /usr/include/c++/7/type_traits:1147:12:   required from ‘struct std::is_copy_constructible<nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value>, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> > > >’
    /usr/include/c++/7/type_traits:2977:25:   required from ‘constexpr const bool std::is_copy_constructible_v<nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value>, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char>, jinja2::Value> > > >’
    /usr/include/c++/7/variant:890:3:   required from ‘class std::variant<jinja2::EmptyValue, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, long int, double, nonstd::vptr::value_ptr<std::vector<jinja2::Value, std::allocator<jinja2::Value> >, nonstd::vptr::detail::default_clone<std::vector<jinja2::Value, std::allocator<jinja2::Value> > >, std::default_delete<std::vector<jinja2::Value, std::allocator<jinja2::Value> > > >, nonstd::vptr::value_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > >, nonstd::vptr::detail::default_clone<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > > >, std::default_delete<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, jinja2::Value> > > > >, jinja2::GenericList, jinja2::GenericMap, std::function<jinja2::Value(const jinja2::FunctionCallParams&)> >’
    /usr/local/Jinja2Cpp/include/jinja2cpp/value.h:190:15:   required from here
    /usr/include/c++/7/bits/stl_pair.h:204:11: error: ‘std::pair<_T1, _T2>::second’ has incomplete type
           _T2 second;                /// @c second is a copy of the second object
    

    Should I just add the backtrace limit like it says, or can this be fixed in a different way? It seems to be an error from the standard library files, which is strange to me.

    This is the compilation command I used:

    g++ -std=c++17 -Wall -pedantic -I /usr/local/Jinja2Cpp/include -I /usr/local/Jinja2Cpp/thirdparty/nonstd/value-ptr-lite/include -I /usr/local/Jinja2Cpp/thirdparty/nonstd/variant-light/include -I /usr/local/Jinja2Cpp/thirdparty/nonstd/expected-light/include -I /usr/local/boost_1_68_0/ -I /usr/local/json/single_include/ -L /usr/local/Jinja2Cpp/build/ -llibjinja2cpp.* -L /usr/local/boost_1_68_0/stage/lib/ -llibboost_system.* currency_converter.cpp -o currency_converter
    
  • Support for 'urlencode' filter

    Support for 'urlencode' filter

    Add support for 'urlencode' filter in order to such kind of templates could be processed:

    <!DOCTYPE html>
    <html lang="en-us">
    <head>
        <meta name="author" content="Osman Zakir" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta charset="utf-8" />
        <link href="resources/mystyles.css" rel="stylesheet" />
        <script src="resources/scripts-bundle.js" async defer></script>
        <script async defer src="https://maps.googleapis.com/maps/api/js?key={{apikey | urlencode}}&callback=init_map"></script>
        <title>DragonOsman Currency Converter</title>
    </head>
    <body>
        <div id="map"></div>
    </body>
    </html>
    

    The sample is provided by @DragonOsman .

  • Support for arbitrary range types

    Support for arbitrary range types

    first of all, tag this as "feature-request" "discussion" etc, for the first time I'm not coming here with a bug report :P

    I've been thinking about reflecting any kind of iterable range type. By range I mean any type where calls to std::begin() and std::end() are valid.

    I see two advantages of implementing that interface:

    • Out of the box support for any container: As long as you're doing a foreach loop (which is the case in most of the template loops) it works. Of course we could provide a fake size() method that does std::distance(), for the uncommon case an user applies a length filter on the range.

    • Lazy ranges: This could be a game changer. By accepting arbitrary range types users could pass lazy ranges to the template, which means true zero-copy API binding. In my case, with @foonathan's cppast, a coroutine range implementing the AST visit comes to my mind.

  • Interest in boost port to cmake

    Interest in boost port to cmake

    Hi,

    Recently I forked your project to use boost-cmake as aubmodule. Boost-cmake is a full port of boost to cmake, with one cmake target per boost lib. I've also forked boost-cmake to ensure only the required libraries are configured.

    Both forks are working (except unit tests) and I'm already using them for my project.

    I would like to know if you would be interested in adopting this boost-cmake aubmodule into your project, so Jinja2Cpp no longer relies on system dependencies (the main reason why I patched your library).

  • Release 1.2.0

    Release 1.2.0

    @rmorozov

    • Latest Release 1.1.0 is dated Jan, 2020
    • Do you think we could make an official release for 1.2.0? We'll try that RC to make it to Conan Center too...

    FYI @danielmartinezruiz @league55

  • reflected entity use-after-free

    reflected entity use-after-free

    I've found an use after free from the template engine. When referencing a variable from the template, the engine is returning a reference to a reflected object that's already been destroyed/released.

    The situation is as follows:

    • cppast AST nodes are passed to Jinja2Cpp engine as entity_refs, which are objects with references to the nodes (Just a wrapper of the cppast reference). entity_refs is what is jinja2::Reflected. @foonathan confirmed that holding references to AST nodes is safe since those live in the parser (So as long as the parser has the same scope as the template engine, which is the case, it works).
    • Templates are fed by only one variable "file", which is an entity_ref to the cppast::cpp_file node returned by the cppast parser. In case there were scoping issues, I made sure that my test fixture has the parser, the returned cppast node ref, the entity_ref, and the jinja2::ValuesMap where "file"` is assigned at the same scope (The fixture object).
    • All reflected properties are on-demand calls to cppast, no caching is done from my side. When a property refers to multiple entities (Such as a list of function arguments for example) a std::vector<entity_ref<Node>> is returned with references to all the nodes matching the AST walk. This vector is automatically exposed by jinja2cpp as a list in the template engine.
    • A test instances this template: {{file.classes[0].name}}. That asks "file" global object for all classes in the file AST, which as explained above does an AST search and returns a vector of references to cppast::cpp_class nodes. Then the engine takes the first element ([0]) and asks for its name, that property being implemented as a call to cppast::cpp_class::name() which returns an std::string. The file has at least four classes, so the list has at least 4 elements (There's a previous test to ensure that).
    • When accessing the entity_ref to get the class node to call name() method both valgrind and ASAN report an invalid read. To check if this is an use after free case, I added a boolean variable _destroyed to the entity_ref class, which is set to false by default and set to true in the destructor. Added an assertion in the function accessing the cppast node object (entity_ref::entity()) to test if the template is attempting to access an entity_ref that has been destroyed. This assertion fails.

    Here's a full capture of the catch2 + valgrind output of the test: logs.txt

  • Compilation in C++17 under MinGW on Windows 10

    Compilation in C++17 under MinGW on Windows 10

    I want to compile the library and use it as source. I have no CMakeLists.txt for my project and I am just using just make to compile it.

    BUT I'm using C++17 and I'm not able to compile Jinja2Cpp in C++17.

    1. Can you provide detailed instructions how to do it? I tried to put the variable from instruction in the section about C++17 in the cmake command and -D parameter and ... nothing.

    2. Also I'd like to know what flags should I add to my compile command (for my project I mean) to use all the staff provided by Jinja2Cpp

    Thank you in advance. 😄

    P.S.: I'm on Windows 10 and I'm using MinGW (8.1.0) as C/C++ compiler. I'm also doing the command-line staff (make/cmake commands) under git bash (means I'm using the Linux shell syntax) P.S.2: I wanted to help you via pull request about how to compile with Windows & MinGW but I'm so far away from CMake configs and it was so hard for me to change anything in the configs in a way that has even a small chance to work.

  • Use cmake to handle thirdparty deps

    Use cmake to handle thirdparty deps

    Long story short: I hate git submodules. They're a pain to keep up to date, to touch, and generate issues when merging different branches.

    I propose removing the submodules and using CMake instead to download the dependencies. There are two options:

    • DownloadProject.cmake: This is a cmake module that implements git project download at configure time. After the download command you can add_subdirectory() the downloaded project source dir as if it was part of your project. See here and here for an example of usage (That's how tinyrefl downloads thirdparty deps).
    • CMake FetchContent module: That's an standard cmake module very similar to (I don't know if it was inspired from) DownloadProject. This module is shipped with CMake >= 3.11, so using it would require Jinja2Cpp to require cmake >= 3.11.

    Why?

    • Updating dep sources is simple: Just go to your cmake config and change the url, git tag, etc.
    • Sources can be externally configured by the user: You can parameterize every dep source url and version, so that users can override your default config. I did this with tinyrefl to allow me point some dependencies to our in-house git mirrors at work.
    • No recursive clone is needed: CMake ensures dependencies are always set up.
    • Integration with package managers is much simpler: Since this uses cmake to handle deps, in the future adapting the library to support package managers and use this package managers to get lib dependencies could be just an if() in the dependencies cmake script:
      if(NOT JINJA2CPP_USING_CONAN)
          downloadproject(...)
          ...
      else()
          include(conanbuildinfo.cmake)
          set(dependencies ${CONAN_LIBS})
      endif()
      

    while at the same time we could keep the cmake deps download for backwards compatibility (i.e. Don't make Jinja2Cpp unusable without conan etc).

  • Unresolved external MemoryFileSystem::GetLastModificationDate

    Unresolved external MemoryFileSystem::GetLastModificationDate

    Hi,

    I finally found some time to play with Jinja2Cpp but not I'm struggling with this issue.

    >jinja2Templates.test.obj : error LNK2001: unresolved external symbol "public: virtual class std::optional<class std::chrono::time_point<struct std::chrono::system_clock,class std::chrono::duration<__int64,struct std::ratio<1,10000000> > > > __thiscall jinja2::MemoryFileSystem::GetLastModificationDate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " ([email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@@@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z)
    1>..\..\GeneratedFiles\Debug32\\axLibrariesLib.dll : fatal error LNK1120: 1 unresolved externals
    

    Still not sure why but MemoryFileSystem::GetLastModificationDate is marked as unresolved external.

    This few lines produce it:

    jinja2::MemoryFileSystem mfs;
    jinja2::TemplateEnv env;
    env.AddFilesystemHandler("", mfs);`
    
    

    It's strange because RealFileSystem works:

    jinja2::RealFileSystem mfs;
    jinja2::TemplateEnv env;
    env.AddFilesystemHandler("", mfs);`
    
    

    and I don't see any difference in Jinja2 source code which could cause this.

    Do you have any idea what can cause it?

  • jinja2::MakeCallable has compilation error when number of arguments > 3

    jinja2::MakeCallable has compilation error when number of arguments > 3

    Example : oTemplateEnv->AddGlobal("urlize", jinja2::MakeCallable( [](const std::string &urlLink, const std::string &labelName, const int &limitWord, const std::string &targetStr) { return urlLink; }, jinja2::ArgInfo{"urlLink"}, jinja2::ArgInfo{"labelName"}, jinja2::ArgInfo{"limitWord", false, 0}, jinja2::ArgInfo{"targetStr", false, ""}));

    Compile: g++: internal compiler error: Killed (program cc1plus)

  • Bug in 'reverse' filter

    Bug in 'reverse' filter

        std::vector<std::string> foundTypes;
        jinja2::ValuesMap renderParams = 
        {   { "specTypes"    , jinja2::Reflect(&foundTypes)  }
        };
    // ...
    
        if (...)
        {
            foundTypes = ...
            renderParams["specTypes"] = jinja2::Reflect(&foundTypes);
        }
    

    Also, simple jinja makes the same effect:

    {{ [3, 1, 2] | reverse }}
    

    produces the bad_expected_access exception, which inspired by std::bad_alloc exception

    // filters.cpp:452
    InternalValue SequenceAccessor::Filter(const InternalValue& baseVal, RenderContext& context)
    //...
    // filters.cpp:479
    listSize = {has_value_=true (0x34) contained={data={_Val=6.951334341138e-310#DEN _Pad=0x000000750f548880 "\x1ЉGyц" } } }
    // 0x34 - 52 - size of my data vector
    // requested size: size = 0x00007ff679478a01
    // hex representation of 6.951334341138e-310 double is 0x00007ff679478a01
    
  • Missing debug info for MSVC static lib

    Missing debug info for MSVC static lib

    CMakeLists.txt

    --original

    if (JINJA2CPP_BUILD_SHARED)
        set(LIB_LINK_TYPE SHARED)
        message(STATUS "Jinja2C++ library type: SHARED")
    else()
        set(LIB_LINK_TYPE STATIC)
        message(STATUS "Jinja2C++ library type: STATIC")
    endif()
    

    --fixed

    if (JINJA2CPP_BUILD_SHARED)
        set(LIB_LINK_TYPE SHARED)
        message(STATUS "Jinja2C++ library type: SHARED")
    else()
        set(LIB_LINK_TYPE STATIC)
        message(STATUS "Jinja2C++ library type: STATIC")
        if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
            set(MSVC_CXX_FLAGS ${MSVC_CXX_FLAGS} /Z7)
        endif()
    endif()
    
  • Add boost::json as an alternative to rapidjson

    Add boost::json as an alternative to rapidjson

    This is a feature request to add boost::json as an alternative to rapidjson/nlohmann. The boost::json API is actually quite similar to rapidjson, in many cases the code is the same but the method names are snake-case like .is_array() instead of camel-case like rapidjson's .IsArray().

    Also it would be nice to be able to build Jinja2Cpp without any JSON support at all.

  • Have Problem Building Current Version of Library With VS2019

    Have Problem Building Current Version of Library With VS2019

    I ran CMake on the command line with this command:

    cmake .. -DCMAKE_INSTALL_PREFIX=../install -G "Visual Studio 16 2019" -A x64 -DCMAKE_CXX_STANDARD=17 -DJINJA2CPP_CXX_STANDARD=17 -DJINJA2CPP_DEPS_MODE=external-boost -DJINJA2CPP_MSVC_RUNTIME_TYPE=/MT -DCMAKE_CXX_FLAGS=/EHsc -DCMAKE_BUILD_TYPE=Release
    

    and had this output:

    -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
    -- Jinja2Cpp C++ standard: 17
    -- Selected MSVC runtime type for Jinja2C++ library: '/MT'
    -- Jinja2C++ library type: STATIC
    -- Selected Jinja2C++ thirdparty libraries runtime type: '/MT'
    -- 'extnernal-boost' dependencies mode selected for Jinja2Cpp. All dependencies are used as submodules except of boost
    -- Project 'expected_lite', package 'expected-lite' version: '0.3.0'
    -- Project 'variant_lite', package 'variant-lite' version: '1.2.2'
    -- Project 'optional_lite', package 'optional-lite' version: '3.2.0'
    -- Project 'string_view_lite', package 'string-view-lite' version: '1.3.0'
    -- Version: 6.1.2
    -- Build type: Release
    -- CXX_STANDARD: 17
    CMake Warning (dev) at thirdparty/json/rapid/CMakeLists.txt:12 (PROJECT):
      Policy CMP0048 is not set: project() command manages VERSION variables.
      Run "cmake --help-policy CMP0048" for policy details.  Use the cmake_policy
      command to set the policy and suppress this warning.
    
      The following variable(s) would be set to empty:
    
        PROJECT_VERSION
        PROJECT_VERSION_MAJOR
        PROJECT_VERSION_MINOR
        PROJECT_VERSION_PATCH
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- RapidJSON found. Headers: C:/Jinja2Cpp/thirdparty/json/rapid/include
    -- Using the multi-header code from C:/Jinja2Cpp/thirdparty/json/nlohmann/include/
    CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:273 (message):
      The package name passed to `find_package_handle_standard_args` (GTest) does
      not match the name of the calling package (gtest).  This can lead to
      problems in calling code that expects `find_package` result variables
      (e.g., `_FOUND`) to follow a certain pattern.
    Call Stack (most recent call first):
      C:/Program Files/CMake/share/cmake-3.18/Modules/FindGTest.cmake:205 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
      thirdparty/CMakeLists.txt:47 (find_package)
      CMakeLists.txt:172 (include)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
    -- gtest not found, using submodule
    -- infix: EXPECTED-LITE target: expected-lite
    -- infix: VARIANT-LITE target: variant-lite
    -- infix: OPTIONAL-LITE target: optional-lite
    -- infix: STRING-VIEW-LITE target: string-view-lite
    -- Configuring done
    -- Generating done
    -- Build files have been written to: C:/Jinja2Cpp/build
    

    Then when I tried to build it, I had some errors:

    cmake --build . --target all_build --config Release
    Microsoft (R) Build Engine version 16.7.0+b89cb5fde for .NET Framework
    Copyright (C) Microsoft Corporation. All rights reserved.
    
      Checking Build System
      Building Custom Rule C:/Jinja2Cpp/CMakeLists.txt
      Building Custom Rule C:/Jinja2Cpp/CMakeLists.txt
      error_info.cpp
      expression_evaluator.cpp
      expression_parser.cpp
      filesystem_handler.cpp
      filters.cpp
      internal_value.cpp
      lexer.cpp
      rapid_json_serializer.cpp
      serialize_filters.cpp
      statements.cpp
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1464,1): error C2039: 'type': is not a member
    of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(151): messa
    ge : see declaration of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(819): messa
    ge : see reference to class template instantiation 'nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImp
    l<char>>,jinja2::ErrorInfo>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to class template instantiation 'std::is_trivially_destructible<nonstd::expected_lite::expected<std::sha
    red_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to variable template 'const bool conjunction_v<std::is_trivially_destructible<jinja2::EmptyValue>,std::i
    s_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char> >,jinja2::ErrorInfo
    Tpl<char> > >,std::is_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar
    _t> >,jinja2::ErrorInfoTpl<wchar_t> > > >' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(1011): message
    : see reference to alias template instantiation 'std::_Variant_destroy_layer<jinja2::EmptyValue,nonstd::expected_lite::
    expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expected_lite::expected<std::shared_ptr
    <jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(275): message : see reference to class template instantiation 'std::variant<jinja2::Em
    ptyValue,nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expecte
    d_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\buil
    d\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(398): message : see reference to class template instantiation 'jinja2::TemplateImpl<Ch
    arT>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,1): error C3646: 'swap': unknown override
     specifier [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,9): error C2059: syntax error: '(' [C:\Ji
    nja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1474,1): error C2334: unexpected token(s) prec
    eding '{'; skipping apparent function body [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
      string_converter_filter.cpp
      template.cpp
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1464,1): error C2039: 'type': is not a member
    of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(151): messa
    ge : see declaration of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(819): messa
    ge : see reference to class template instantiation 'nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImp
    l<char>>,jinja2::ErrorInfo>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to class template instantiation 'std::is_trivially_destructible<nonstd::expected_lite::expected<std::sha
    red_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to variable template 'const bool conjunction_v<std::is_trivially_destructible<jinja2::EmptyValue>,std::i
    s_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char> >,jinja2::ErrorInfo
    Tpl<char> > >,std::is_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar
    _t> >,jinja2::ErrorInfoTpl<wchar_t> > > >' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(1011): message
    : see reference to alias template instantiation 'std::_Variant_destroy_layer<jinja2::EmptyValue,nonstd::expected_lite::
    expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expected_lite::expected<std::shared_ptr
    <jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(275): message : see reference to class template instantiation 'std::variant<jinja2::Em
    ptyValue,nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expecte
    d_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\buil
    d\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(398): message : see reference to class template instantiation 'jinja2::TemplateImpl<Ch
    arT>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,1): error C3646: 'swap': unknown override
     specifier [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,9): error C2059: syntax error: '(' [C:\Ji
    nja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1474,1): error C2334: unexpected token(s) prec
    eding '{'; skipping apparent function body [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
      template_env.cpp
      template_parser.cpp
      testers.cpp
      value.cpp
      Generating Code...
      Building Custom Rule C:/Jinja2Cpp/thirdparty/gtest/googletest/CMakeLists.txt
      gtest-all.cc
      gtest.vcxproj -> C:\Jinja2Cpp\build\thirdparty\gtest\googlemock\gtest\Release\gtest.lib
      Building Custom Rule C:/Jinja2Cpp/thirdparty/gtest/googletest/CMakeLists.txt
      gtest_main.cc
      gtest_main.vcxproj -> C:\Jinja2Cpp\build\thirdparty\gtest\googlemock\gtest\Release\gtest_main.lib
    

    I also tried building INSTALL.vcxproj after this since it seemed like some stuff got built, but no dice. It didn't even create a folder called "install". Build result:

    cmake --build . --target install --config Release
    Microsoft (R) Build Engine version 16.7.0+b89cb5fde for .NET Framework
    Copyright (C) Microsoft Corporation. All rights reserved.
    
      statements.cpp
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1464,1): error C2039: 'type': is not a member
    of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(151): messa
    ge : see declaration of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(819): messa
    ge : see reference to class template instantiation 'nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImp
    l<char>>,jinja2::ErrorInfo>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to class template instantiation 'std::is_trivially_destructible<nonstd::expected_lite::expected<std::sha
    red_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to variable template 'const bool conjunction_v<std::is_trivially_destructible<jinja2::EmptyValue>,std::i
    s_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char> >,jinja2::ErrorInfo
    Tpl<char> > >,std::is_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar
    _t> >,jinja2::ErrorInfoTpl<wchar_t> > > >' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(1011): message
    : see reference to alias template instantiation 'std::_Variant_destroy_layer<jinja2::EmptyValue,nonstd::expected_lite::
    expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expected_lite::expected<std::shared_ptr
    <jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(275): message : see reference to class template instantiation 'std::variant<jinja2::Em
    ptyValue,nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expecte
    d_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\buil
    d\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(398): message : see reference to class template instantiation 'jinja2::TemplateImpl<Ch
    arT>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,1): error C3646: 'swap': unknown override
     specifier [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,9): error C2059: syntax error: '(' [C:\Ji
    nja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1474,1): error C2334: unexpected token(s) prec
    eding '{'; skipping apparent function body [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
      template.cpp
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1464,1): error C2039: 'type': is not a member
    of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(151): messa
    ge : see declaration of 'std::enable_if<false,void>' [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\type_traits(819): messa
    ge : see reference to class template instantiation 'nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImp
    l<char>>,jinja2::ErrorInfo>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to class template instantiation 'std::is_trivially_destructible<nonstd::expected_lite::expected<std::sha
    red_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(956): message :
     see reference to variable template 'const bool conjunction_v<std::is_trivially_destructible<jinja2::EmptyValue>,std::i
    s_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char> >,jinja2::ErrorInfo
    Tpl<char> > >,std::is_trivially_destructible<nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar
    _t> >,jinja2::ErrorInfoTpl<wchar_t> > > >' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\variant(1011): message
    : see reference to alias template instantiation 'std::_Variant_destroy_layer<jinja2::EmptyValue,nonstd::expected_lite::
    expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expected_lite::expected<std::shared_ptr
    <jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(275): message : see reference to class template instantiation 'std::variant<jinja2::Em
    ptyValue,nonstd::expected_lite::expected<std::shared_ptr<jinja2::TemplateImpl<char>>,jinja2::ErrorInfo>,nonstd::expecte
    d_lite::expected<std::shared_ptr<jinja2::TemplateImpl<wchar_t>>,jinja2::ErrorInfoW>>' being compiled [C:\Jinja2Cpp\buil
    d\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\src\template_impl.h(398): message : see reference to class template instantiation 'jinja2::TemplateImpl<Ch
    arT>' being compiled [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,1): error C3646: 'swap': unknown override
     specifier [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1469,9): error C2059: syntax error: '(' [C:\Ji
    nja2Cpp\build\jinja2cpp.vcxproj]
    C:\Jinja2Cpp\thirdparty\nonstd\expected-lite\include\nonstd/expected.hpp(1474,1): error C2334: unexpected token(s) prec
    eding '{'; skipping apparent function body [C:\Jinja2Cpp\build\jinja2cpp.vcxproj]
      Generating Code...
      gtest.vcxproj -> C:\Jinja2Cpp\build\thirdparty\gtest\googlemock\gtest\Release\gtest.lib
      gtest_main.vcxproj -> C:\Jinja2Cpp\build\thirdparty\gtest\googlemock\gtest\Release\gtest_main.lib
    

    Any help is appreciated. Thanks.

📘 MIPT University - Olympiad School of Competitive Programming (C++) Curated repository with full explanations, solutions & written lectures collected throughout my academic experience at MIPT school

MIPT - Olympiad School of Competitive Programming (with C++) Outcomes: Studying at this school has allowed be to explore numerous algorithms, data str

Nov 24, 2021
A custom,multifunctional class template for arrays which supports lambda functions for removing and selecting

C++ Array Template Class This is an implementation of a template class for storing data in any type.It includes user-friendly interface with lots of h

Dec 8, 2021
Love template metaprogramming

Metal Metal is a single-header C++11 library designed to make you love template metaprogramming. Overview #include <metal.hpp> // First we need some

Dec 3, 2022
LRU implementation exercises
LRU implementation exercises

LRU implementation exercises

Jul 3, 2022
Implementation using C in programming lab class when being Teacher Assistant.

C Programming Lab Implementation using C in programming lab class when being Teacher Assistant. The problems are here Problems and Description Week2 w

Aug 16, 2022
Implementation of kcp protocol based on c++11
Implementation of kcp protocol based on c++11

?? kcp-cpp A C++11 header-only kcp library,It has been heavily optimized to support native heartbeat packets and multithreading There are a lot of ins

Oct 25, 2022
Imu_initialization - Implementation of "An Analytical Solution to the IMU Initialization Problem for Visual-Inertial Systems"

An Analytical Solution to the IMU Initialization Problem for Visual-Inertial Systems Implementation of "An Analytical Solution to the IMU Initializati

Nov 23, 2022
wideint is a C++ implementation of wide exact-width integer types.

wideint - wide exact-width integer types Copyright (c) 2022 Joergen Ibsen About wideint is a C++ implementation of wide exact-width integer types. #in

Jan 27, 2022
The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++
The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++

The C++ Core Guidelines are a collaborative effort led by Bjarne Stroustrup, much like the C++ language itself. They are the result of many person-years of discussion and design across a number of organizations. Their design encourages general applicability and broad adoption but they can be freely copied and modified to meet your organization's needs.

Dec 5, 2022
Welcome to my dungeon. Here, I keep all my configuration files in case I have a stroke and lose all my memory. You're very welcome to explore and use anything in this repository. Have fun!

Fr1nge's Dotfiles Welcome to my dungeon. Here, I keep all my configuration files in case I have a stroke an d lose all my memory. You're very welcome

Oct 28, 2022
This repository contains notes and starter code for Bit manipulation and mathematics session for DSA bootcamp organized by Codeflows.

Bitmanipulation_maths This repository contains notes and starter code for Bit manipulation and mathematics session for DSA bootcamp organized by Codef

Jun 15, 2022
cpp fundamentals and questions for beginners and intermediates
cpp fundamentals and questions for beginners and intermediates

DSA 60 days Hi people! So we have started grasping dsa concepts and solving problems from 12 July. And we shall continue till September 10 Starting fr

Nov 18, 2022
A demonstration of implementing, and using, a "type safe", extensible, and lazy iterator interface in pure C99.

c-iterators A demonstration of implementing, and using, a "type safe", extensible, and lazy iterator interface in pure C99. The iterable is generic on

Dec 2, 2022
About Write a program to create a circular doubly linked list and perform insertions and deletions of various cases

Write a program to create a circular doubly linked list and perform insertions and deletions of various cases Circular Doubly Linked List Circular Dou

Aug 28, 2021
This repository aims to solve and create new problems from different spheres of coding. A path to help students to get access to solutions and discuss their doubts.

CPP-Questions-and-Solutions ?? This repository aims to solve and create new problems from different spheres of coding, which will serve as a single po

Oct 3, 2022
The Repository Contains all about Data Structure and Algorithms with Practice problems, series, and resources to follow!

?? The Complete DSA Preparation ?? This repository contains all the DSA (Data-Structures, Algorithms, 450 DSA by Love Babbar Bhaiya,STriver Series ,FA

Oct 6, 2022
Starting with OpenCV and Qt on MacOS is a bit of difficult if you haven't installed and used libraries in XCode.
Starting with OpenCV and Qt on MacOS is a bit of difficult if you haven't installed and used libraries in XCode.

OpenCV and Qt on MacOS Introduction Starting with OpenCV and Qt on MacOS is a bit of difficult if you haven't installed and used libraries in XCode. T

Oct 20, 2022
A place where you can learn and practise various Problems and algorithms
A place where you can learn and practise various Problems and algorithms

Problem-Solving Problem solving is an art of solving some real time challenges. And this is a place to get started, you can find many problems to solv

Apr 22, 2022
This repo is created to post all my codes and learning of C++ and DSA in C++

This is a readme file where you can read some documentaton about learning on c++and Data Structures and algorithms . I will be posting each and every

Jul 27, 2022