General Utility Library for C++17 25.4.1
Functions
gul17/join_split.h

Detailed Description

Joining and splitting strings.

Collaboration diagram for gul17/join_split.h:

Functions

template<typename StringContainer = std::vector<std::string>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split (std::string_view text, std::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 a container.
 
template<typename StringContainer = std::vector<std::string>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split (std::string_view text, const std::regex &delimiter, ContainerInsertFct insert_fct=detail::emplace_back< StringContainer >)
 Separate a string at all occurrences of a delimiter described by a regular expression, returning the strings between the delimiters in a container.
 
template<typename StringContainer = std::vector<std::string_view>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split_sv (std::string_view text, std::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 a vector.
 
template<typename Iterator >
std::string gul17::join (Iterator begin, Iterator end, std::string_view glue)
 Concatenate all strings (or string-like elements) in a range, placing a delimiter between them.
 
template<typename StringContainer >
std::string gul17::join (const StringContainer &parts, std::string_view glue)
 Concatenate all strings (or string-like elements) in a range, placing a delimiter between them.
 
template<typename Iterator , typename ConversionFct >
std::string gul17::join (Iterator begin, Iterator end, std::string_view glue, ConversionFct to_string, std::size_t prealloc=0)
 Concatenate the strings resulting from calling the given function on each element in a range, placing a delimiter between them.
 
template<typename Container , typename ConversionFct >
std::string gul17::join (const Container &container, std::string_view glue, ConversionFct to_string, std::size_t prealloc=0)
 Concatenate the strings resulting from calling the given function on each element in a range, placing a delimiter between them.
 

Function Documentation

◆ join() [1/4]

std::string gul17::join ( const Container container,
std::string_view  glue,
ConversionFct  to_string,
std::size_t  prealloc = 0 
)
inline

Concatenate the strings resulting from calling the given function on each element in a range, placing a delimiter between them.

std::vector<int> parts = { 1, 2, 3 };
std::string result = join(parts, "-", [](int i) { return std::to_string(i); });
assert(result == "1-2-3");
auto constexpr bit_set(unsigned bit) noexcept -> ReturnT
Set a bit in an integral type.
Definition bit_manip.h:121
std::string join(Iterator begin, Iterator end, std::string_view glue)
Concatenate all strings (or string-like elements) in a range, placing a delimiter between them.
Definition join_split.h:284

This algorithm iterates exactly once over the range. To speed up complex joining operations, string memory can be preallocated via the last parameter.

Parameters
containerContainer of input elements
glueString to be put between the string-converted elements
to_stringFunction object to convert the container elements to strings
preallocNumber of bytes to preallocate for the result string. Providing this parameter is not necessary, but it may provide a tiny performance boost. The default is zero (no preallocation).
Returns
the concatenated string.
Template Parameters
ContainerA container type that provides a cbegin() and cend() member function returning forward iterators.
ConversionFctA function object type that can be called with the dereferenced iterator type and returns a string type. This string type must support concatenation with std::string::operator+=().
Since
GUL version UNRELEASED

References gul17::bit_set(), and gul17::join().

◆ join() [2/4]

std::string gul17::join ( const StringContainer parts,
std::string_view  glue 
)
inline

Concatenate all strings (or string-like elements) in a range, placing a delimiter between them.

std::vector<std::string> parts = { "one", "two", "three" };
std::string result = join(parts, "-");
assert(result == "one-two-three");

If the element type in the range has a size() member function, the algorithm iterates twice over the range in order to pre-allocate a string of the correct size. Otherwise, it only iterates once.

This is the inverse function of split(). It is guaranteed that join(split(text, del), del) == text (unless del is a std::regex object).

Parameters
partsA container holding strings or string views that are to be concatenated
glueString that is put between each element of parts
Returns
all strings glued together with the delimiter glue.
Template Parameters
StringContainerA container type that holds string-like elements, e.g. std::vector<std::string> or std::list<std::string_view>. The container must provide an STL-like forward iterator interface. The string type must must support concatenation using std::string::operator+=. An additional optimization is enabled if the string type has a size() member function.
See also
join(Iterator, Iterator, std::string_view) has a two-iterator interface. join(Container, std::string_view, ConversionFct) and join(Iterator, Iterator, std::string_view, ConversionFct) allow joining ranges of arbitrary type into a string using a conversion function. split() and associated functions can be used to split a string into a vector of substrings.
Since
GUL version 2.3, join() accepts arbitrary containers or iterators (it was limited to std::vector before).

References gul17::bit_set(), and gul17::join().

◆ join() [3/4]

template<typename Iterator >
std::string gul17::join ( Iterator  begin,
Iterator  end,
std::string_view  glue 
)
inline

Concatenate all strings (or string-like elements) in a range, placing a delimiter between them.

std::vector<std::string> parts = { "one", "two", "three" };
std::string result = join(parts.begin(), parts.end(), "-");
assert(result == "one-two-three");

If the element type in the range has a size() member function, the algorithm iterates twice over the range in order to pre-allocate a string of the correct size. Otherwise, it only iterates once.

Parameters
beginIterator pointing to the first string
endIterator pointing past the last string
glueString that is put between each element of parts
Returns
all strings glued together with the delimiter glue.
Template Parameters
IteratorA forward iterator type that dereferences to a string-like type. This string type must must support concatenation using std::string::operator+=. An additional optimization is enabled if the string type has a size() member function.
See also
join(StringContainer, std::string_view) is a convenience overload for joining entire containers. join(Container, std::string_view, ConversionFct) and join(Iterator, Iterator, std::string_view, ConversionFct) allow joining ranges of arbitrary type into a string using a conversion function. split() and associated functions can be used to split a string into a vector of substrings.
Since
GUL version 2.3

References gul17::bit_set().

Referenced by gul17::join(), and gul17::join().

◆ join() [4/4]

template<typename Iterator , typename ConversionFct >
std::string gul17::join ( Iterator  begin,
Iterator  end,
std::string_view  glue,
ConversionFct  to_string,
std::size_t  prealloc = 0 
)
inline

Concatenate the strings resulting from calling the given function on each element in a range, placing a delimiter between them.

std::vector<int> parts = { 1, 2, 3 };
std::string result = join(parts.begin(), parts.end(), "-",
[](int i) { return std::to_string(i); });
assert(result == "1-2-3");

This algorithm iterates exactly once over the range. To speed up complex joining operations, string memory can be preallocated via the last parameter.

Parameters
beginIterator to the first input element
endIterator pointing past the last input element
glueString to be put between the string-converted elements
to_stringFunction object to convert the container elements to strings
preallocNumber of bytes to preallocate for the result string. Providing this parameter is not necessary, but it may provide a tiny performance boost. The default is zero (no preallocation).
Returns
the concatenated string.
Template Parameters
IteratorA forward iterator type that dereferences to a type that can be passed to the ConversionFct.
ConversionFctA function object type that can be called with the dereferenced iterator type and returns a string type. This string type must support concatenation with std::string::operator+=().
Since
GUL version UNRELEASED

References gul17::bit_set().

◆ split() [1/2]

template<typename StringContainer = std::vector<std::string>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split ( std::string_view  text,
const std::regex &  delimiter,
ContainerInsertFct  insert_fct = detail::emplace_back<StringContainer> 
)
inline

Separate a string at all occurrences of a delimiter described by a regular expression, returning the strings between the delimiters in a container.

This function is a variant of split(std::string_view, std::string_view, ContainerInsertFct) that accepts a std::regex object to describe the delimiter:

// Return type is std::vector<std::string>
auto parts = split("one\ntwo\nthree"s, std::regex{"[^[:print:]]"});
assert(y.size() == 3);
assert(y[0] == "one"s);
assert(y[1] == "two"s);
assert(y[2] == "three"s);
StringContainer split(std::string_view text, std::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
Parameters
textThe string to be split
delimiterA std::regex object describing the delimiters
insert_fctCustom container inserter function
See also
split(std::string_view, std::string_view, ContainerInsertFct) splits at a fixed substring,
split_sv() does the same returning a vector of std::string_views, and
join() can join the vector back into a string.

References gul17::bit_set().

◆ split() [2/2]

template<typename StringContainer = std::vector<std::string>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split ( std::string_view  text,
std::string_view  delimiter,
ContainerInsertFct  insert_fct = detail::emplace_back<StringContainer> 
)
inline

Separate a string at all occurrences of a delimiter, returning the strings between the delimiters in a container.

The result has at least one element. If the delimiter is not present in the text, the whole text is returned. If there are consecutive delimiters, the collected string between them is the empty string. If the delimiter is directly at the end of the input, the collected string between the end of the input and the delimiter is again the empty string.

split() is the inverse function of join(). It is guaranteed that join(split(text, del), del) == text.

std::vector<std::string> parts1 = split(" hello world", " ");
assert(parts1.size() == 3);
assert(parts1[0] == ""s);
assert(parts1[1] == "hello"s);
assert(parts1[2] == "world"s);
std::vector<std::string> parts2 = split("<>", "<>");
assert(parts2.size() == 2);
assert(parts2[0] == ""s);
assert(parts2[1] == ""s);

This function returns a std::vector<std::string> by default, but a compatible container for string/string_view types can be specified via a template parameter:

Template Parameters
StringContainerA container for strings or std::string_view-like types, e.g. std::vector<std::string> or std::list<std::string_view>
ContainerInsertFctType for the insert_fct function parameter.
Parameters
textThe string to be split
delimiterThe delimiting substring
insert_fctBy default, split() calls the emplace_back() member function on the container to insert strings. This parameter may contain a different function pointer or object with the signature void f(StringContainer&, std::string_view) that is called instead. This can be useful for containers that do not provide emplace_back() or for other customizations.
Returns
a container filled with the substrings that were separated by delimiter in the original string.
// Different string type
auto parts1 = split<std::vector<std::string_view>>("Hello world", " "); // behaves like split_sv()
assert(parts1.size() == 2);
assert(parts1[0] == "Hello"); // No lifetime problems because "Hello world" is a
assert(parts1[1] == "world"); // string literal with static storage duration
// Custom container type
assert(parts2.size() == 3);
assert(parts2[0] == "a");
assert(parts2[1] == "b");
assert(parts2[2] == "c");
// For a container without emplace_back(), use a custom inserter:
using WeirdContainer = std::queue<std::string>;
auto inserter = [](WeirdContainer& c, std::string_view sv) { c.emplace(sv); };
assert(parts3.size() == 2);
assert(parts3.front() == "a");
assert(parts3.back() == "b");
See also
split_sv() returns a vector of std::string_views,
split(const std::string&, const std::regex&) splits at a delimiter described by a regular expression, and
join() can join the vector back into a string.
Since
GUL version 2.5, the return type of split() can be specified as a template parameter and a custom inserter can be specified (it always returned std::vector<std::string> before).

References gul17::bit_set().

◆ split_sv()

template<typename StringContainer = std::vector<std::string_view>, typename ContainerInsertFct = void (*)(StringContainer&, std::string_view)>
StringContainer gul17::split_sv ( std::string_view  text,
std::string_view  delimiter,
ContainerInsertFct  insert_fct = detail::emplace_back<StringContainer> 
)
inline

Separate a string at all occurrences of a delimiter, returning the strings between the delimiters in a vector.

This function is identical to split(std::string_view, std::string_view, ContainerInsertFct) except that it returns a std::vector of std::string_views instead of strings by default:

auto parts = split_sv("hello world", " "); // Return type is std::vector<std::string_view>
assert(parts.size() == 2);
assert(parts[0] == "hello"); // No problems with lifetime because "hello world"
assert(parts[1] == "world"); // is a string literal with static storage duration
StringContainer split_sv(std::string_view text, std::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:229
See also
split(std::string_view, std::string_view, ContainerInsertFct) returns a vector of strings,
split(const std::string&, const std::regex&) splits at a delimiter described by a regular expression, and
join() can join the vector back into a string.
Since
GUL version 2.5, the return type of split_sv() can be specified as a template parameter and a custom inserter can be specified (it always returned std::vector<std::string> before).

References gul17::bit_set().