#include <iostream>
#include <utility>
#include <array>
#include <tuple>
using ID = unsigned int;;
ID const maxID = 1<<8;
template <typename... Ts>
struct SOA {
std::tuple< std::array< Ts, maxID >... > a;
ID currentMaxID = 0;
};
template<unsigned...>struct indexes{using type=indexes;};
template<unsigned Max, unsigned...Is>struct make_indexes:make_indexes<Max-1,Max-1,Is...>{};
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};
template<unsigned Max>using make_indexes_t=typename make_indexes<Max>::type;
template<class T>using decay_t=typename std::decay<T>::type;
namespace details {
template <typename... Ts, unsigned... Is>
ID AddEntity(indexes<Is...>, SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
int unused[] = { ( (std::get<Is>(soa.a)[soa.currentMaxID] = ts), void(), 0 )..., 0 };
(void)(unused);
return soa.currentMaxID++;
}
template <typename... Ts, unsigned... Is>
void RemoveEntity(indexes<Is...>, SOA<Ts...>& soa, ID entityID) {
--soa.currentMaxID;
int unused[] = {
( (std::get<Is>(soa.a)[entityID] = std::get<Is>(soa.a)[soa.currentMaxID]),
void(), 0 )..., 0
};
(void)(unused);
}
}
template <typename... Ts>
ID AddEntity(SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
return details::AddEntity( make_indexes_t< sizeof...(Ts) >{}, soa, ts... );
}
template <typename...Ts>
void RemoveEntity(SOA<Ts...>& soa, ID entityID) {
details::RemoveEntity( make_indexes_t< sizeof...(Ts) >{}, soa, entityID );
}
int main() {
SOA<int, double> test;
AddEntity( test, 0, 3 );
RemoveEntity( test, 1 );
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8dHVwbGU+Cgp1c2luZyBJRCA9IHVuc2lnbmVkIGludDs7CklEIGNvbnN0IG1heElEID0gMTw8ODsKCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUcz4Kc3RydWN0IFNPQSB7CiAgc3RkOjp0dXBsZTwgc3RkOjphcnJheTwgVHMsIG1heElEID4uLi4gPiBhOwogIElEIGN1cnJlbnRNYXhJRCA9IDA7Cn07Cgp0ZW1wbGF0ZTx1bnNpZ25lZC4uLj5zdHJ1Y3QgaW5kZXhlc3t1c2luZyB0eXBlPWluZGV4ZXM7fTsKdGVtcGxhdGU8dW5zaWduZWQgTWF4LCB1bnNpZ25lZC4uLklzPnN0cnVjdCBtYWtlX2luZGV4ZXM6bWFrZV9pbmRleGVzPE1heC0xLE1heC0xLElzLi4uPnt9Owp0ZW1wbGF0ZTx1bnNpZ25lZC4uLklzPnN0cnVjdCBtYWtlX2luZGV4ZXM8MCxJcy4uLj46aW5kZXhlczxJcy4uLj57fTsKdGVtcGxhdGU8dW5zaWduZWQgTWF4PnVzaW5nIG1ha2VfaW5kZXhlc190PXR5cGVuYW1lIG1ha2VfaW5kZXhlczxNYXg+Ojp0eXBlOwp0ZW1wbGF0ZTxjbGFzcyBUPnVzaW5nIGRlY2F5X3Q9dHlwZW5hbWUgc3RkOjpkZWNheTxUPjo6dHlwZTsKCm5hbWVzcGFjZSBkZXRhaWxzIHsKICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVHMsIHVuc2lnbmVkLi4uIElzPgogIElEIEFkZEVudGl0eShpbmRleGVzPElzLi4uPiwgU09BPFRzLi4uPiYgc29hLCBkZWNheV90PFRzPiBjb25zdCYuLi4gdHMpIHsKICAgIGludCB1bnVzZWRbXSA9IHsgKCAoc3RkOjpnZXQ8SXM+KHNvYS5hKVtzb2EuY3VycmVudE1heElEXSA9IHRzKSwgdm9pZCgpLCAwICkuLi4sIDAgfTsKICAgICh2b2lkKSh1bnVzZWQpOwogICAgcmV0dXJuIHNvYS5jdXJyZW50TWF4SUQrKzsKICB9CiAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uIFRzLCB1bnNpZ25lZC4uLiBJcz4KICB2b2lkIFJlbW92ZUVudGl0eShpbmRleGVzPElzLi4uPiwgU09BPFRzLi4uPiYgc29hLCBJRCBlbnRpdHlJRCkgewogICAgLS1zb2EuY3VycmVudE1heElEOwogICAgaW50IHVudXNlZFtdID0gewogICAgICAoIChzdGQ6OmdldDxJcz4oc29hLmEpW2VudGl0eUlEXSA9IHN0ZDo6Z2V0PElzPihzb2EuYSlbc29hLmN1cnJlbnRNYXhJRF0pLAogICAgICB2b2lkKCksIDAgKS4uLiwgMAogICAgfTsKICAgICh2b2lkKSh1bnVzZWQpOwogIH0KfQp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVHM+CklEIEFkZEVudGl0eShTT0E8VHMuLi4+JiBzb2EsIGRlY2F5X3Q8VHM+IGNvbnN0Ji4uLiB0cykgewogIHJldHVybiBkZXRhaWxzOjpBZGRFbnRpdHkoIG1ha2VfaW5kZXhlc190PCBzaXplb2YuLi4oVHMpID57fSwgc29hLCB0cy4uLiApOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi5Ucz4Kdm9pZCBSZW1vdmVFbnRpdHkoU09BPFRzLi4uPiYgc29hLCBJRCBlbnRpdHlJRCkgewogIGRldGFpbHM6OlJlbW92ZUVudGl0eSggbWFrZV9pbmRleGVzX3Q8IHNpemVvZi4uLihUcykgPnt9LCBzb2EsIGVudGl0eUlEICk7Cn0KaW50IG1haW4oKSB7CglTT0E8aW50LCBkb3VibGU+IHRlc3Q7CglBZGRFbnRpdHkoIHRlc3QsIDAsIDMgKTsKCVJlbW92ZUVudGl0eSggdGVzdCwgMSApOwoJLy8geW91ciBjb2RlIGdvZXMgaGVyZQoJcmV0dXJuIDA7Cn0=