#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iomanip>
#include <type_traits>
#include <typeinfo>
#ifndef _MSC_VER
# include <cxxabi.h>
#endif
#include <memory>
#include <string>
#include <cstdlib>
template <class T>
std::string
type_name()
{
typedef typename std::remove_reference<T>::type TR;
std::unique_ptr<char, void(*)(void*)> own
(
#ifndef _MSC_VER
abi::__cxa_demangle(typeid(TR).name(), nullptr,
nullptr, nullptr),
#else
nullptr,
#endif
std::free
);
std::string r = own != nullptr ? own.get() : typeid(TR).name();
if (std::is_const<TR>::value)
r += " const";
if (std::is_volatile<TR>::value)
r += " volatile";
if (std::is_lvalue_reference<T>::value)
r += "&";
else if (std::is_rvalue_reference<T>::value)
r += "&&";
return r;
}
template<typename T1, typename T2>
struct my_tuple {
T1 x;
T2 y;
my_tuple(const T1& x, const T2& y) : x(x), y(y) {
std::cout << "tuple(" << type_name<const T1&>() << "," << type_name<const T2&>() << ")" << std::endl;
}
my_tuple(my_tuple<T1,T2>&& other) : x(other.x), y(other.y) {
std::cout << "tuple(" << type_name<my_tuple<T1,T2>&&>() << ")" << std::endl;
}
my_tuple(const my_tuple<T1,T2>& other) : x(other.x), y(other.y) {
std::cout << "tuple(" << type_name<const my_tuple<T1,T2>&>() << ")" << std::endl;
}
my_tuple& operator=(my_tuple<T1,T2>&& other) {
std::cout << "tuple(" << type_name<my_tuple<T1,T2>&&>() << ")" << std::endl;
x = other.x; y = other.y;
}
my_tuple& operator=(const my_tuple<T1,T2>& other) {
std::cout << "tuple(" << type_name<const my_tuple<T1,T2>&>() << ")" << std::endl;
x = other.x; y = other.y;
}
};
template<typename T1, typename T2>
my_tuple<T1&, T2&> my_tie(T1& x, T2& y) {
return my_tuple<T1&, T2&>(x,y);
}
struct Foo {
int x, y;
Foo(int x, int y) : x(x), y(y) {
std::cout << "Foo(x,y)" << std::endl;
}
~Foo() {
std::cout << "~Foo()" << std::endl;
}
template<typename T1, typename T2>
operator my_tuple<T1, T2>() {
std::cout << "tuple conversion" << std::endl;
return my_tuple<T1, T2>(x, y);
}
};
int main()
{
int a, b;
my_tie(a, b) = Foo(3,4);
std::cout << a << ", " << b << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpZm5kZWYgX01TQ19WRVIKIyAgIGluY2x1ZGUgPGN4eGFiaS5oPgojZW5kaWYKI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGNzdGRsaWI+Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4Kc3RkOjpzdHJpbmcKdHlwZV9uYW1lKCkKewogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8VD46OnR5cGUgVFI7CiAgICBzdGQ6OnVuaXF1ZV9wdHI8Y2hhciwgdm9pZCgqKSh2b2lkKik+IG93bgogICAgICAgICAgICgKI2lmbmRlZiBfTVNDX1ZFUgogICAgICAgICAgICAgICAgYWJpOjpfX2N4YV9kZW1hbmdsZSh0eXBlaWQoVFIpLm5hbWUoKSwgbnVsbHB0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGxwdHIsIG51bGxwdHIpLAojZWxzZQogICAgICAgICAgICAgICAgbnVsbHB0ciwKI2VuZGlmCiAgICAgICAgICAgICAgICBzdGQ6OmZyZWUKICAgICAgICAgICApOwogICAgc3RkOjpzdHJpbmcgciA9IG93biAhPSBudWxscHRyID8gb3duLmdldCgpIDogdHlwZWlkKFRSKS5uYW1lKCk7CiAgICBpZiAoc3RkOjppc19jb25zdDxUUj46OnZhbHVlKQogICAgICAgIHIgKz0gIiBjb25zdCI7CiAgICBpZiAoc3RkOjppc192b2xhdGlsZTxUUj46OnZhbHVlKQogICAgICAgIHIgKz0gIiB2b2xhdGlsZSI7CiAgICBpZiAoc3RkOjppc19sdmFsdWVfcmVmZXJlbmNlPFQ+Ojp2YWx1ZSkKICAgICAgICByICs9ICImIjsKICAgIGVsc2UgaWYgKHN0ZDo6aXNfcnZhbHVlX3JlZmVyZW5jZTxUPjo6dmFsdWUpCiAgICAgICAgciArPSAiJiYiOwogICAgcmV0dXJuIHI7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4Kc3RydWN0IG15X3R1cGxlIHsKCVQxIHg7CglUMiB5OwoJbXlfdHVwbGUoY29uc3QgVDEmIHgsIGNvbnN0IFQyJiB5KSA6IHgoeCksIHkoeSkgewoJCXN0ZDo6Y291dCA8PCAidHVwbGUoIiA8PCB0eXBlX25hbWU8Y29uc3QgVDEmPigpIDw8ICIsIiA8PCB0eXBlX25hbWU8Y29uc3QgVDImPigpIDw8ICIpIiA8PCBzdGQ6OmVuZGw7Cgl9CglteV90dXBsZShteV90dXBsZTxUMSxUMj4mJiBvdGhlcikgOiB4KG90aGVyLngpLCB5KG90aGVyLnkpIHsKCQlzdGQ6OmNvdXQgPDwgInR1cGxlKCIgPDwgdHlwZV9uYW1lPG15X3R1cGxlPFQxLFQyPiYmPigpIDw8ICIpIiA8PCBzdGQ6OmVuZGw7Cgl9CglteV90dXBsZShjb25zdCBteV90dXBsZTxUMSxUMj4mIG90aGVyKSA6IHgob3RoZXIueCksIHkob3RoZXIueSkgewoJCXN0ZDo6Y291dCA8PCAidHVwbGUoIiA8PCB0eXBlX25hbWU8Y29uc3QgbXlfdHVwbGU8VDEsVDI+Jj4oKSA8PCAiKSIgPDwgc3RkOjplbmRsOwoJfQoJbXlfdHVwbGUmIG9wZXJhdG9yPShteV90dXBsZTxUMSxUMj4mJiBvdGhlcikgewoJCXN0ZDo6Y291dCA8PCAidHVwbGUoIiA8PCB0eXBlX25hbWU8bXlfdHVwbGU8VDEsVDI+JiY+KCkgPDwgIikiIDw8IHN0ZDo6ZW5kbDsKCQl4ID0gb3RoZXIueDsgeSA9IG90aGVyLnk7Cgl9CglteV90dXBsZSYgb3BlcmF0b3I9KGNvbnN0IG15X3R1cGxlPFQxLFQyPiYgb3RoZXIpIHsKCQlzdGQ6OmNvdXQgPDwgInR1cGxlKCIgPDwgdHlwZV9uYW1lPGNvbnN0IG15X3R1cGxlPFQxLFQyPiY+KCkgPDwgIikiIDw8IHN0ZDo6ZW5kbDsKCQl4ID0gb3RoZXIueDsgeSA9IG90aGVyLnk7Cgl9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+Cm15X3R1cGxlPFQxJiwgVDImPiBteV90aWUoVDEmIHgsIFQyJiB5KSB7CglyZXR1cm4gbXlfdHVwbGU8VDEmLCBUMiY+KHgseSk7Cn0KCgpzdHJ1Y3QgRm9vIHsKCWludCB4LCB5OwoJCglGb28oaW50IHgsIGludCB5KSA6IHgoeCksIHkoeSkgewoJCXN0ZDo6Y291dCA8PCAiRm9vKHgseSkiIDw8IHN0ZDo6ZW5kbDsKCX0KCX5Gb28oKSB7CgkJc3RkOjpjb3V0IDw8ICJ+Rm9vKCkiIDw8IHN0ZDo6ZW5kbDsKCX0KCQoJdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPgoJb3BlcmF0b3IgbXlfdHVwbGU8VDEsIFQyPigpIHsKCQlzdGQ6OmNvdXQgPDwgInR1cGxlIGNvbnZlcnNpb24iIDw8IHN0ZDo6ZW5kbDsKCQlyZXR1cm4gbXlfdHVwbGU8VDEsIFQyPih4LCB5KTsKCX0KfTsKCmludCBtYWluKCkKewoJaW50IGEsIGI7CglteV90aWUoYSwgYikgPSBGb28oMyw0KTsKCglzdGQ6OmNvdXQgPDwgYSA8PCAiLCAiIDw8IGIgPDwgc3RkOjplbmRsOwoKCXJldHVybiAwOwp9Cg==