перевожу на С++ код с раста
там есть прикольный макрос matches
накидал по быстрому более менее похожее
из TODO это добавить std::ignore для пропуска аргументов
может кто улучит или дополнит
еще по правильному бы сделать static_assert в matches до вызова _impl на размер массива и количество аргументов
я начал было делать и он работает
но для этого нужно было делать больше перегрузок для span и обычного массива
иначе размерность не достать
а делать на одном span, нельзя в чистую захватить обычный массив
вообщем оставил с обычной ссылкой, котрая матчит и то и другое
по мере разгребания конюшен раста, может что то усовершенствую
а расте он конечно более мощнее и навороченее, полностю врядли можно повторить на плюсах такое
https://godbolt.org/z/67r7dadja
#include <cstdlib>
#include <iostream>
#include <memory>
#include <cassert>
#include <array>
#include <span>
template<typename T>
constexpr auto in(T min, T max)
{ return [=](const auto& x){ return min<=x && x<=max; }; }
template<typename T, typename Arg>
bool cmp(const T & arr, int idx, Arg && val)
{
if constexpr (!std::is_integral<Arg>::value)
return val(arr[idx]);
else return arr[idx] == val;
}
template<typename T, typename... Args, std::size_t... Is>
bool matches_impl(const T & arr, std::index_sequence<Is...>, Args && ...values)
{
return (cmp(arr,Is,std::forward<Args>(values)) && ...);
}
template<typename T, typename... Args>
bool matches(const T & arr, Args && ...values)
{
return matches_impl(arr,
std::index_sequence_for<Args...>{},
std::forward<Args>(values)...);
}
int main()
{
int a[3]={1,2,3};
std::array<int,4> aa{1,2,3,4};
assert(matches(std::span(a), [](int v){return v==1;},2,in(1,5)) );
assert(matches(std::span(a), 1,2,3) );
assert(matches(std::span(aa), 1,2,3,[](auto v){return v>3;}) );
assert(matches(aa, 1,2,3,[](auto v){return v>3;}) );
assert(matches(std::span(a), 1,2,3,[](auto v){return v>3;}) );
}