0

Let's say I have a function

template<typename retScalar, typename... scalars>
retScalar func_scalar(scalars... items); 

declared somewhere.

I now want a "array" version of this function

template<typename retScalar, typename... scalars>
std::array<retScalar, LEN> func_vec(std::tuple<std::array<scalars, LEN>...> vecs) {
     std::array<retScalar, LEN> res; // initialized somehow
     for (int i = 0; i < LEN; ++i) {
        res[i] = func_scalar(/* ?? */);
     }

     return res;
}

I searched a lot and don't see any correct way to do that.

Regis Portalez
  • 4,675
  • 1
  • 29
  • 41
  • You could [convert the arrays into tuples](https://stackoverflow.com/questions/37029886/how-to-construct-a-tuple-from-an-array), and then use `std::apply` to call `func_scalar` on the resulting tuples. – NathanOliver May 19 '22 at 13:36
  • @NathanOliver Sorry but I don't see how that helps – Regis Portalez May 19 '22 at 13:42

1 Answers1

0

Thanks to another anwser, I found this solution, which I find pretty cool and probably useful for other people

#include <cstdio>
 #include <tuple>

template<typename T>
struct myvect {
    T data[4];

};

template<typename... Ts>
struct helper {
    template<std::size_t... I> 
    static auto inner(int index, std::tuple<myvect<Ts>...> vects, std::index_sequence<I...>)
    {
        return std::make_tuple(std::get<I>(vects).data[index]...);
    }
};

template<typename... Ts>
auto elements(int index, std::tuple<myvect<Ts>...> vectors)
{
    return helper<Ts...>::template inner(index, vectors, std::index_sequence_for<Ts...>{});
}

template<typename retS, typename... args> 
struct vectorize {
    template<retS(*funcptr)(args...)>
    static myvect<retS> func_vect(std::tuple<myvect<args>...> v) {
        myvect<retS> res;
        for (int i = 0; i < 4; ++i) {
            res.data[i] = std::apply(funcptr, elements(i, v));
        }

        return res;
    }
};

int test(int a, int b) {
    return a + b;
}

int main() {
    myvect<int> a { 1, 2, 3, 4 };
    myvect<int> b { 2, 4, 6, 8 };
    auto added = vectorize<int, int, int>::func_vect<&test>(std::make_tuple(a, b));

    for (int i = 0; i < 4; ++i) {
        printf("%d\n", added.data[i]);
    }
}
Regis Portalez
  • 4,675
  • 1
  • 29
  • 41