#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;
}