Skip to content

Instantly share code, notes, and snippets.

@jonvaldes
Last active December 26, 2015 08:49
Show Gist options
  • Save jonvaldes/7124736 to your computer and use it in GitHub Desktop.
Save jonvaldes/7124736 to your computer and use it in GitHub Desktop.
Compile-time text concatenation via templates and constexpr. Not exactly clean, but perfectly functional. Intended use is automatic JNI type string construction. Technique is a derivation of this: http://stackoverflow.com/a/16720106/375486
#include <cstdio>
using namespace std;
template <size_t dim> struct c_array {
char value[dim];
};
// helper; construct a sequence of non-type template arguments
template <size_t... tt_i > struct seq {};
template <size_t t_n, size_t... tt_i > struct gen_seq : gen_seq < t_n-1, t_n-1, tt_i...> {};
template <size_t... tt_i > struct gen_seq < 0, tt_i... > : seq < tt_i... > {};
// Concatenate strings by using parameter pack expansion
template < size_t S1, size_t S2, size_t... tt_S1, size_t... tt_S2>
constexpr c_array<S1+S2> concat_internal(seq<tt_S1...>, seq<tt_S2...>, c_array<S1> a1, c_array<S2> a2){
return {{ a1.value[tt_S1]...,a2.value[tt_S2]...}};
}
template < size_t S1, size_t S2>
constexpr c_array<S1+S2> concat(c_array<S1> a1, c_array<S2> a2){
return concat_internal(gen_seq<S1>{},gen_seq<S2>{},a1,a2);
}
template <size_t dim, size_t ...tt>
constexpr c_array<dim> ConstStr_internal(const char * str,seq<tt...>){
return {{ str[tt]...}};
}
template <size_t dim>
constexpr c_array<dim-1> ConstStr(const char (&str)[dim]) {
return ConstStr_internal<dim-1>(str,gen_seq<dim-1>{});
}
constexpr auto arr = ConstStr("Hello");
constexpr auto arr2 = ConstStr(" world.");
constexpr auto arr3 = ConstStr(" Also...");
constexpr auto arr4 = ConstStr(" I think my head is going to");
constexpr auto arr5 = ConstStr(" EXPLODE\0");
constexpr auto arr6 = concat(arr,concat(arr2,concat(arr3,concat(arr4,arr5))));
int main(){
printf("%s\n", arr6.value);
}
Generated assembly code:
.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
leaq __ZL4arr6(%rip), %rdi
callq _puts
xorl %eax, %eax
popq %rbp
ret
.cfi_endproc
.section __TEXT,__const
__ZL4arr6: ## @_ZL4arr6
.ascii "Hello world Also... I think my head is going to EXPLODE"
.subsections_via_symbols
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment