#include <cstring>
#include <iostream>
using namespace std;
// Test for copy-ellision
// A is old school class with pass-by-const-ref operator=
class A
{
public:
static int n,d,c;
A() : ptr(0),size(0) {}
A(size_t sz) : size(sz)
{
n++;
ptr = new float[sz];
}
A(A const& src)
{
size = src.size;
n++;
ptr = new float[size];
c++;
memcpy(ptr,src.ptr,sizeof(float)*size);
}
A& operator=(A const& src)
{
if(this != &src)
{
size = src.size;
d++;
if(ptr) delete[] ptr;
n++;
ptr = new float[size];
c++;
memcpy(ptr,src.ptr,sizeof(float)*size);
}
return *this;
}
void operator()() { cout << "non-const call" << endl; }
~A()
{
d++;
if(ptr) delete[] ptr;
ptr = 0;
}
private:
float* ptr;
int size;
};
int A::n = 0;
int A::d = 0;
int A::c = 0;
// B is new school class with pass-by-value operator=
class B
{
public:
static int n,d,c;
B() : ptr(0),size(0) {}
B(size_t sz) : size(sz)
{
n++;
ptr = new float[sz];
}
B(B const& src)
{
size = src.size;
n++;
ptr = new float[size];
c++;
memcpy(ptr,src.ptr,sizeof(float)*size);
}
B& operator=(B src)
{
swap(src);
return *this;
}
void swap(B& src)
{
std::swap(size,src.size);
std::swap(ptr,src.ptr);
}
void operator()() { cout << "non-const call" << endl; }
~B()
{
d++;
if(ptr) delete[] ptr;
ptr = 0;
}
private:
float* ptr;
int size;
};
int B::n = 0;
int B::d = 0;
int B::c = 0;
A sort( A const& names)
{
A ret = names;
ret();
return ret;
}
B sort( B names)
{
names();
return names;
}
int main()
{
cout << "gcc " << __GNUC__ << "." << __GNUC_MINOR__<< endl;
{
A a;
a = A(5);
A c;
c = sort(A(7));
}
cout << "A new : " << A::n << endl;
cout << "A delete : " << A::d << endl;
cout << "A copy : " << A::c << endl;
cout << endl;
{
B a;
a = B(8);
B c;
c = sort(B(9));
}
cout << "B new : " << B::n << endl;
cout << "B delete : " << B::d << endl;
cout << "B copy : " << B::c << endl;
cout << endl;
}
I2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBUZXN0IGZvciBjb3B5LWVsbGlzaW9uCgovLyBBIGlzIG9sZCBzY2hvb2wgY2xhc3Mgd2l0aCBwYXNzLWJ5LWNvbnN0LXJlZiBvcGVyYXRvcj0KY2xhc3MgQQp7CiAgcHVibGljOgoKICBzdGF0aWMgaW50IG4sZCxjOwoKICBBKCkgOiBwdHIoMCksc2l6ZSgwKSB7fQogIEEoc2l6ZV90IHN6KSA6IHNpemUoc3opCiAgewogICAgbisrOwogICAgcHRyID0gbmV3IGZsb2F0W3N6XTsKICB9CgogIEEoQSBjb25zdCYgc3JjKQogIHsKICAgIHNpemUgPSBzcmMuc2l6ZTsKICAgIG4rKzsKICAgIHB0ciA9IG5ldyBmbG9hdFtzaXplXTsKICAgIGMrKzsKICAgIG1lbWNweShwdHIsc3JjLnB0cixzaXplb2YoZmxvYXQpKnNpemUpOwogIH0KCiAgQSYgb3BlcmF0b3I9KEEgY29uc3QmIHNyYykKICB7CiAgICBpZih0aGlzICE9ICZzcmMpCiAgICB7CiAgICAgIHNpemUgPSBzcmMuc2l6ZTsKICAgICAgZCsrOwogICAgICBpZihwdHIpIGRlbGV0ZVtdIHB0cjsKICAgICAgbisrOwogICAgICBwdHIgPSBuZXcgZmxvYXRbc2l6ZV07CiAgICAgIGMrKzsKICAgICAgbWVtY3B5KHB0cixzcmMucHRyLHNpemVvZihmbG9hdCkqc2l6ZSk7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwogIH0KCiAgdm9pZCBvcGVyYXRvcigpKCkgeyBjb3V0IDw8ICJub24tY29uc3QgY2FsbCIgPDwgZW5kbDsgfQoKICB+QSgpCiAgewogICAgZCsrOwogICAgaWYocHRyKSBkZWxldGVbXSBwdHI7CiAgICBwdHIgPSAwOwogIH0KCiAgcHJpdmF0ZToKICBmbG9hdCogIHB0cjsKICBpbnQgICAgIHNpemU7Cn07CgppbnQgQTo6biA9IDA7CmludCBBOjpkID0gMDsKaW50IEE6OmMgPSAwOwoKLy8gQiBpcyBuZXcgc2Nob29sIGNsYXNzIHdpdGggcGFzcy1ieS12YWx1ZSBvcGVyYXRvcj0KY2xhc3MgQgp7CiAgcHVibGljOgoKICBzdGF0aWMgaW50IG4sZCxjOwoKICBCKCkgOiBwdHIoMCksc2l6ZSgwKSB7fQogIEIoc2l6ZV90IHN6KSA6IHNpemUoc3opCiAgewogICAgbisrOwogICAgcHRyID0gbmV3IGZsb2F0W3N6XTsKICB9CgogIEIoQiBjb25zdCYgc3JjKQogIHsKICAgIHNpemUgPSBzcmMuc2l6ZTsKICAgIG4rKzsKICAgIHB0ciA9IG5ldyBmbG9hdFtzaXplXTsKICAgIGMrKzsKICAgIG1lbWNweShwdHIsc3JjLnB0cixzaXplb2YoZmxvYXQpKnNpemUpOwogIH0KCiAgQiYgb3BlcmF0b3I9KEIgc3JjKQogIHsKICAgIHN3YXAoc3JjKTsKICAgIHJldHVybiAqdGhpczsKICB9CgogIHZvaWQgc3dhcChCJiBzcmMpCiAgewogICAgc3RkOjpzd2FwKHNpemUsc3JjLnNpemUpOwogICAgc3RkOjpzd2FwKHB0cixzcmMucHRyKTsKICB9CgogIHZvaWQgb3BlcmF0b3IoKSgpIHsgY291dCA8PCAibm9uLWNvbnN0IGNhbGwiIDw8IGVuZGw7IH0KCiAgfkIoKQogIHsKICAgIGQrKzsKICAgIGlmKHB0cikgZGVsZXRlW10gcHRyOwogICAgcHRyID0gMDsKICB9CgogIHByaXZhdGU6CiAgZmxvYXQqICBwdHI7CiAgaW50ICAgICBzaXplOwp9OwoKaW50IEI6Om4gPSAwOwppbnQgQjo6ZCA9IDA7CmludCBCOjpjID0gMDsKCkEgc29ydCggQSBjb25zdCYgbmFtZXMpCnsKICBBIHJldCA9IG5hbWVzOwogIHJldCgpOwogIHJldHVybiByZXQ7Cn0KCkIgc29ydCggQiBuYW1lcykKewogIG5hbWVzKCk7CiAgcmV0dXJuIG5hbWVzOwp9CgppbnQgbWFpbigpCnsKICBjb3V0IDw8ICJnY2MgIiA8PCBfX0dOVUNfXyAgPDwgICIuIiA8PCAgICAgIF9fR05VQ19NSU5PUl9fPDwgZW5kbDsKICB7CiAgICBBIGE7CiAKICAgIGEgPSBBKDUpOwoKICAgIEEgYzsKICAgIGMgPSBzb3J0KEEoNykpOwogIH0KCiAgY291dCA8PCAiQSBuZXcgOiAiIDw8IEE6Om4gPDwgZW5kbDsKICBjb3V0IDw8ICJBIGRlbGV0ZSA6ICIgPDwgQTo6ZCA8PCBlbmRsOwogIGNvdXQgPDwgIkEgY29weSA6ICIgPDwgQTo6YyA8PCBlbmRsOwogIGNvdXQgPDwgZW5kbDsKCiAgewogICAgQiBhOwogICAgCiAgICBhID0gQig4KTsKCiAgICBCIGM7CiAgICBjID0gc29ydChCKDkpKTsKICB9CgogIGNvdXQgPDwgIkIgbmV3IDogIiA8PCBCOjpuIDw8IGVuZGw7CiAgY291dCA8PCAiQiBkZWxldGUgOiAiIDw8IEI6OmQgPDwgZW5kbDsKICBjb3V0IDw8ICJCIGNvcHkgOiAiIDw8IEI6OmMgPDwgZW5kbDsKICBjb3V0IDw8IGVuZGw7Cgp9Cg==