#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <type_traits>
#include <cctype>
enum tokenize_options
{
tokenize_skip_empty_tokens = 1 << 0,
tokenize_include_delimiters = 1 << 1,
tokenize_exclude_whitespace_delimiters = 1 << 2,
//
tokenize_options_none = 0,
tokenize_options_default = tokenize_skip_empty_tokens
| tokenize_exclude_whitespace_delimiters
| tokenize_include_delimiters,
};
template <typename Input, typename Delimiters, typename Out>
Out tokenize(
Input const& input,
Delimiters const& delim,
Out out,
tokenize_options options = tokenize_options_default
)
{
// decode option flags
const bool includeDelim = options & tokenize_include_delimiters;
const bool excludeWsDelim = options & tokenize_exclude_whitespace_delimiters;
const bool skipEmpty = options & tokenize_skip_empty_tokens;
using namespace std;
string accum;
for(auto it = begin(input), last = end(input); it != last; ++it)
{
if (find(begin(delim), end(delim), *it) == end(delim))
{
accum += *it;
}
else
{
// output the token
if (!(skipEmpty && accum.empty()))
*out++ = accum; // optionally skip if `accum.empty()`?
// output the delimiter
bool isWhitespace = std::isspace(*it) || (*it == '\0');
if (includeDelim && !(excludeWsDelim && isWhitespace))
{
*out++ = { *it }; // dump the delimiter as a separate token
}
accum.clear();
}
}
if (!accum.empty())
*out++ = accum;
return out;
}
int main()
{
// let's print tokens to stdout
std::ostream_iterator<std::string> out(std::cout, "\n");
tokenize("asd sdf qwe wer,sdf;wer", " ;,", out);
// that's all, folks
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPGNjdHlwZT4KCmVudW0gdG9rZW5pemVfb3B0aW9ucwp7CiAgICB0b2tlbml6ZV9za2lwX2VtcHR5X3Rva2VucyAgICAgICAgICAgICAgPSAxIDw8IDAsCiAgICB0b2tlbml6ZV9pbmNsdWRlX2RlbGltaXRlcnMgICAgICAgICAgICAgPSAxIDw8IDEsCiAgICB0b2tlbml6ZV9leGNsdWRlX3doaXRlc3BhY2VfZGVsaW1pdGVycyAgPSAxIDw8IDIsCiAgICAvLwogICAgdG9rZW5pemVfb3B0aW9uc19ub25lICAgID0gMCwKICAgIHRva2VuaXplX29wdGlvbnNfZGVmYXVsdCA9ICAgdG9rZW5pemVfc2tpcF9lbXB0eV90b2tlbnMgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHRva2VuaXplX2V4Y2x1ZGVfd2hpdGVzcGFjZV9kZWxpbWl0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHRva2VuaXplX2luY2x1ZGVfZGVsaW1pdGVycywKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBJbnB1dCwgdHlwZW5hbWUgRGVsaW1pdGVycywgdHlwZW5hbWUgT3V0PgogICBPdXQgdG9rZW5pemUoCiAgICAgICAgICAgSW5wdXQgY29uc3QmIGlucHV0LAogICAgICAgICAgIERlbGltaXRlcnMgY29uc3QmIGRlbGltLAogICAgICAgICAgIE91dCBvdXQsCiAgICAgICAgICAgdG9rZW5pemVfb3B0aW9ucyBvcHRpb25zID0gdG9rZW5pemVfb3B0aW9uc19kZWZhdWx0CiAgICAgICAgKQp7CiAgICAvLyBkZWNvZGUgb3B0aW9uIGZsYWdzCiAgICBjb25zdCBib29sIGluY2x1ZGVEZWxpbSAgID0gb3B0aW9ucyAmIHRva2VuaXplX2luY2x1ZGVfZGVsaW1pdGVyczsKICAgIGNvbnN0IGJvb2wgZXhjbHVkZVdzRGVsaW0gPSBvcHRpb25zICYgdG9rZW5pemVfZXhjbHVkZV93aGl0ZXNwYWNlX2RlbGltaXRlcnM7CiAgICBjb25zdCBib29sIHNraXBFbXB0eSAgICAgID0gb3B0aW9ucyAmIHRva2VuaXplX3NraXBfZW1wdHlfdG9rZW5zOwoKICAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAgICBzdHJpbmcgYWNjdW07CgogICAgZm9yKGF1dG8gaXQgPSBiZWdpbihpbnB1dCksIGxhc3QgPSBlbmQoaW5wdXQpOyBpdCAhPSBsYXN0OyArK2l0KQogICAgewogICAgICAgIGlmIChmaW5kKGJlZ2luKGRlbGltKSwgZW5kKGRlbGltKSwgKml0KSA9PSBlbmQoZGVsaW0pKQogICAgICAgIHsKICAgICAgICAgICAgYWNjdW0gKz0gKml0OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvLyBvdXRwdXQgdGhlIHRva2VuCiAgICAgICAgICAgIGlmICghKHNraXBFbXB0eSAmJiBhY2N1bS5lbXB0eSgpKSkKICAgICAgICAgICAgICAgICpvdXQrKyA9IGFjY3VtOyAgIC8vIG9wdGlvbmFsbHkgc2tpcCBpZiBgYWNjdW0uZW1wdHkoKWA/CgogICAgICAgICAgICAvLyBvdXRwdXQgdGhlIGRlbGltaXRlcgogICAgICAgICAgICBib29sIGlzV2hpdGVzcGFjZSA9IHN0ZDo6aXNzcGFjZSgqaXQpIHx8ICgqaXQgPT0gJ1wwJyk7IAogICAgICAgICAgICBpZiAoaW5jbHVkZURlbGltICYmICEoZXhjbHVkZVdzRGVsaW0gJiYgaXNXaGl0ZXNwYWNlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKm91dCsrID0geyAqaXQgfTsgLy8gZHVtcCB0aGUgZGVsaW1pdGVyIGFzIGEgc2VwYXJhdGUgdG9rZW4KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYWNjdW0uY2xlYXIoKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFhY2N1bS5lbXB0eSgpKQogICAgICAgICpvdXQrKyA9IGFjY3VtOwoKICAgIHJldHVybiBvdXQ7Cn0KCmludCBtYWluKCkKewogICAgLy8gbGV0J3MgcHJpbnQgdG9rZW5zIHRvIHN0ZG91dAogICAgc3RkOjpvc3RyZWFtX2l0ZXJhdG9yPHN0ZDo6c3RyaW5nPiBvdXQoc3RkOjpjb3V0LCAiXG4iKTsgCgogICAgdG9rZW5pemUoImFzZCBzZGYgcXdlIHdlcixzZGY7d2VyIiwgIiA7LCIsIG91dCk7CgogICAgLy8gdGhhdCdzIGFsbCwgZm9sa3MKfQo=