1#include <cstring>
2#include <string>
3
4template<typename T>
5struct string_builder_helper;
6
7template<typename A, typename B>
8struct string_builder
9{
10 typedef string_builder_helper<A> HA;
11 typedef string_builder_helper<B> HB;
12 operator std::string() const
13 {
14 std::string s;
15 s.reserve(size());
16 HA::append_to(s, a);
17 HB::append_to(s, b);
18 return s;
19 }
20 unsigned int size() const
21 {
22 return HA::size(a) + HB::size(b);
23 }
24
25 string_builder(const A &a, const B &b)
26 : a(a)
27 , b(b)
28 {
29 }
30 const A &a;
31 const B &b;
32};
33
34template<>
35struct string_builder_helper<std::string>
36{
37 typedef std::string T;
38 static unsigned int size(const std::string &s)
39 {
40 return s.size();
41 }
42 static void append_to(std::string &s, const std::string &a)
43 {
44 s += a;
45 }
46};
47
48template<>
49struct string_builder_helper<const char *>
50{
51 typedef const char *T;
52 static unsigned int size(const char *s)
53 {
54 return std::strlen(s: s);
55 }
56 static void append_to(std::string &s, const char *a)
57 {
58 s += a;
59 }
60};
61
62template<typename A, typename B>
63struct string_builder_helper<string_builder<A, B>>
64{
65 typedef string_builder<A, B> T;
66 static unsigned int size(const T &t)
67 {
68 return t.size();
69 }
70 static void append_to(std::string &s, const T &t)
71 {
72 T::HA::append_to(s, t.a);
73 T::HB::append_to(s, t.b);
74 }
75};
76
77template<int N>
78struct string_builder_helper<char[N]>
79{
80 typedef char T[N];
81 static unsigned int size(const char *s)
82 {
83 return N - 1;
84 }
85 static void append_to(std::string &s, const char *a)
86 {
87 s.append(s: a, n: N - 1);
88 }
89};
90
91template<typename A, typename B>
92string_builder<typename string_builder_helper<A>::T, typename string_builder_helper<B>::T>
93operator%(const A &a, const B &b)
94{
95 return { a, b };
96}
97
98template<typename T>
99std::string &operator%=(std::string &s, const T &t)
100{
101 typedef string_builder_helper<T> H;
102 s.reserve(s.size() + H::size(t));
103 H::append_to(s, t);
104 return s;
105}
106
107#include <llvm/ADT/StringRef.h>
108template<>
109struct string_builder_helper<llvm::StringRef>
110{
111 typedef llvm::StringRef T;
112 static unsigned int size(llvm::StringRef s)
113 {
114 return s.size();
115 }
116 static void append_to(std::string &s, llvm::StringRef a)
117 {
118 s += a;
119 }
120};
121

source code of codebrowser/generator/stringbuilder.h