General Utility Library for C++14  2.11
join_split.h
Go to the documentation of this file.
1 
23 #ifndef GUL14_JOIN_SPLIT_H_
24 #define GUL14_JOIN_SPLIT_H_
25 
26 #include <iterator>
27 #include <regex>
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31 
32 #include "gul14/internal.h"
33 #include "gul14/string_util.h"
34 #include "gul14/string_view.h"
35 
36 namespace gul14 {
37 
121 template <typename StringContainer = std::vector<std::string>,
122  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
123 inline StringContainer
124 split(string_view text, string_view delimiter,
125  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
126 {
127  using StringType = typename StringContainer::value_type;
128  using SizeType = typename StringType::size_type;
129 
130  auto result = StringContainer{ };
131  auto search_start = SizeType{ 0 };
132  auto push_start = search_start;
133 
134  for (;;) {
135  const auto hit = text.find(delimiter.data(), search_start, delimiter.size());
136  if (hit == StringType::npos)
137  break;
138  const auto hit_len = hit - push_start;
139  insert_fct(result, text.substr(push_start, hit_len));
140  search_start += std::max(delimiter.size() + hit_len, SizeType{ 1 });
141  push_start += delimiter.size() + hit_len;
142  }
143  insert_fct(result, text.substr(push_start));
144  return result;
145 }
146 
171 template <typename StringContainer = std::vector<std::string>,
172  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
173 inline StringContainer
174 split(string_view text, const std::regex& delimiter,
175  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
176 {
177  auto const end = std::cregex_iterator{ };
178  auto result = StringContainer{ };
179 
180  auto parts = std::cregex_iterator(text.begin(), text.end(), delimiter);
181  if (parts == end)
182  {
183  insert_fct(result, text);
184  }
185  else
186  {
187  auto previous = std::cregex_iterator{ };
188  for (; parts != end; ++parts) {
189  if (parts == previous and not parts->length())
190  break;
191  auto const& match = parts->prefix();
192  insert_fct(result, string_view(match.first, match.length()));
193  previous = parts;
194  }
195 
196  auto const& match = previous->suffix();
197  insert_fct(result, string_view(match.first, match.length()));
198  }
199 
200  return result;
201 }
202 
225 template <typename StringContainer = std::vector<string_view>,
226  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
227 inline StringContainer
229  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
230 {
231  return split<StringContainer>(text, delimiter, insert_fct);
232 }
233 
257 template <typename Iterator>
258 inline std::string
259 join(Iterator begin, Iterator end, string_view glue)
260 {
261  std::string result;
262 
263  if (begin == end)
264  return result; // Return an empty string
265 
266  std::size_t num_strings = 0;
267  std::size_t len = 0;
268 
269  for (auto it = begin; it != end; ++it)
270  {
271  ++num_strings;
272  len += it->size();
273  }
274  len += (num_strings - 1) * glue.size();
275 
276  result.reserve(len);
277 
278  result += *begin;
279 
280  // Iterate over all but the last string
281  for (auto it = std::next(begin); it != end; ++it)
282  {
283  result.append(glue.data(), glue.size());
284  result += *it;
285  }
286 
287  return result;
288 }
289 
318 template <typename StringContainer>
319 inline std::string
320 join(const StringContainer& parts, string_view glue)
321 {
322  return join(parts.begin(), parts.end(), glue);
323 }
324 
326 
327 } // namespace gul14
328 
329 #endif
330 
331 /* vim:set noexpandtab softtabstop=4 tabstop=4 shiftwidth=4 textwidth=90 cindent: */
std::string join(Iterator begin, Iterator end, string_view glue)
Concatenate all strings in a range, placing a delimiter between them.
Definition: join_split.h:259
StringContainer split(string_view text, string_view delimiter, ContainerInsertFct insert_fct=detail::emplace_back< StringContainer >)
Separate a string at all occurrences of a delimiter, returning the strings between the delimiters in ...
Definition: join_split.h:124
StringContainer split_sv(string_view text, string_view delimiter, ContainerInsertFct insert_fct=detail::emplace_back< StringContainer >)
Separate a string at all occurrences of a delimiter, returning the strings between the delimiters in ...
Definition: join_split.h:228
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:624
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
Declaration of string utility functions.
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.