StructureOfArrays can push_back move-only types
This commit is contained in:
committed by
Mathias Agopian
parent
960c6170fe
commit
3c77d2c3f5
@@ -352,33 +352,55 @@ public:
|
||||
return push_back_unsafe(std::forward<Elements>(args)...);
|
||||
}
|
||||
|
||||
// in C++20 we could use a lambda with explicit template parameter instead
|
||||
struct PushBackUnsafeClosure {
|
||||
size_t last;
|
||||
std::tuple<Elements...> args;
|
||||
inline explicit PushBackUnsafeClosure(size_t last, Structure&& args)
|
||||
: last(last), args(std::forward<Structure>(args)) {}
|
||||
template<size_t I>
|
||||
inline void operator()(TypeAt<I>* p) {
|
||||
new(p + last) TypeAt<I>{ std::get<I>(args) };
|
||||
}
|
||||
};
|
||||
template <std::size_t... Indices>
|
||||
struct ElementIndices {};
|
||||
|
||||
template <std::size_t N, std::size_t... Indices>
|
||||
struct BuildElementIndices : BuildElementIndices<N - 1, N - 1, Indices...> {};
|
||||
|
||||
template <std::size_t... Indices>
|
||||
struct BuildElementIndices<0, Indices...> : ElementIndices<Indices...> {};
|
||||
|
||||
template<std::size_t... Indices>
|
||||
void push_back_unsafe(Structure&& args, ElementIndices<Indices...>){
|
||||
size_t last = mSize++;
|
||||
// Fold expression on the comma operator
|
||||
([&]{
|
||||
new(std::get<Indices>(mArrays) + last) Elements{std::get<Indices>(args)};
|
||||
}() , ...);
|
||||
}
|
||||
|
||||
template<std::size_t... Indices>
|
||||
void push_back_unsafe(Elements const& ... args, ElementIndices<Indices...>){
|
||||
size_t last = mSize++;
|
||||
// Fold expression on the comma operator
|
||||
([&]{
|
||||
new(std::get<Indices>(mArrays) + last) Elements{args};
|
||||
}() , ...);
|
||||
}
|
||||
|
||||
template<std::size_t... Indices>
|
||||
void push_back_unsafe(Elements && ... args, ElementIndices<Indices...>){
|
||||
size_t last = mSize++;
|
||||
// Fold expression on the comma operator
|
||||
([&]{
|
||||
new(std::get<Indices>(mArrays) + last) Elements{std::forward<Elements>(args)};
|
||||
}() , ...);
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Structure&& args) noexcept {
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, std::forward<Structure>(args) });
|
||||
push_back_unsafe(std::forward<Structure>(args), BuildElementIndices<sizeof...(Elements)>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Elements const& ... args) noexcept {
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, { args... } });
|
||||
push_back_unsafe(args..., BuildElementIndices<sizeof...(Elements)>{});
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Elements&& ... args) noexcept {
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, { std::forward<Elements>(args)... }});
|
||||
push_back_unsafe(std::forward<Elements>(args)..., BuildElementIndices<sizeof...(Elements)>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,3 +173,13 @@ TEST(StructureOfArraysTest, Simple) {
|
||||
soa.push_back(0.0f, 1.0, std::move(destroyedFloat4));
|
||||
}
|
||||
|
||||
TEST(StructureOfArraysTest, MoveOnly) {
|
||||
StructureOfArrays<float, std::unique_ptr<int32_t>> soa;
|
||||
soa.setCapacity(2);
|
||||
soa.push_back(1.0f, std::make_unique<int32_t>(1));
|
||||
soa.push_back(2.0f, std::make_unique<int32_t>(2));
|
||||
EXPECT_EQ(soa.size(), 2);
|
||||
EXPECT_EQ(*soa.elementAt<1>(0).get(), 1);
|
||||
EXPECT_EQ(*soa.elementAt<1>(1).get(), 2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user