In this section, we are going to implement our own STL-like algorithm called split, and then we check it out by splitting an example string:
- First things first, we include some STL library parts and declare that we use the std namespace:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std;
- The whole algorithm this section revolves around is split. It accepts a begin/end pair of input iterators, and an output iterator, which makes it similar to std::copy or std::transform at first. The other parameters are split_val and bin_func. The split_val parameter is the value we are searching for in the input range, which represents a splitting point at which we cut the input interval. The bin_func parameter is a function that transforms a pair of iterators that mark the beginning and the end of such a split chunk subrange. We iterate through the input range using std::find, so we jump from occurrence to occurrence of split_val values. When splitting a long string into its individual words, we would jump from space character to space character. On every split value, we stop by to form a chunk and feed it into the output range:
template <typename InIt, typename OutIt, typename T, typename F>
InIt split(InIt it, InIt end_it, OutIt out_it, T split_val,
F bin_func)
{
while (it != end_it) {
auto slice_end (find(it, end_it, split_val));
*out_it++ = bin_func(it, slice_end);
if (slice_end == end_it) { return end_it; }
it = next(slice_end);
}
return it;
}
- Let's use the new algorithm. We construct a string that we want to split. The item that marks the end of the last chunk, and the beginning of the next chunk, shall be the dash character '-':
int main()
{
const string s {"a-b-c-d-e-f-g"};
- Whenever the algorithm calls its bin_func on a pair of iterators, we want to construct a new string from it:
auto binfunc ([](auto it_a, auto it_b) {
return string(it_a, it_b);
});
- The output range will be an std::list of strings. We can now call the split algorithm, which has a similar design compared to all the other STL algorithms:
list<string> l;
split(begin(s), end(s), back_inserter(l), '-', binfunc);
- In order to see what we got, let's print the new chunked list of strings:
copy(begin(l), end(l), ostream_iterator<string>{cout, "n"});
}
- Compiling and running the program yields the following output. It contains no dashes anymore and shows that it has isolated the individual words (which are, of course, only single characters in our example string):
$ ./split
a
b
c
d
e
f
g