Skip to content

Commit 14a4be6

Browse files
committed
Add string_parts
1 parent f9ca050 commit 14a4be6

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

source/common.h

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,116 @@ struct comment
100100
std::string text;
101101
};
102102

103+
struct string_parts {
104+
struct cpp_code { std::string text; };
105+
struct raw_string { std::string text; };
106+
enum adds_sequences { no_ends = 0, on_the_begining = 1, on_the_end = 2, on_both_ends = 3 };
107+
108+
string_parts(const std::string& beginseq,
109+
const std::string& endseq,
110+
adds_sequences strateg)
111+
: begin_seq{beginseq}
112+
, end_seq{endseq}
113+
, strategy{strateg}
114+
{
115+
if (!(strategy & on_the_begining)) {
116+
parts.push_back(raw_string{""});
117+
}
118+
}
119+
120+
void add_code(const std::string& text) { parts.push_back(cpp_code{text});}
121+
void add_string(const std::string& text) { parts.push_back(raw_string{text});}
122+
void add_string(const std::string_view& text) { parts.push_back(raw_string{std::string(text)});}
123+
124+
void clear() { parts.clear(); }
125+
126+
127+
auto generate() const -> std::string {
128+
129+
if (parts.empty()) {
130+
return (strategy & on_the_begining ? begin_seq : std::string{})
131+
+ (strategy & on_the_end ? end_seq : std::string{});
132+
}
133+
134+
auto result = std::visit(begin_visit{begin_seq, strategy},
135+
parts.front());
136+
137+
if (std::ssize(parts) > 1) {
138+
auto it1 = parts.cbegin();
139+
auto it2 = parts.cbegin()+1;
140+
for(;it2 != parts.cend(); ++it1, ++it2) {
141+
result += std::visit(generator_visit{begin_seq, end_seq}, *it1, *it2);
142+
}
143+
}
144+
145+
if (!(strategy & on_the_end)) {
146+
result += std::visit([this](const auto& lhs) {
147+
return generator_visit{begin_seq, end_seq}(lhs, raw_string{""});
148+
}, parts.back());
149+
}
150+
151+
result += std::visit(end_visit{end_seq, strategy}, parts.back());
152+
153+
return result;
154+
}
155+
156+
auto is_expanded() const -> bool {
157+
for (const auto& p : parts) {
158+
if (std::holds_alternative<cpp_code>(p)) {
159+
return true;
160+
}
161+
}
162+
return false;
163+
}
164+
165+
private:
166+
std::string begin_seq;
167+
std::string end_seq;
168+
adds_sequences strategy;
169+
std::vector<std::variant<raw_string, cpp_code>> parts;
170+
171+
struct begin_visit {
172+
std::string begin_seq;
173+
adds_sequences strategy;
174+
175+
auto operator()(const raw_string& part) const -> std::string {
176+
return (strategy & on_the_begining ? begin_seq : "") + part.text;
177+
}
178+
auto operator()(const cpp_code& part) const -> std::string {
179+
return part.text;
180+
}
181+
};
182+
183+
struct end_visit {
184+
std::string end_seq;
185+
adds_sequences strategy;
186+
auto operator()(const raw_string& part) const -> std::string {
187+
return strategy & on_the_end ? end_seq : "";
188+
}
189+
auto operator()(const cpp_code& part) const -> std::string {
190+
return {};
191+
}
192+
};
193+
194+
struct generator_visit {
195+
std::string begin_seq;
196+
std::string end_seq;
197+
198+
auto operator()(const raw_string&, const cpp_code& part ) const -> std::string {
199+
return end_seq + " + " + part.text;
200+
}
201+
auto operator()(const cpp_code&, const raw_string& part ) const -> std::string {
202+
return " + " + begin_seq + part.text;
203+
}
204+
auto operator()(const raw_string&, const raw_string& part ) const -> std::string {
205+
return part.text;
206+
}
207+
auto operator()(const cpp_code&, const cpp_code& part ) const -> std::string {
208+
return " + " + part.text;
209+
}
210+
};
211+
};
212+
103213
//-----------------------------------------------------------------------
104214
//
105215
// error: represents a user-readable error message

0 commit comments

Comments
 (0)