#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
template<typename... T> class tuple;
template<> class tuple<> {};
template<typename H, typename... T>
class tuple<H, T...> : private tuple<T...>
{
typedef tuple<T...> inherited;
public:
tuple() {}
tuple(typename std::add_lvalue_reference<typename std::add_const<H>::type>::type v,
typename std::add_lvalue_reference<typename std::add_const<T>::type>::type... vtail)
: inherited(vtail...), m_head(v) { }
template<typename... VValues>
tuple(const tuple<VValues...>& other)
: inherited(other.tail()), m_head(other.head()) { }
template<typename... VValues>
tuple& operator=(const tuple<VValues...>& other)
{
m_head = other.head();
tail() = other.tail();
return *this;
}
typename std::add_lvalue_reference<H>::type head() { return m_head; }
typename std::add_lvalue_reference<const H>::type head() const { return m_head; }
inherited& tail() { return *this; }
const inherited& tail() const { return *this; }
protected:
H m_head;
};
template<class... T>
tuple<T...> make_tuple(T&&... t)
{
return tuple<T...>(t...);
}
int main()
{
tuple<std::string, std::vector<int>, double> tt("hello", {1,2,3,4}, 1.2);
std::string h = tt.head();
tuple<std::vector<int>, double> t2 = tt.tail();
std::string s = "Hello";
std::vector<int> v = {1,22,3,4,5};
auto x = make_tuple(s, v, 1.2);
std::cout << "tt.head is " << tt.head() << '\n'
<< "t2.tail.head is " << t2.tail().head() << '\n'
<< " x.head is " << x.head() << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUPiBjbGFzcyB0dXBsZTsKdGVtcGxhdGU8PiBjbGFzcyB0dXBsZTw+IHt9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBILCB0eXBlbmFtZS4uLiBUPgpjbGFzcyB0dXBsZTxILCBULi4uPiA6IHByaXZhdGUgdHVwbGU8VC4uLj4KewogICAgdHlwZWRlZiB0dXBsZTxULi4uPiBpbmhlcml0ZWQ7CiBwdWJsaWM6CiAgICB0dXBsZSgpIHt9CiAgICB0dXBsZSh0eXBlbmFtZSBzdGQ6OmFkZF9sdmFsdWVfcmVmZXJlbmNlPHR5cGVuYW1lIHN0ZDo6YWRkX2NvbnN0PEg+Ojp0eXBlPjo6dHlwZSB2LAogICAgICAgICAgdHlwZW5hbWUgc3RkOjphZGRfbHZhbHVlX3JlZmVyZW5jZTx0eXBlbmFtZSBzdGQ6OmFkZF9jb25zdDxUPjo6dHlwZT46OnR5cGUuLi4gdnRhaWwpCiAgICAgICAgOiBpbmhlcml0ZWQodnRhaWwuLi4pLCBtX2hlYWQodikgeyB9CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBWVmFsdWVzPgogICAgdHVwbGUoY29uc3QgdHVwbGU8VlZhbHVlcy4uLj4mIG90aGVyKQogICAgICAgIDogaW5oZXJpdGVkKG90aGVyLnRhaWwoKSksIG1faGVhZChvdGhlci5oZWFkKCkpIHsgfQogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gVlZhbHVlcz4KICAgIHR1cGxlJiBvcGVyYXRvcj0oY29uc3QgdHVwbGU8VlZhbHVlcy4uLj4mIG90aGVyKQogICAgewogICAgICAgIG1faGVhZCA9IG90aGVyLmhlYWQoKTsKICAgICAgICB0YWlsKCkgPSBvdGhlci50YWlsKCk7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQogICAgdHlwZW5hbWUgc3RkOjphZGRfbHZhbHVlX3JlZmVyZW5jZTxIPjo6dHlwZSBoZWFkKCkgeyByZXR1cm4gbV9oZWFkOyB9CiAgICB0eXBlbmFtZSBzdGQ6OmFkZF9sdmFsdWVfcmVmZXJlbmNlPGNvbnN0IEg+Ojp0eXBlIGhlYWQoKSBjb25zdCB7IHJldHVybiBtX2hlYWQ7IH0KCiAgICBpbmhlcml0ZWQmIHRhaWwoKSB7IHJldHVybiAqdGhpczsgfQogICAgY29uc3QgaW5oZXJpdGVkJiB0YWlsKCkgY29uc3QgeyByZXR1cm4gKnRoaXM7IH0KIHByb3RlY3RlZDoKICAgICBIIG1faGVhZDsKfTsKCnRlbXBsYXRlPGNsYXNzLi4uIFQ+CnR1cGxlPFQuLi4+IG1ha2VfdHVwbGUoVCYmLi4uIHQpCnsKICAgIHJldHVybiB0dXBsZTxULi4uPih0Li4uKTsKfQoKaW50IG1haW4oKQp7CiAgICB0dXBsZTxzdGQ6OnN0cmluZywgc3RkOjp2ZWN0b3I8aW50PiwgZG91YmxlPiB0dCgiaGVsbG8iLCB7MSwyLDMsNH0sIDEuMik7CiAgICBzdGQ6OnN0cmluZyBoID0gdHQuaGVhZCgpOwogICAgdHVwbGU8c3RkOjp2ZWN0b3I8aW50PiwgZG91YmxlPiB0MiA9IHR0LnRhaWwoKTsKCiAgICBzdGQ6OnN0cmluZyBzID0gIkhlbGxvIjsKICAgIHN0ZDo6dmVjdG9yPGludD4gdiA9IHsxLDIyLDMsNCw1fTsKICAgIGF1dG8geCA9IG1ha2VfdHVwbGUocywgdiwgMS4yKTsKCiAgICBzdGQ6OmNvdXQgPDwgInR0LmhlYWQgaXMgIiA8PCB0dC5oZWFkKCkgPDwgJ1xuJwogICAgICAgICAgICAgIDw8ICJ0Mi50YWlsLmhlYWQgaXMgIiA8PCB0Mi50YWlsKCkuaGVhZCgpIDw8ICdcbicKICAgICAgICAgICAgICA8PCAiIHguaGVhZCBpcyAiIDw8IHguaGVhZCgpIDw8ICdcbic7Cn0K