Last active
December 26, 2015 08:49
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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