#include <concepts>
#include <iostream>

template <std::predicate<int> Pred>
void fun(Pred pred, int value)
{
    std::cout << pred(value) << '\n';
}

template <typename Container, typename Value>
size_t findIdx(Container const &cont, size_t from, Value const &value)
//    requires FindConcept<Container, Value>
{
    auto iter = std::find(cont.begin() + from, cont.end(), value);
    return iter == cont.end() ? cont.size() : iter - cont.begin();
}

template <typename Container>
concept StdContainer =
    requires()
    {
        typename Container::const_iterator;
        typename Container::value_type;
    };

    //  begin(), end() members -> Container::const_iterator
    //  Container::const_iterator + int -> Container::const_iterator
    //  Container::const_iterator - Container::const_iterator -> int
    //  Predicate(Container::value_type)

template <typename Type>
concept Iter =
    requires(Type lhs, Type rhs)
    {
        { lhs - rhs } -> std::convertible_to<int>; // or: same_as<long int>
        { lhs + 0 }   -> std::same_as<Type>;
    };


#include <algorithm>
#include <string>

//predicate
template <typename Container, typename Predicate>
concept Find_ifConcept =
    std::predicate<Predicate, typename Container::value_type>
    and
    requires(Container container)
    {
        { container.begin() } -> Iter;
        { container.end() }   -> Iter;
        { container.size() }  -> std::same_as<size_t>;
    };

template <typename Container, typename Predicate>
size_t findIdx_if(Container const &cont, size_t from, Predicate const &pred)
    requires Find_ifConcept<Container, Predicate>
{
    auto iter = std::find_if(cont.begin() + from, cont.end(), pred);
    return iter == cont.end() ? cont.size() : iter - cont.begin();
}

int main()
{
    std::cout << "Index at " <<
        findIdx_if(std::string{ "hello world" }, 0,
            [&](int ch)
            {
                return ch == ' ';
            }
        ) << '\n';

    int target = 4;
    fun(
        [&](int value)
        {
            return value == target;
        },
        4
    );
}
//=
