Is there a good way of testing to make sure that an object was not copied?
You may try following check:
live demo
#include <boost/container/vector.hpp>
#include <iostream>
#include <ostream>
#include <vector>
#include <string>
using namespace boost;
using namespace std;
struct Test
{
bool copied;
Test()
: copied(false)
{
}
Test(const Test&)
: copied(true)
{
}
};
template<typename Container>
void check_move_constructor()
{
Container from(1);
Container to(boost::move(from));
cout << "\tmove constructor is" << (to[0].copied ? " not" : "") << " working" << endl;
}
template<typename Container>
void check_move_assignment()
{
Container from(1);
Container to;
to=boost::move(from);
cout << "\tmove assignment is" << (to[0].copied ? " not" : "") << " working" << endl;
}
template<typename Container>
void check_move(const string &name)
{
cout << name << " :" << endl;
check_move_constructor< Container >();
check_move_assignment< Container >();
cout << string(16,'_') << endl;
}
int main()
{
cout << boolalpha;
check_move< container::vector<Test> >("boost::container::vector");
check_move< vector<Test> >("std::vector");
return 0;
}
MSVC2008 outputs:
boost::container::vector :
move constructor is working
move assignment is working
________________
std::vector :
move constructor is not working
move assignment is not working
________________
Note, that in this code I used explicit move from lvalues, so Copy-elision can't work here.
P.S. another way to do this is to check generated assembler code. For instance /FA compiler option on MSVC or -S on GCC.
You can mark place of interest with special function call:
__declspec(noinline) void asm_marker(int line) { volatile int i=line; };
#define ASM_MARKER asm_marker(__LINE__)
And place that marker in code:
ASM_MARKER;
func_of_interest();
ASM_MARKER;
Asm code may look like:
mov ecx, 235 ; 000000ebH
call ?asm_marker@@YAXH@Z ; asm_marker
mov edi, r12d
lea rcx, QWORD PTR [rdi+rdi*4]
mov rax, QWORD PTR vec$[rsp]
lea r9, QWORD PTR [rax+rcx*8]
mov rbx, QWORD PTR vec$[rsp+32]
mov ecx, 237 ; 000000edH
call ?asm_marker@@YAXH@Z ; asm_marker