c++ matches like rust
От: reversecode google
Дата: 13.11.23 13:34
Оценка: 4 (1)
перевожу на С++ код с раста
там есть прикольный макрос 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;}) );
}
Отредактировано 13.11.2023 15:56 Великий Реверс . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.