Date Tags cpp

I previously discussed the mixin technique for C++, where layers are used to construct types from reusable classes. As the stacks of layers grow in size, it becomes tedious to pass arguments to the different layers. At first, I used a big struct to hold each an every argument I needed for the stack in question, which would look something like this:

// file: some_layer.hpp
template<class super>
class some_layer : public super
{
    uint32_t m_val;

  public:
    template<typename Args>
    some_layer(const Args &args) : super(args)
    {
        m_val = args.val;
    }
};

// file: mixin.cpp
#include "some_layer.hpp"
#include "other_layer.hpp"
#include "final_layer.hpp"

typedef some_layer<
        other_layer<
        final_layer
        >> my_stack;

struct args
{
    uint32_t val = 42;
} args;

int main(int argc, char **argv)
{
    my_stack ms(args);

    // ...

    return 0;
}

Although this approach is simple, it gets annoying when you need different sets of arguments for different stacks of layers - often within the same application. So how can we make this more flexible?

We use keyword arguments as we know it from python. What we want is something like this:

// ...
int main(int argc, char **argv)
{
    my_stack ms(val=42);

    // ...

    return 0;
}

Since this isn't available as a default feature of C++, a bit of magic is needed. Luckily enough, someone already did the hard work for us here.

By using the kwargs from Ross Smith, we can specify valid keywords in each layer, and pass values to them when constructing our stack object. The example from before then looks like this:

// file: some_layer.hpp
#include "kwargs.hpp"

const Kwarg<uint32_t> some_val;

template<class super>
class some_layer : public super
{
    uint32_t m_val;

  public:
    template<typename... Args>
    some_layer(const Args&... args) : super(args...)
    {
        kwget(some_val, m_val, args...);
    }
};

// file: mixin.cpp
#include "some_layer.hpp"
#include "other_layer.hpp"
#include "final_layer.hpp"

typedef some_layer<
        other_layer<
        final_layer
        >> my_stack;

int main(int argc, char **argv)
{
    my_stack ms(some_val=42);

    // ...

    return 0;
}

Which is exactly the semantics we wanted. Now, the examples above are not even compile tested, but I have updated the example from my previous post to use kwargs. It is available for download here.