Параметры шаблона итерации C ++ - PullRequest
0 голосов
/ 07 апреля 2020

Можно заполнить соответствующие регистры виртуальной машины на основе списка аргументов и некоторых логик c, используя сложение C ++ 17, например: https://github.com/fwsGonzo/libriscv/blob/master/lib/libriscv/machine_vmcall.hpp#L35

https://github.com/fwsGonzo/libriscv/blob/master/lib/libriscv/machine_vmcall.hpp#L18

Структуры будут помещены в стек, а адрес займет целочисленный слот регистра. Таким образом, я могу превратить обычный вызов функции в вызов моей виртуальной машины. Я не думаю, что какой-либо другой язык программирования может сделать это.

Теперь, с другой стороны, существуют обработчики системных вызовов. Они выглядят так: https://github.com/fwsGonzo/libriscv/blob/master/emulator/src/syscalls.cpp#L20

Чтобы упростить обработку системных вызовов, я хочу иметь возможность получить список типов аргументов, выполнить несколько логик c для каждого из их (извлеките значения, основанные на типе), а затем опционально вызовите лямбду с созданными мной аргументами.

Число и типы аргументов известны заранее. Значения неизвестны, пока они не будут извлечены из машинных регистров.

Спасибо @bipll за ответ. Я решил реализовать это так:

template<typename... Args, std::size_t... indices>
inline auto resolve_args(machine_t& m, std::index_sequence<indices...>)
{
    std::tuple<std::decay_t<Args>...> retval;
    ((std::get<indices>(retval) = m.template sysarg<Args>(indices)), ...);
    return retval;
}
template<typename... Args>
inline auto resolve_args(machine_t& m) {
    return resolve_args<Args...>(m, std::index_sequence_for<Args...>{});
}

1 Ответ

1 голос
/ 07 апреля 2020

Хм, это то, что вы ищете?

#include <iostream>
#include <type_traits>

template<class... Args> void omg(Args &&...args)
{
        ((std::is_integral_v<Args> && std::cout << args << " is integral\n"), ...);
}

int main() {
        omg(1, 42, 3.14, "Hi!", 0<<0);
}
1 is integral
42 is integral
0 is integral

operator, может быть швейцарским армейским ножом с одинарными выражениями foreach.

Вы не Для этого даже не нужны фактические значения:

template<class... Args> void omg()
{
        std::size_t i{};
        ((++i,
          std::is_integral_v<Args> && std::cout <<
                  "Arg #" << i << " is integral\n"
          || std::is_scalar_v<Args> && std::cout <<
                  "Arg #" << i << " is not integral, yet is scalar\n"
          ), ...);
}

int main() {
        omg<int, int, double, char const *, std::size_t>();
}

Если у вас нет фактических значений под рукой, но есть их типы и доступ к индексу, ну, вы можете легко получить их очень простым способом c :

template<class... Args, std::size_t... indices> void add_args(
        std::index_sequence<indices...>)
{
    (p.append(sys.get_arg<Args>(indices)), ...);
}

template<class... Args> void add_args() {
    add_args<Args...>(std::index_sequence_for<Args...>{});
}

Даже хранить их в кортеже немного сложно и не совсем просто:

std::tuple<std::decay_t<Args>...> retval;
((std::get<indices>(retval) = sys.get_arg<Args>(indices)), ...);
return retval;
...