#include <iostream>
#include <utility>
#include <cstring>
class S {
public:
S(const char* s) : l(std::strlen(s)), s(new char[l+1]) { std::strcpy(this->s, s); }
S(const S& o) : l(o.l), s(new char[l+1]) { strcpy(s, o.s); }
S& operator = (S o)
{
swap(o);
return *this;
}
~S() { delete [] s; }
void swap(S& o)
{
using std::swap;
swap(l, o.l);
swap(s, o.s);
}
friend std::ostream& operator << (std::ostream& os, const S& s) { return os << s.s; }
private:
size_t l;
char* s;
};
class A {
public:
A(const char* s) : s(s) {}
A(const A& o) : s(o.s) {}
A& operator = (A o)
{
swap(o);
return *this;
}
virtual ~A() {}
void swap(A& o)
{
s.swap(o.s);
}
friend std::ostream& operator << (std::ostream& os, const A& a) { return os << a.s; }
private:
S s;
};
template <int N>
class B : public virtual A {
public:
B(const char* sA, const char* s) : A(sA), s(s) {}
B(const B& o) : A(o), s(o.s) {}
B& operator = (B o)
{
swap(o);
return *this;
}
virtual ~B() {}
void swap(B& o)
{
A::swap(o);
s.swap(o.s);
}
friend std::ostream& operator << (std::ostream& os, const B& b)
{ return os << (const A&)b << ',' << b.s; }
private:
S s;
};
class D : public B<1>, public B<2> {
public:
D(const char* sA, const char* sB1, const char* sB2, const char* s)
: A(sA), B<1>(sA, sB1), B<2>(sA, sB2), s(s)
{}
D(const D& o) : A(o), B<1>(o), B<2>(o), s(o.s) {}
D& operator = (D o)
{
swap(o);
return *this;
}
virtual ~D() {}
void swap(D& o)
{
B<1>::swap(o); // calls A::swap(o); A::s changed to o.s
B<2>::swap(o); // calls A::swap(o); A::s returned to original value...
s.swap(o.s);
}
friend std::ostream& operator << (std::ostream& os, const D& d)
{
// prints A::s twice...
return os
<< (const B<1>&)d << ','
<< (const B<2>&)d << ','
<< d.s;
}
private:
S s;
};
int main() {
D x("ax", "b1x", "b2x", "x");
D y("ay", "b1y", "b2y", "y");
std::cout << x << "\n" << y << "\n";
x = y;
std::cout << x << "\n" << y << "\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGNzdHJpbmc+CgpjbGFzcyBTIHsKcHVibGljOgogIFMoY29uc3QgY2hhciogcykgOiBsKHN0ZDo6c3RybGVuKHMpKSwgcyhuZXcgY2hhcltsKzFdKSB7IHN0ZDo6c3RyY3B5KHRoaXMtPnMsIHMpOyB9CiAgUyhjb25zdCBTJiBvKSA6IGwoby5sKSwgcyhuZXcgY2hhcltsKzFdKSB7IHN0cmNweShzLCBvLnMpOyB9CiAgUyYgb3BlcmF0b3IgPSAoUyBvKQogIHsKICAgICBzd2FwKG8pOwogICAgIHJldHVybiAqdGhpczsKICB9CiAgflMoKSB7IGRlbGV0ZSBbXSBzOyB9CiAgdm9pZCBzd2FwKFMmIG8pCiAgewogICAgIHVzaW5nIHN0ZDo6c3dhcDsKICAgICBzd2FwKGwsIG8ubCk7CiAgICAgc3dhcChzLCBvLnMpOwogIH0KICBmcmllbmQgc3RkOjpvc3RyZWFtJiBvcGVyYXRvciA8PCAoc3RkOjpvc3RyZWFtJiBvcywgY29uc3QgUyYgcykgeyByZXR1cm4gb3MgPDwgcy5zOyB9CnByaXZhdGU6CiAgc2l6ZV90IGw7CiAgY2hhciogczsKfTsKCmNsYXNzIEEgewpwdWJsaWM6CiAgQShjb25zdCBjaGFyKiBzKSA6IHMocykge30KICBBKGNvbnN0IEEmIG8pIDogcyhvLnMpIHt9CiAgQSYgb3BlcmF0b3IgPSAoQSBvKQogIHsKICAgICBzd2FwKG8pOwogICAgIHJldHVybiAqdGhpczsKICB9CiAgdmlydHVhbCB+QSgpIHt9CiAgdm9pZCBzd2FwKEEmIG8pCiAgewogICAgIHMuc3dhcChvLnMpOwogIH0KICBmcmllbmQgc3RkOjpvc3RyZWFtJiBvcGVyYXRvciA8PCAoc3RkOjpvc3RyZWFtJiBvcywgY29uc3QgQSYgYSkgeyByZXR1cm4gb3MgPDwgYS5zOyB9Cgpwcml2YXRlOgogIFMgczsKfTsKCnRlbXBsYXRlIDxpbnQgTj4KY2xhc3MgQiA6IHB1YmxpYyB2aXJ0dWFsIEEgewpwdWJsaWM6CiAgQihjb25zdCBjaGFyKiBzQSwgY29uc3QgY2hhciogcykgOiBBKHNBKSwgcyhzKSB7fQogIEIoY29uc3QgQiYgbykgOiBBKG8pLCBzKG8ucykge30KICBCJiBvcGVyYXRvciA9IChCIG8pCiAgewogICAgIHN3YXAobyk7CiAgICAgcmV0dXJuICp0aGlzOwogIH0KICB2aXJ0dWFsIH5CKCkge30KICB2b2lkIHN3YXAoQiYgbykKICB7CiAgICAgQTo6c3dhcChvKTsKICAgICBzLnN3YXAoby5zKTsKICB9CiAgZnJpZW5kIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3IgPDwgKHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IEImIGIpIAogIHsgcmV0dXJuIG9zIDw8IChjb25zdCBBJiliIDw8ICcsJyA8PCBiLnM7IH0KCnByaXZhdGU6CiAgUyBzOwp9OwoKY2xhc3MgRCA6IHB1YmxpYyBCPDE+LCBwdWJsaWMgQjwyPiB7CnB1YmxpYzoKICBEKGNvbnN0IGNoYXIqIHNBLCBjb25zdCBjaGFyKiBzQjEsIGNvbnN0IGNoYXIqIHNCMiwgY29uc3QgY2hhciogcykgCiAgIDogQShzQSksIEI8MT4oc0EsIHNCMSksIEI8Mj4oc0EsIHNCMiksIHMocykgCiAge30KICBEKGNvbnN0IEQmIG8pIDogQShvKSwgQjwxPihvKSwgQjwyPihvKSwgcyhvLnMpIHt9CiAgRCYgb3BlcmF0b3IgPSAoRCBvKQogIHsKICAgICBzd2FwKG8pOwogICAgIHJldHVybiAqdGhpczsKICB9CiAgdmlydHVhbCB+RCgpIHt9CiAgdm9pZCBzd2FwKEQmIG8pCiAgewogICAgIEI8MT46OnN3YXAobyk7IC8vIGNhbGxzIEE6OnN3YXAobyk7IEE6OnMgY2hhbmdlZCB0byBvLnMKICAgICBCPDI+Ojpzd2FwKG8pOyAvLyBjYWxscyBBOjpzd2FwKG8pOyBBOjpzIHJldHVybmVkIHRvIG9yaWdpbmFsIHZhbHVlLi4uCiAgICAgcy5zd2FwKG8ucyk7CiAgfQogIGZyaWVuZCBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yIDw8IChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBEJiBkKSAKICB7IAogICAgIC8vIHByaW50cyBBOjpzIHR3aWNlLi4uCiAgICAgcmV0dXJuIG9zIAoJPDwgKGNvbnN0IEI8MT4mKWQgPDwgJywnIAoJPDwgKGNvbnN0IEI8Mj4mKWQgPDwgJywnIAogICAgICAgIDw8IGQuczsKICB9CnByaXZhdGU6CiAgUyBzOwp9OwoKaW50IG1haW4oKSB7CiAgIEQgeCgiYXgiLCAiYjF4IiwgImIyeCIsICJ4Iik7CiAgIEQgeSgiYXkiLCAiYjF5IiwgImIyeSIsICJ5Iik7CiAgIHN0ZDo6Y291dCA8PCB4IDw8ICJcbiIgPDwgeSA8PCAiXG4iOwogICB4ID0geTsKICAgc3RkOjpjb3V0IDw8IHggPDwgIlxuIiA8PCB5IDw8ICJcbiI7Cn0KCg==