General Utility Library for C++14  2.8
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 #include "gul14/internal.h"
32 #include "gul14/string_util.h"
33 #include "gul14/string_view.h"
34 
35 namespace gul14 {
36 
114 template <typename StringContainer = std::vector<std::string>,
115  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
116 inline StringContainer
117 split(string_view text, string_view delimiter,
118  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
119 {
120  using StringType = typename StringContainer::value_type;
121  using SizeType = typename StringType::size_type;
122 
123  auto result = StringContainer{ };
124  auto search_start = SizeType{ 0 };
125  auto push_start = search_start;
126 
127  for (;;) {
128  const auto hit = text.find(delimiter.data(), search_start, delimiter.size());
129  if (hit == StringType::npos)
130  break;
131  const auto hit_len = hit - push_start;
132  insert_fct(result, text.substr(push_start, hit_len));
133  search_start += std::max(delimiter.size() + hit_len, SizeType{ 1 });
134  push_start += delimiter.size() + hit_len;
135  }
136  insert_fct(result, text.substr(push_start));
137  return result;
138 }
139 
164 template <typename StringContainer = std::vector<std::string>,
165  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
166 inline StringContainer
167 split(string_view text, const std::regex& delimiter,
168  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
169 {
170  auto const end = std::cregex_iterator{ };
171  auto result = StringContainer{ };
172 
173  auto parts = std::cregex_iterator(text.begin(), text.end(), delimiter);
174  if (parts == end)
175  {
176  insert_fct(result, text);
177  }
178  else
179  {
180  auto previous = std::cregex_iterator{ };
181  for (; parts != end; ++parts) {
182  if (parts == previous and not parts->length())
183  break;
184  auto const& match = parts->prefix();
185  insert_fct(result, string_view(match.first, match.length()));
186  previous = parts;
187  }
188 
189  auto const& match = previous->suffix();
190  insert_fct(result, string_view(match.first, match.length()));
191  }
192 
193  return result;
194 }
195 
218 template <typename StringContainer = std::vector<string_view>,
219  typename ContainerInsertFct = void (*)(StringContainer&, string_view)>
220 inline StringContainer
222  ContainerInsertFct insert_fct = detail::emplace_back<StringContainer>)
223 {
224  return split<StringContainer>(text, delimiter, insert_fct);
225 }
226 
255 template <typename StringContainer>
256 inline std::string
257 join(const StringContainer& parts, string_view glue)
258 {
259  return join(parts.begin(), parts.end(), glue);
260 }
261 
285 template <typename Iterator>
286 inline std::string
287 join(Iterator begin, Iterator end, string_view glue)
288 {
289  std::string result;
290 
291  if (begin == end)
292  return result; // Return an empty string
293 
294  std::size_t num_strings = 0;
295  std::size_t len = 0;
296 
297  for (auto it = begin; it != end; ++it)
298  {
299  ++num_strings;
300  len += it->size();
301  }
302  len += (num_strings - 1) * glue.size();
303 
304  result.reserve(len);
305 
306  result += *begin;
307 
308  // Iterate over all but the last string
309  for (auto it = std::next(begin); it != end; ++it)
310  {
311  result.append(glue.data(), glue.size());
312  result += *it;
313  }
314 
315  return result;
316 }
317 
318 
319 } // namespace gul14
320 
321 #endif
322 
323 /* vim:set noexpandtab softtabstop=4 tabstop=4 shiftwidth=4 textwidth=90 cindent: */
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
std::string join(const StringContainer &parts, string_view glue)
Concatenate all strings in a range, placing a delimiter between them.
Definition: join_split.h:257
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:117
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:623
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:221
Declarations of string utility functions for the General Utility Library.
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.