#include <iostream>
#include <string>
#include <algorithm>
using namespace std::literals::string_literals;
template <class StringType, class Predicate, class SizeType = typename StringType::size_type>
SizeType search(const StringType& where, Predicate pred, SizeType pos, SizeType n)
{
if (n > 0 && pos < where.size())
{
auto start = where.c_str(),
ptr = start + pos,
stop = ptr + std::min(where.size() - pos, n);
do
{
if (pred(ptr, stop - ptr))
return ptr - start;
}
while (++ptr < stop);
}
return StringType::npos;
}
template <class StringType, class Predicate, class SizeType = typename StringType::size_type>
SizeType search(const StringType& where, Predicate pred, SizeType pos = 0)
{
return search(where, pred, pos, where.size()-pos);
}
int main()
{
std::cout << search("Hello world"s,
[](auto&& str, auto n) {
return n > 3 &&
str[0] == 'l' &&
str[1] == 'l';
}
) << std::endl;
std::cout << search(L"Hello world"s,
[](auto&& str, auto n) {
return n > 3 &&
str[0] == L'l' &&
str[1] == L'l';
}
) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOjpsaXRlcmFsczo6c3RyaW5nX2xpdGVyYWxzOwoKdGVtcGxhdGUgPGNsYXNzIFN0cmluZ1R5cGUsIGNsYXNzIFByZWRpY2F0ZSwgY2xhc3MgU2l6ZVR5cGUgPSB0eXBlbmFtZSBTdHJpbmdUeXBlOjpzaXplX3R5cGU+ClNpemVUeXBlIHNlYXJjaChjb25zdCBTdHJpbmdUeXBlJiB3aGVyZSwgUHJlZGljYXRlIHByZWQsIFNpemVUeXBlIHBvcywgU2l6ZVR5cGUgbikKewoJaWYgKG4gPiAwICYmIHBvcyA8IHdoZXJlLnNpemUoKSkKCXsKICAgIAlhdXRvIHN0YXJ0ID0gd2hlcmUuY19zdHIoKSwKICAgIAkJIHB0ciA9IHN0YXJ0ICsgcG9zLAoJICAgIAkgc3RvcCA9IHB0ciArIHN0ZDo6bWluKHdoZXJlLnNpemUoKSAtIHBvcywgbik7CiAgICAJZG8KICAgIAl7CiAgICAgICAgCWlmIChwcmVkKHB0ciwgc3RvcCAtIHB0cikpCiAgICAgICAgCQlyZXR1cm4gcHRyIC0gc3RhcnQ7CgkJfQoJCXdoaWxlICgrK3B0ciA8IHN0b3ApOwoJfQogICAgcmV0dXJuIFN0cmluZ1R5cGU6Om5wb3M7Cn0KCnRlbXBsYXRlIDxjbGFzcyBTdHJpbmdUeXBlLCBjbGFzcyBQcmVkaWNhdGUsIGNsYXNzIFNpemVUeXBlID0gdHlwZW5hbWUgU3RyaW5nVHlwZTo6c2l6ZV90eXBlPgpTaXplVHlwZSBzZWFyY2goY29uc3QgU3RyaW5nVHlwZSYgd2hlcmUsIFByZWRpY2F0ZSBwcmVkLCBTaXplVHlwZSBwb3MgPSAwKQp7CiAgICByZXR1cm4gc2VhcmNoKHdoZXJlLCBwcmVkLCBwb3MsIHdoZXJlLnNpemUoKS1wb3MpOwp9CgppbnQgbWFpbigpCnsKCXN0ZDo6Y291dCA8PCBzZWFyY2goIkhlbGxvIHdvcmxkInMsCgkJW10oYXV0byYmIHN0ciwgYXV0byBuKSB7IAogICAgICAgIAlyZXR1cm4gbiA+IDMgJiYKICAgICAgICAJCXN0clswXSA9PSAnbCcgJiYKICAgICAgICAJCXN0clsxXSA9PSAnbCc7IAogICAgICAgIH0KCSkgPDwgc3RkOjplbmRsOwogICAgICAgICAgICAgICAgICAgICAgICAKCXN0ZDo6Y291dCA8PCBzZWFyY2goTCJIZWxsbyB3b3JsZCJzLAoJCVtdKGF1dG8mJiBzdHIsIGF1dG8gbikgeyAKICAgICAgICAJcmV0dXJuIG4gPiAzICYmCiAgICAgICAgCQlzdHJbMF0gPT0gTCdsJyAmJgogICAgICAgICAgICAJc3RyWzFdID09IEwnbCc7IAogICAgICAgIH0KCSkgPDwgc3RkOjplbmRsOwoKCXJldHVybiAwOwp9