Compile-time 'String' Manipulation with Variadic Templates

c++, c++11, metaprogramming, templates

Solution

If you just want to operate on one character at a time its easy:

template<char c> struct add_three {
    enum { value = c+3 };
};

template <char... Chars> struct EncryptCharsA {
    static const char value[sizeof...(Chars) + 1];
};

template<char... Chars>
char const EncryptCharsA<Chars...>::value[sizeof...(Chars) + 1] = {
    add_three<Chars>::value...
};

int main() {   
    std::cout << EncryptCharsA<'A','B','C'>::value << std::endl;
    // prints "DEF"
}

Note that `CountArgs` is redundant (that's what `sizeof...` is for) and that this uses element-wise transformation of the elements in a parameter-pack.

To make the transformation dependent on previous results, one option would be to consume the characters recursively, one at a time, and incrementally build a new template from that:

template<char... P> struct StringBuilder {
    template<char C> struct add_char {
        typedef StringBuilder<P..., C> type;
    };

    static const char value[sizeof...(P)+1];
};

template<char... P> const char StringBuilder<P...>::value[sizeof...(P)+1] = {
    P...
};

template<class B, char...> struct EncryptImpl;

template<class B, char Seed, char Head, char... Tail> 
struct EncryptImpl<B, Seed, Head, Tail...> {
    static const char next = Head + Seed; // or whatever
    typedef typename EncryptImpl<
        typename B::template add_char<next>::type,
        next, Tail...
    >::type type;
};

template<class B, char Seed> struct EncryptImpl<B, Seed> {
    typedef B type;
};

template<char... P> struct Encrypt {
    typedef typename EncryptImpl<StringBuilder<>, 0, P...>::type type;
};

Problem

Hey all, I'm currently trying to write a compile-time string encryption (using the words 'string' and 'encryption' quite loosely) lib. What I have so far is as follows: ``` // Cacluate narrow string length at compile-time template <char... ArgsT> struct CountArgs { template <char... ArgsInnerT> struct Counter; template <char Cur, char... Tail> struct Counter<Cur, Tail...> { static unsigned long const Value = Counter<Tail...>::Value + 1; }; template <char Cur> struct Counter<Cur> { static unsigned long const Value = 1; }; static unsigned long const Value = Counter<ArgsT...>::Value; }; // 'Encrypt' narrow string at compile-time template <char... Chars> struct EncryptCharsA { static const char Value[CountArgs<Chars...>::Value + 1]; }; template<char... Chars> char const EncryptCharsA<Chars...>::Value[CountArgs<Chars...>::Value + 1] = { Chars... }; ``` However I can't figure out how to perform operations on the characters as I expand them into the static array. I'd just like to execute a simple operation on each character (e.g. '(((c ^ 0x12) ^ 0x55) + 1)' where c is the character). A shove in the right direction would be greatly appreciated. Thanks all.

Original source

Related problems