- #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==