Library introduction
There are several reasons why template metaprogramming is complex. One of them is that it's often presented at too low level. With such approach, before you can start to produce something useful in real life, you have to learn a lot of things that are not directly related to the problem you want to solve. You have to learn quite a few implementation techniques, clever tricks, subtle language details, and deficiencies of particular compilers you happened to work with, in order to implement something so conceptually clean that it can be expressed in one sentence. While such learning experience can definitely be fascinating, it also definitely not for everyone [1], and there are a lot of people for whom learning all these would be a time loss (for many reasons). If an analogy can help to demonstrate the point, we are sure that implementing red-black tree is a fascinating exercise too, yet you would have hard time convincing us that learning how to implement that useful data structure is a necessary step before a person can use std::map in her application code.
In other words, abstractions are as important in the unfamiliar world of template metaprogramming as they are in traditional run-time world, - if not more [2]. Rephrazing Andrew Koenig and Barbara Moo [KM00], if abstractions are well designed, well chosen, and well-known, we believe that we can use them even if we don't understand all the details of how they work. We do not need to be automotive engineers to drive a car, nor do we need to understand everything about C++ templates before we can use them in a new, exciting, and yet practical ways that will helps us to solve our everyday real-life programming problems better.
So, that's what this library is trying to do - to present template metaprogramming at a higher level, to provide a well-defined conceptual framework for many common tasks that template metaprograms solves, and to make metaprogramming more accessible and practical for real-life applications.
Metaprogramming is the activity of creating programs that manipulate other programs or themselves. Any program that takes (other) program as its input and produces (yet another) program as the result of its execution is an example of metaprogram. Compilers, interpreters, preprocessors and program generators are all examples of metaprograms. Metaprogramming is central to automating the process of building software; it helps to relieve the programmer from all repetitive and conceptually redundant operations, so that he may focus on the essence of programming, that is, on the problems that have never been solved yet.
Although is is possible, in almost any programming language, to create programs that manipulate other programs at runtime, there are few languages that support compile-time metaprogramming.
[1] It shouldn't come as surprise that a lot of real-life environments are task-oriented; that means that if in order to solve a problem in a way that would require you a half of the day to implement and than months to teach your co-workers to understand the solution, most likely this way won't be considered - even if such solution would be superior from a technical standpoint.
[2] Another source of seeming difficulty of template metaprogramming is that when you are building a compile-time (only) program, you are pretty much dealing with a different language - different from the one you used to know while programming "for a real world". The syntax is different, the implementation techniques are different, and, finally, the problems you are trying to solve by writing this program are different. While "unfamiliar" and "difficult" are not synonyms, reducing the seeming complexity of the task is the last thing unfamiliarity helps with, and one way to make template metaprogramming easy from that side is to reduce unfamiliarity - by introducing some appropriate and well-known abstractions.