Skip to content

Instantly share code, notes, and snippets.

@dangkhoasdc
Forked from daniel-j-h/ct-strings.cc
Created April 18, 2017 02:54
Show Gist options
  • Save dangkhoasdc/c22f52570ff811a0801e83e9b9db3de9 to your computer and use it in GitHub Desktop.
Save dangkhoasdc/c22f52570ff811a0801e83e9b9db3de9 to your computer and use it in GitHub Desktop.
Compile-time strings and string concatenation
#include <stdexcept>
#include <utility>
class Str {
public:
template <std::size_t N>
constexpr Str(const char(&a)[N]) : p(a), s(N - 1) {}
constexpr char operator[](std::size_t n) const {
return n < s ? p[n] : throw std::out_of_range("Str::operator[]");
}
constexpr std::size_t size() const {
return s;
}
private:
const char* const p;
const std::size_t s;
};
template <typename... Strs>
class StrList {
public:
constexpr StrList(Strs... strs) : list{strs...} {}
constexpr Str operator[](std::size_t n) const {
return n < (sizeof...(Strs)) ? list[n] : throw std::out_of_range("StrList::operator[]");
}
constexpr std::size_t size() const {
return do_size(0, sizeof...(Strs));
}
constexpr StrList<Strs..., Str> operator+(Str r) {
return do_add(std::index_sequence_for<Strs...>{}, r);
}
private:
const Str list[sizeof...(Strs)];
constexpr std::size_t do_size(std::size_t a, std::size_t n) const {
return n == 0 ? a : do_size(a + list[n - 1].size(), n - 1);
}
template <std::size_t... I>
constexpr auto do_add(std::index_sequence<I...>, Str r) -> StrList<Strs..., Str> {
return StrList<Strs..., Str>(list[I]..., r);
}
};
constexpr auto operator+(Str l, Str r) -> StrList<Str, Str> {
return StrList<Str, Str>(l, r);
}
int main() {
constexpr auto x = Str("ab") + Str("cd") + Str("ef");
constexpr auto ab = x[0];
static_assert(ab[0] == 'a', "");
static_assert(ab[1] == 'b', "");
return x.size(); // compiles down to ret 6
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment