#include <iostream>
struct X
{
X() : id(instances++)
{
std::cout << "X" << id << ": construct\n";
}
X(X const& rhs) : id(instances++)
{
std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n";
++copies;
}
X(X&& rhs) : id(instances++)
{
std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **move**\n";
++moves;
}
// This particular test doesn't exercise assignment, but for
// completeness:
X& operator=(X const& rhs)
{
std::cout << "X" << id << ": <- " << "X" << rhs.id << ": copy-assign\n";
}
X& operator=(X&& rhs)
{
std::cout << "X" << id << ": <- " << "X" << rhs.id << ": move-assign\n";
}
~X() { std::cout << "X" << id << ": destroy\n"; }
X& operator+=( const X& rhs ) {
std::cout << "X" << id << ": += " << "X" << rhs.id << ": add-assign\n";
return *this;
}
unsigned id;
static unsigned copies;
static unsigned moves;
static unsigned instances;
};
X operator+( X lhs, const X& rhs ) {
std::cout << "X" << lhs.id << ": + " << "X" << rhs.id << ": add\n";
lhs += rhs;
return lhs;
}
unsigned X::copies = 0;
unsigned X::moves = 0;
unsigned X::instances = 0;
#define CHECK_COPIES( stmt, min, max_copies, max_moves, comment ) \
{ \
unsigned const old_copies = X::copies; \
unsigned const old_moves = X::moves; \
\
std::cout << "\n" comment "\n" #stmt "\n===========\n"; \
{ \
stmt; \
} \
unsigned const n = X::copies - old_copies; \
unsigned const m = X::moves - old_moves; \
unsigned const t = n+m; \
if (t < min) \
std::cout << "*** min is too high or compiler is buggy ***\n"; \
if (n > max_copies) \
std::cout << "*** max_copies is too low or compiler is buggy ***\n";\
if (m > max_moves) \
std::cout << "*** max_moves is too low or compiler is buggy ***\n"; \
\
\
std::cout << "-----------\n" \
<< n << "/" << max_copies \
<< " possible copies made\n" \
<< m << "/" << max_moves \
<< " possible moves made\n" \
<< max_copies - t << "/" << max_copies - min \
<< " possible elisions performed\n\n"; \
\
if (t > min) \
std::cout << "*** " << t - min \
<< " possible elisions missed! ***\n"; \
}
X lvalue_;
X& lvalue()
{
return lvalue_;
}
typedef X rvalue;
int main()
{
CHECK_COPIES( lvalue() + lvalue(), 1, 2, 1, "lvalue + lvalue" );
CHECK_COPIES( rvalue() + lvalue(), 0, 2, 2, "rvalue + lvalue" );
CHECK_COPIES( lvalue() + rvalue(), 1, 2, 1, "lvalue + rvalue" );
}