Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Convert tuple of homogeneous wrapped type to tuple of raw type

I'd like to call std::apply() to a function; however, I am unable to because the std::tuple I use is currently wrapped. For example:

#include <tuple>

template <class T>
struct wrapped
{
    wrapped(T t) : t(t) {}

    T t;
};

template <class T, class ... Args>
struct delay_call
{
    T(*callback)(Args...);
    std::tuple<Args...> params;

    delay_call(T(*callback)(Args...), Args ... params) :
        callback(callback), params(params...)
    {}

    T call()
    {
        return std::apply(callback, params);
    }
};

template <class T, class ... Args>
struct delay_call_with_wrap
{
    T(*callback)(Args...);
    std::tuple<wrapped<Args>...> w_params;

    delay_call_with_wrap(T(*callback)(Args...), wrapped<Args> ... w_params) :
        callback(callback), w_params(w_params...)
    {}

    T call()
    {
        std::tuple<Args...> params; // = w_params.t
        return std::apply(callback, actual_params);
    }
};

float saxpy(float a, float x, float y)
{
    return a * x + y;
}

int main()
{
    float a = 1, x = 2, y = 3;
    delay_call delay_saxpy(saxpy, a, x, y);

    wrapped w_a = 1.f, w_x = 2.f, w_y = 3.f;
    delay_call_with_wrap w_delay_saxpy(saxpy, w_a, w_x, w_y);

    float result = delay_saxpy.call();

    float w_result = w_delay_saxpy.call();
}

the delay_call struct works as expected; however, I am unsure how to go about extracting the actual value of each tuple element and giving that to std::apply() to execute.

In short, for delay_call_with_wrap::call, how would I convert std::tuple<wrapped<Args>...> to a std::tuple<Args...>?

like image 595
Michael Choi Avatar asked Jan 27 '23 20:01

Michael Choi


1 Answers

I would avoid std::apply completely and call the callback directly by unpacking the tuple using std::index_sequence:

template <std::size_t ...I> T call_low(std::index_sequence<I...>)
{
    return callback(std::get<I>(w_params).t...);
}

T call()
{
    return call_low(std::make_index_sequence<sizeof...(Args)>{});
}
like image 130
HolyBlackCat Avatar answered Feb 01 '23 11:02

HolyBlackCat