Quickstart

After reading this guide you will know the foundations of the templatious library.

Templatious is a header only library, meaning, just add one directory to the include path and off you go.

When using templatious library you will be looking at the following three classes the most:

templatious::StaticAdapter
templatious::StaticFactory
templatious::StaticManipulator

Static Adapter

StaticAdapter is adapter for every collection or collection-like class. Well, not for every class. Treating collections universally is not magic. Templatious library achieves this universal treatment by specializing CollectionAdapter class for each instance it considers collection.

Example of specialization is similar to:

template <class T>
struct CollectionAdapter< std::vector<T> > {
...
};

This is example of specialization declaration for std::vector class. In fact CollectionAdapter is modelled mainly after std::vector.

However, writing things like:

std::vector<int> v;
typedef templatious::adapters::CollectionAdapter<
    std::vector<int> > Ad;

// following two lines do the same thing
v.push_back(7);
Ad::add(v,7);

Would not be convenient. So, StaticAdapter infers the type for user and he can write the following instead:

std::vector<int> v;
templatious::StaticAdapter::add(v,7);

So, basically, templatious::StaticAdapter is a basic interface for every collection which allows to do quite generic stuff.

Templatious specializes CollectionAdapter for the following (but not limited to):

  • static arrays
  • std::vector
  • std::list
  • custom templatious sequence class

To plug an arbitrary collection into the rich templatious ecosystem user would only need to specialize CollectionAdapter for his class (preferrably non-const and const versions). The interface is quite self-explanatory and can be viewed at templatious/CollectionAdapter.hpp header.

Static Factory

StaticFactory is mainly responsible making objects which belong to templatious. User doesn't have to remember all the classes he should use in this library (with only some exceptions), user can just expect that all the objects he will be instantiating are under StaticFactory class.

There are two benefits of this approach:

  • Only one class for making objects.
  • In 90% of the cases user is completely relieved of specifying template arguments for those classes and they are almost always inferred.

The user will very likely be using C++11 feature of auto keyword.

Consider this example for making a sequence class:

auto s = templatious::StaticFactory::seqL(10);

This creates a sequence containing elements from 0 to 9. User is completely relieved from specifying type. If he had to use an actual instance of template class he would have written:

templatious::SeqL<int> s(0,10,1);
// arguments for constructor - start, end, step

This benefit might seem funny in this toy example but this is actual class type of an object that gets created without user specifying a single template argument:

templatious::Skipper<
    templatious::Filter<
        templatious::SeqL<int, false>&&,
        main(int, char**)::__lambda0,
        templatious::util::DefaultStoragePolicy
    >&&,
    templatious::util::DefaultStoragePolicy
>

The upper type name was generated by the following code:

auto f = 
    SF::skip(
        SF::filter(
            SF::seqL(100),
            [](int i) { return i > 50; }
        ),
        2
    );

Thank you auto.

Static Manipulator

This class is responsible for manipulation of objects. Either collections, packs or other things in templatious ecosystem. For instance, StaticManipulator has a “quadro” function that allows loop in a loop traversals for arbitrary depth loops:

auto seq = templatious::StaticFactory::seqL(2);
// seq = [0,1]

templatious::StaticManipulator::quadro(
    [](int a,int b,int c,int d) {
        std::cout << a << b << c << d << std::endl;
    },
    seq,seq,seq,seq
);

Previous example prints:

0000
0001
0010
0011
...
1101
1110
1111

The trinity

Let's be honest, templatious::StaticAdapter is quite a long name to type. Therefore, templatious library has a built in macro which shortens the typing quite a bit - TEMPLATIOUS_TRIPLET_STD.

TEMPLATIOUS_TRIPLET_STD;
// expands to:
// typedef templatious::StaticAdapter SA;
// typedef templatious::StaticFactory SF;
// typedef templatious::StaticManipulator SM;


void func() {
    std::vector<int> v;

    SA::add(v,7);         // StaticAdapter
    auto s = SF::seqL(7); // StaticFactory
    SM::set(v,'7');       // StaticManipulator
}

So, after all this time, what headers should you include to start balling in your translation units?

There are two options…

  • You're lazy
  • You care about included text size

First option is the most convenient. The only include you need is:

#include <templatious/FullPack.hpp>

Now, this include includes all the three trinity classes, which themselves include the rest of the templatious classes. However, it also includes all STL container adapters… There will be compile time errors if we specialize std::list with adapter and compiler doesn't know what std::list is, so, adapters have to include the classes they specialize, meaning, if you include full pack you automatically include vector, list, forward_list and etc.

However, I found that this completely doesn't matter, as long as your compiled sources are small compilation is still quick, so, use this with caution.

Second option is less convenient but includes less:

#include <templatious/MainPack.hpp>

This only includes StaticAdapter, StaticFactory and StaticManipulator + Sugar header which contains some useful macros.

So, basically, this option includes everything FullPack would include but without the adapters - only the templatious headers (which include some commonly used std headers, but not all the collections like FullPack needs).

That's it, you can start blasting! The next recommended readings would be in did you ever write section.