#include <iostream>
#include <type_traits>
#include <array>
#include <utility>
#include <tuple>
//get_size
template <typename T_head>
constexpr size_t get_size()
{
return sizeof(T_head);
}
template <typename T_head, typename T_second, typename... T_tail>
constexpr size_t get_size()
{
return get_size<T_head>() + get_size<T_second, T_tail...>();
}
//concat
template<size_t N1, size_t... I1, size_t N2, size_t... I2>
constexpr std::array<size_t, N1+N2> concat(const std::array<size_t, N1>& a1, const std::array<size_t, N2>& a2, std::index_sequence<I1...>, std::index_sequence<I2...>)
{
return { a1[I1]..., a2[I2]... };
}
template<size_t N1, size_t N2>
constexpr std::array<size_t, N1+N2> concat(const std::array<size_t, N1>& a1, const std::array<size_t, N2>& a2)
{
return concat(a1, a2, std::make_index_sequence<N1>{}, std::make_index_sequence<N2>{});
}
//make_index_array
template<size_t T_offset, typename T_head>
constexpr std::array<size_t, 1> make_index_array()
{
return {T_offset};
}
template<size_t T_offset, typename T_head, typename T_Second, typename... T_tail>
constexpr std::array<size_t, (sizeof...(T_tail) + 2)> make_index_array()
{
return concat(
make_index_array<T_offset, T_head>(),
make_index_array<T_offset + sizeof(T_head),T_Second, T_tail...>()
);
}
template<typename... T_args>
constexpr std::array<size_t, (sizeof...(T_args))> make_index_array()
{
return make_index_array<0, T_args...>();
}
template<int N, typename... Ts>
using T_param = typename std::tuple_element<N, std::tuple<Ts...>>::type;
template <typename... T_args>
struct standard_layout_tuple
{
static constexpr std::array<size_t, sizeof...(T_args)> index_array = make_index_array<T_args...>();
char storage[get_size<T_args...>()];
//Initialization
template<size_t T_index, typename T_val>
void initialize(T_val&& val)
{
void* place = &this->storage[index_array[T_index]];
new(place) T_val(std::forward<T_val>(val));
}
template<size_t T_index, typename T_val, typename T_val2, typename... T_vals_rest>
void initialize(T_val&& val, T_val2&& val2, T_vals_rest&&... vals_rest)
{
initialize<T_index, T_val>(std::forward<T_val>(val));
initialize<T_index+1, T_val2, T_vals_rest...>(std::forward<T_val2>(val2), std::forward<T_vals_rest>(vals_rest)...);
}
void initialize(T_args&&... args)
{
initialize<0, T_args...>(std::forward<T_args>(args)...);
}
standard_layout_tuple(T_args&&... args)
{
initialize(std::forward<T_args>(args)...);
}
//Destruction
template<size_t T_index, typename T_val>
void destroy()
{
T_val* place = reinterpret_cast<T_val*>(&this->storage[index_array[T_index]]);
place->~T_val();
}
template<size_t T_index, typename T_val, typename T_val2, typename... T_vals_rest>
void destroy()
{
destroy<T_index, T_val>();
destroy<T_index+1, T_val2, T_vals_rest...>();
}
void destroy()
{
destroy<0, T_args...>();
}
~standard_layout_tuple()
{
destroy();
}
template<size_t T_index>
void set(T_param<T_index, T_args...>&& data)
{
T_param<T_index, T_args...>* ptr = reinterpret_cast<T_param<T_index, T_args...>*>(&this->storage[index_array[T_index]]);
*ptr = std::forward<T_param<T_index, T_args...>>(data);
}
template<size_t T_index>
T_param<T_index, T_args...>& get()
{
return *reinterpret_cast<T_param<T_index, T_args...>*>(&this->storage[index_array[T_index]]);
}
};
int main() {
standard_layout_tuple<float, double, int, double> sltuple{5.5f, 3.4, 7, 1.22};
sltuple.set<2>(47);
std::cout << sltuple.get<0>() << std::endl;
std::cout << sltuple.get<1>() << std::endl;
std::cout << sltuple.get<2>() << std::endl;
std::cout << sltuple.get<3>() << std::endl;
std::cout << "is standard layout:" << std::endl;
std::cout << std::boolalpha << std::is_standard_layout<standard_layout_tuple<float, double, int, double>>::value << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxhcnJheT4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0dXBsZT4KCi8vZ2V0X3NpemUKdGVtcGxhdGUgPHR5cGVuYW1lIFRfaGVhZD4KY29uc3RleHByIHNpemVfdCBnZXRfc2l6ZSgpCnsKCXJldHVybiBzaXplb2YoVF9oZWFkKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFRfaGVhZCwgdHlwZW5hbWUgVF9zZWNvbmQsIHR5cGVuYW1lLi4uIFRfdGFpbD4KY29uc3RleHByIHNpemVfdCBnZXRfc2l6ZSgpCnsKCXJldHVybiBnZXRfc2l6ZTxUX2hlYWQ+KCkgKyBnZXRfc2l6ZTxUX3NlY29uZCwgVF90YWlsLi4uPigpOwp9CgoKLy9jb25jYXQKdGVtcGxhdGU8c2l6ZV90IE4xLCBzaXplX3QuLi4gSTEsIHNpemVfdCBOMiwgc2l6ZV90Li4uIEkyPgpjb25zdGV4cHIgc3RkOjphcnJheTxzaXplX3QsIE4xK04yPiBjb25jYXQoY29uc3Qgc3RkOjphcnJheTxzaXplX3QsIE4xPiYgYTEsIGNvbnN0IHN0ZDo6YXJyYXk8c2l6ZV90LCBOMj4mIGEyLCBzdGQ6OmluZGV4X3NlcXVlbmNlPEkxLi4uPiwgc3RkOjppbmRleF9zZXF1ZW5jZTxJMi4uLj4pCnsKICByZXR1cm4geyBhMVtJMV0uLi4sIGEyW0kyXS4uLiB9Owp9Cgp0ZW1wbGF0ZTxzaXplX3QgTjEsIHNpemVfdCBOMj4KY29uc3RleHByIHN0ZDo6YXJyYXk8c2l6ZV90LCBOMStOMj4gY29uY2F0KGNvbnN0IHN0ZDo6YXJyYXk8c2l6ZV90LCBOMT4mIGExLCBjb25zdCBzdGQ6OmFycmF5PHNpemVfdCwgTjI+JiBhMikKewoJcmV0dXJuIGNvbmNhdChhMSwgYTIsIHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTxOMT57fSwgc3RkOjptYWtlX2luZGV4X3NlcXVlbmNlPE4yPnt9KTsKfQoKCi8vbWFrZV9pbmRleF9hcnJheQp0ZW1wbGF0ZTxzaXplX3QgVF9vZmZzZXQsIHR5cGVuYW1lIFRfaGVhZD4KY29uc3RleHByIHN0ZDo6YXJyYXk8c2l6ZV90LCAxPiBtYWtlX2luZGV4X2FycmF5KCkKewoJcmV0dXJuIHtUX29mZnNldH07Cn0KCnRlbXBsYXRlPHNpemVfdCBUX29mZnNldCwgdHlwZW5hbWUgVF9oZWFkLCB0eXBlbmFtZSBUX1NlY29uZCwgdHlwZW5hbWUuLi4gVF90YWlsPgpjb25zdGV4cHIgc3RkOjphcnJheTxzaXplX3QsIChzaXplb2YuLi4oVF90YWlsKSArIDIpPiBtYWtlX2luZGV4X2FycmF5KCkKewoJcmV0dXJuIGNvbmNhdCgKCQltYWtlX2luZGV4X2FycmF5PFRfb2Zmc2V0LCBUX2hlYWQ+KCksCgkJbWFrZV9pbmRleF9hcnJheTxUX29mZnNldCArIHNpemVvZihUX2hlYWQpLFRfU2Vjb25kLCBUX3RhaWwuLi4+KCkKCSk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lLi4uIFRfYXJncz4KY29uc3RleHByIHN0ZDo6YXJyYXk8c2l6ZV90LCAoc2l6ZW9mLi4uKFRfYXJncykpPiBtYWtlX2luZGV4X2FycmF5KCkKewoJcmV0dXJuIG1ha2VfaW5kZXhfYXJyYXk8MCwgVF9hcmdzLi4uPigpOwp9CgoKdGVtcGxhdGU8aW50IE4sIHR5cGVuYW1lLi4uIFRzPgp1c2luZyBUX3BhcmFtID0gdHlwZW5hbWUgc3RkOjp0dXBsZV9lbGVtZW50PE4sIHN0ZDo6dHVwbGU8VHMuLi4+Pjo6dHlwZTsKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVF9hcmdzPgpzdHJ1Y3Qgc3RhbmRhcmRfbGF5b3V0X3R1cGxlCnsKCXN0YXRpYyBjb25zdGV4cHIgc3RkOjphcnJheTxzaXplX3QsIHNpemVvZi4uLihUX2FyZ3MpPiBpbmRleF9hcnJheSA9IG1ha2VfaW5kZXhfYXJyYXk8VF9hcmdzLi4uPigpOwoJCgljaGFyIHN0b3JhZ2VbZ2V0X3NpemU8VF9hcmdzLi4uPigpXTsKCQoJLy9Jbml0aWFsaXphdGlvbgoJdGVtcGxhdGU8c2l6ZV90IFRfaW5kZXgsIHR5cGVuYW1lIFRfdmFsPgoJdm9pZCBpbml0aWFsaXplKFRfdmFsJiYgdmFsKQoJewoJCXZvaWQqIHBsYWNlID0gJnRoaXMtPnN0b3JhZ2VbaW5kZXhfYXJyYXlbVF9pbmRleF1dOwoJCW5ldyhwbGFjZSkgVF92YWwoc3RkOjpmb3J3YXJkPFRfdmFsPih2YWwpKTsKCX0KCQoJdGVtcGxhdGU8c2l6ZV90IFRfaW5kZXgsIHR5cGVuYW1lIFRfdmFsLCB0eXBlbmFtZSBUX3ZhbDIsIHR5cGVuYW1lLi4uIFRfdmFsc19yZXN0PgoJdm9pZCBpbml0aWFsaXplKFRfdmFsJiYgdmFsLCBUX3ZhbDImJiB2YWwyLCBUX3ZhbHNfcmVzdCYmLi4uIHZhbHNfcmVzdCkKCXsKCQlpbml0aWFsaXplPFRfaW5kZXgsIFRfdmFsPihzdGQ6OmZvcndhcmQ8VF92YWw+KHZhbCkpOwoJCWluaXRpYWxpemU8VF9pbmRleCsxLCBUX3ZhbDIsIFRfdmFsc19yZXN0Li4uPihzdGQ6OmZvcndhcmQ8VF92YWwyPih2YWwyKSwgc3RkOjpmb3J3YXJkPFRfdmFsc19yZXN0Pih2YWxzX3Jlc3QpLi4uKTsKCX0KCQoJdm9pZCBpbml0aWFsaXplKFRfYXJncyYmLi4uIGFyZ3MpCgl7CgkJaW5pdGlhbGl6ZTwwLCBUX2FyZ3MuLi4+KHN0ZDo6Zm9yd2FyZDxUX2FyZ3M+KGFyZ3MpLi4uKTsKCX0KCQoJc3RhbmRhcmRfbGF5b3V0X3R1cGxlKFRfYXJncyYmLi4uIGFyZ3MpCgl7CgkJaW5pdGlhbGl6ZShzdGQ6OmZvcndhcmQ8VF9hcmdzPihhcmdzKS4uLik7Cgl9CgkKCS8vRGVzdHJ1Y3Rpb24KCXRlbXBsYXRlPHNpemVfdCBUX2luZGV4LCB0eXBlbmFtZSBUX3ZhbD4KCXZvaWQgZGVzdHJveSgpCgl7CgkJVF92YWwqIHBsYWNlID0gcmVpbnRlcnByZXRfY2FzdDxUX3ZhbCo+KCZ0aGlzLT5zdG9yYWdlW2luZGV4X2FycmF5W1RfaW5kZXhdXSk7CgkJcGxhY2UtPn5UX3ZhbCgpOwoJfQoJCgl0ZW1wbGF0ZTxzaXplX3QgVF9pbmRleCwgdHlwZW5hbWUgVF92YWwsIHR5cGVuYW1lIFRfdmFsMiwgdHlwZW5hbWUuLi4gVF92YWxzX3Jlc3Q+Cgl2b2lkIGRlc3Ryb3koKQoJewoJCWRlc3Ryb3k8VF9pbmRleCwgVF92YWw+KCk7CgkJZGVzdHJveTxUX2luZGV4KzEsIFRfdmFsMiwgVF92YWxzX3Jlc3QuLi4+KCk7Cgl9CgkKCXZvaWQgZGVzdHJveSgpCgl7CgkJZGVzdHJveTwwLCBUX2FyZ3MuLi4+KCk7Cgl9CgkKCX5zdGFuZGFyZF9sYXlvdXRfdHVwbGUoKQoJewoJCWRlc3Ryb3koKTsKCX0KCgl0ZW1wbGF0ZTxzaXplX3QgVF9pbmRleD4KCXZvaWQgc2V0KFRfcGFyYW08VF9pbmRleCwgVF9hcmdzLi4uPiYmIGRhdGEpCgl7CgkJVF9wYXJhbTxUX2luZGV4LCBUX2FyZ3MuLi4+KiBwdHIgPSByZWludGVycHJldF9jYXN0PFRfcGFyYW08VF9pbmRleCwgVF9hcmdzLi4uPio+KCZ0aGlzLT5zdG9yYWdlW2luZGV4X2FycmF5W1RfaW5kZXhdXSk7CgkJKnB0ciA9IHN0ZDo6Zm9yd2FyZDxUX3BhcmFtPFRfaW5kZXgsIFRfYXJncy4uLj4+KGRhdGEpOwoJfQoJCgl0ZW1wbGF0ZTxzaXplX3QgVF9pbmRleD4KCVRfcGFyYW08VF9pbmRleCwgVF9hcmdzLi4uPiYgZ2V0KCkKCXsKCQlyZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8VF9wYXJhbTxUX2luZGV4LCBUX2FyZ3MuLi4+Kj4oJnRoaXMtPnN0b3JhZ2VbaW5kZXhfYXJyYXlbVF9pbmRleF1dKTsKCX0KfTsKCgppbnQgbWFpbigpIHsKCXN0YW5kYXJkX2xheW91dF90dXBsZTxmbG9hdCwgZG91YmxlLCBpbnQsIGRvdWJsZT4gc2x0dXBsZXs1LjVmLCAzLjQsIDcsIDEuMjJ9OwoJc2x0dXBsZS5zZXQ8Mj4oNDcpOwoJCglzdGQ6OmNvdXQgPDwgc2x0dXBsZS5nZXQ8MD4oKSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgc2x0dXBsZS5nZXQ8MT4oKSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgc2x0dXBsZS5nZXQ8Mj4oKSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgc2x0dXBsZS5nZXQ8Mz4oKSA8PCBzdGQ6OmVuZGw7CgoJc3RkOjpjb3V0IDw8ICJpcyBzdGFuZGFyZCBsYXlvdXQ6IiA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgc3RkOjpib29sYWxwaGEgPDwgc3RkOjppc19zdGFuZGFyZF9sYXlvdXQ8c3RhbmRhcmRfbGF5b3V0X3R1cGxlPGZsb2F0LCBkb3VibGUsIGludCwgZG91YmxlPj46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKCglyZXR1cm4gMDsKfQ==