Skip to content

Instantly share code, notes, and snippets.

@rianhunter
Created March 29, 2014 19:54
Show Gist options
  • Save rianhunter/9861720 to your computer and use it in GitHub Desktop.
Save rianhunter/9861720 to your computer and use it in GitHub Desktop.
C++ compilers can manipulate and create string literals at compile time
#include <type_traits>
#include <cstring>
#include <cstdio>
template <size_t N>
class StaticallySizedString {
char _str[N + 1];
public:
template <size_t a_size, size_t b_size,
typename std::enable_if<a_size + b_size == N>::type * = nullptr>
StaticallySizedString(const StaticallySizedString<a_size> & a,
const StaticallySizedString<b_size> & b) {
std::memcpy(_str, a.c_str(), a_size);
std::memcpy((char *) _str + a_size, b.c_str(), b_size);
_str[a_size + b_size] = '\0';
}
StaticallySizedString(const char *f) {
std::memcpy(_str, f, sizeof(_str));
}
template <size_t other_n>
StaticallySizedString<N + other_n>
operator+(const StaticallySizedString<other_n> & other) const {
return StaticallySizedString<N + other_n>(*this, other);
}
const char *c_str() const {
return _str;
}
};
template <size_t N>
StaticallySizedString<N - 1>
make_static_string(const char (&str)[N]) {
return StaticallySizedString<N - 1>(str);
}
int main(int argc, char *argv[]) {
// because StaticallySizedString's storage is known at compile time
// (it's not a pointer to malloc'd memory)
// the following will be run at compile-time
// (does not work with std::string)
auto hai = make_static_string("abbb") + make_static_string("b");
// this would fail:
// make_static_string(argv[0])
std::printf("%s\n", hai.c_str());
return 0;
}
/*
$ g++ -v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
$ g++ -std=c++11 -O3 -S test.cc
$ cat test.s
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
subq $16, %rsp
movw $98, -4(%rbp)
movl $1650614881, -8(%rbp) ## imm = 0x62626261
leaq -8(%rbp), %rdi
callq _puts
xorl %eax, %eax
addq $16, %rsp
popq %rbp
ret
.cfi_endproc
.subsections_via_symbols
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment