Skip to content
C++ Templates are turing complete - So why not make them usable in that way?
C++ Python
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
headerlib/hdr Switch to definition-less math values Oct 6, 2017
test
.gitignore
License
README.md Better formatting for code May 2, 2017
SConstruct Advance set implementation Sep 27, 2017
how_to_extract_subobjects.cpp Readme and c++17 features Feb 24, 2017
template-template-partial-specialization Shame on clang 4.0 for not doing the template template partial specia… Apr 21, 2017
timing

README.md

CppLibrary

A small library of my C++ stuff built upon my header library. The header library is meant to work similarly to the type meta programming part of Boost.Hana while alleviating some issues I had with it. The approach is a functional one, relying on template programming instead of constexpr object representation. It maps untyped lambda calculus with strict evaluation to structures available in C++-1z.

The code quality is not up to Boost.Hana yet but afterall I explore a completely new style of functional templating, sorry for the inconvenience. A very interesting aspect of the Boost library is the usefullness of its error messages which I can currently not even come close to. Debugging statements are rare (only tested for correctness by a couple of test cases) and "type type safety" is not enforced in any way.

Paradigm

The only first class citizen in headerlib are structs. Without free template parameters of any sort. It's is very complicated for functions in the template system to have side effects on the type system which is strong reasoning behind the functional approach of programming I chose for this library.

Several conversion methods from conventional template meta programming approaches to the one supported here exist, for easy of use. This is by design, the user should be able to incorporate his own style and methods of MTP while being offered the full depth and power the library has to offer.

// Transforming a template from std in one line
using add_ptr = TypeFunction<::std::add_pointer>;

Building

Make sure to have clang-4.0 installed on your system and at least gcc-libs version 6 (I may try to remove all std dependencies of core in future releases). Then you can simply run

scons

Otherwise, any compilter compatible to c++ draft n4659 should work, you can specify it as follows:

CXX=<compiler> scons

Note that gcc-7.1 is not compatible at the moment.

Advantages

Let's look at an example as a comparison from Boost.Hana about eval_if coding the factorial function adapted for c++17 from here

template<typename N>
constexpr auto ffactorial(const N n) {
    return hana::eval_if(hana::equal(n, hana::int_c<0>),
        [] () constexpr { return hana::int_c<1>; },
        [=](auto _) constexpr { return hana::mult(n, fact(hana::minus(_(n), hana::int_c<1>))); }
    );
}
constexpr auto res = ffactorial(hana::int_c<5>);

There are several negative points made in the documentation and it's just as bad when using it to dynamically determining a typename. But you know how to code the same function with template specialization already. That's where this library comes in.

template<int n> struct factorial {
  constexpr static const int value = n*factorial<n-1>::value;
};
template<> struct factorial<0> {
  constexpr static const int value = 1;
};
constexpr auto res = hdr::Apply<hdr::ValueTemplateFunction<factorial>, hdr::Signed<5>>::value;

To see this in action, see this file

Real world application

Consider building a parser program for a specific language. Several approaches to this problem have already been explored (e.g. YACC, CUP) but most suffer from a minor flaw: They generate the source files instead of being integrated into them, or their products suffer from the additional overhead of being generated at program runtime.

This can theoretically be tackled with this library. Take an existing parser generator in a functional language, such as Parsec and reformulate the well revised code for this library. Then one is able to make use of every standard conformant c++ compiler to generate a parser, fully contained within the source file. With a guarantee of being runtime-overhead free compared to a version generated by an external tooling with the same parser structure.

Should reflection (even as simple as N4428) be integrated into C++ one day, these two tools could fuse into a truly powerful machinery capable of fully replacing Qt-Moc in a way that every programmer can read and understand when he has knowledge about C++.

You can’t perform that action at this time.