@@ -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