c++stdstd-rangesstructure-of-arrays

How to copy values from array to array of structures?


In the code below I could use convenient syntax of std::ranges::transform to copy values from array of structures (AoS) to structure of arrays (SoA) (in this example, just one vector). Is there a way to do the same in opposite way, copying data from a specific field of structure when I need to copy values from SoA to AoS?

Specifically, is there a way to replace for-loop in the code below with some algorithm call (ranges of views would be preferrable)?

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>

struct S
{
    float v1;
    float v2;
};

int main() {
    std::vector<S> aos = { { 1.0f, 2.0f } };
    std::vector<float> soa(aos.size());

    std::ranges::transform(aos, soa.begin(), &S::v1);

    std::cout << "soa value:" << soa[0] << std::endl;

    soa[0] = 3.0;

    // I want to replace this with something transform-like above
    for (std::size_t i = 0; i < soa.size(); ++i)
    {
        aos[i].v1 = soa[i];
    }

    std::cout << "aos value:" << aos[0].v1 << std::endl;
}

Demo


Solution

  • You can copy the data into transform view of v1 without touching member v2:

    auto as_v1 = aos | std::views::transform(&S::v1);
    std::ranges::copy(soa, as_v1.begin());
    

    Demo