Skip to content

Instantly share code, notes, and snippets.

@serge-sans-paille
Created October 6, 2016 12:47
Show Gist options
  • Save serge-sans-paille/f5d64af5cbfb5ff2a1a437858f81fb02 to your computer and use it in GitHub Desktop.
Save serge-sans-paille/f5d64af5cbfb5ff2a1a437858f81fb02 to your computer and use it in GitHub Desktop.
#include <string>
#include <cassert>
#include <array>
#include <numeric>
template<std::size_t N, char Seed = 42>
class constexpr_str {
std::array<char, N> data_;
template<std::size_t... Is>
static constexpr char reduce(char const (&data)[N], std::index_sequence<Is...>) {
return (data[Is] ^ ... ^ Seed);
}
template<class... Seqs>
constexpr constexpr_str(char const (&data)[N], Seqs... seq) : data_({reduce(data, seq)...}) {
}
template<std::size_t... Is>
constexpr constexpr_str(char const (&data)[N], std::index_sequence<Is...>) : constexpr_str(data, std::make_index_sequence<Is + 1>()...) {
}
public:
constexpr constexpr_str(char const (&data)[N]) : constexpr_str(data, std::make_index_sequence<N>()) {
}
operator std::string() const {
std::string out;
out.resize(N - 1);
char acc = Seed;
for(std::size_t i = 0; i <N - 1; ++i) {
out[i] = acc ^ data_[i];
acc = acc ^ out[i];
}
assert(acc ^data_[N-1] == 0);
return out;
}
};
template<std::size_t N>
constexpr auto obf_(const char (&s)[N]) noexcept {
return constexpr_str<N>{s};
}
template <typename CharT, CharT ...c>
constexpr auto operator"" _obf() noexcept {
static_assert(std::is_same<CharT, char>::value, "on char");
char data[sizeof...(c) + 1] = {c...};
data[sizeof...(c) + 1] = 0;
return obf_(data);
}
auto out0(std::size_t i) {
constexpr auto val = "bonjour"_obf;
return std::string(val);
}
#include <iostream>
int main() {
std::cout << out0(1) << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment