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
If I understand what you want to do correctly (actually create an array at compile time) I think variadic templates aren't enough and you'll have to wait for constexpr.
If however you don't need an actual array and can instead compromise on using something akin to tuple
's get<I>
then it's possible (you can then build a char
array at runtime).
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;
};