1#include <string>
2#include <cstring>
3
4template<typename T> struct string_builder_helper;
5
6template <typename A, typename B> struct string_builder {
7 typedef string_builder_helper<A> HA;
8 typedef string_builder_helper<B> HB;
9 operator std::string() const {
10 std::string s;
11 s.reserve(size());
12 HA::append_to(s, a);
13 HB::append_to(s, b);
14 return s;
15 }
16 unsigned int size() const { return HA::size(a) + HB::size(b); }
17
18 string_builder(const A &a, const B &b) : a(a), b(b) {}
19 const A &a;
20 const B &b;
21};
22
23template<> struct string_builder_helper<std::string> {
24 typedef std::string T;
25 static unsigned int size(const std::string &s) { return s.size(); }
26 static void append_to(std::string &s, const std::string &a) { s+=a; }
27};
28
29template<> struct string_builder_helper<const char *> {
30 typedef const char *T;
31 static unsigned int size(const char *s) { return std::strlen(s); }
32 static void append_to(std::string &s, const char *a) { s+=a; }
33};
34
35template<typename A, typename B> struct string_builder_helper<string_builder<A,B>> {
36 typedef string_builder<A,B> T;
37 static unsigned int size(const T &t) { return t.size(); }
38 static void append_to(std::string &s, const T &t) {
39 T::HA::append_to(s, t.a);
40 T::HB::append_to(s, t.b);
41 }
42};
43
44template<int N> struct string_builder_helper<char[N]> {
45 typedef char T[N];
46 static unsigned int size(const char *s) { return N-1; }
47 static void append_to(std::string &s, const char *a) { s.append(a, N-1); }
48};
49
50template<typename A, typename B>
51string_builder<typename string_builder_helper<A>::T, typename string_builder_helper<B>::T>
52operator %(const A &a, const B &b) {
53 return {a, b};
54}
55
56template<typename T> std::string &operator %=(std::string &s, const T &t) {
57 typedef string_builder_helper<T> H;
58 s.reserve(s.size() + H::size(t));
59 H::append_to(s, t);
60 return s;
61}
62
63#include <llvm/ADT/StringRef.h>
64template<> struct string_builder_helper<llvm::StringRef> {
65 typedef llvm::StringRef T;
66 static unsigned int size(llvm::StringRef s) { return s.size(); }
67 static void append_to(std::string &s, llvm::StringRef a) { s+=a; }
68};
69