|
//COPY ELISION
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
//#define MOVE_FUNCTIONALITY
int count_copies = 0;
int count_allocations = 0;
int elem_access = 0;
class Array
{
int m_size;
double *m_array;
public:
Array():m_size(0),m_array(nullptr) {}
Array(int n):m_size(n),m_array(new double[n])
{
std::cout << ">>>allocate:" << n << std::endl;
count_allocations += n;
}
Array(const Array& x):m_size(x.m_size),m_array(new double[m_size])
{
std::cout << ">>>(const Array& x) copy:" << m_size << std::endl;
count_allocations += m_size;
count_copies += m_size;
std::copy(x.m_array, x.m_array+x.m_size, m_array);
}
#ifdef MOVE_FUNCTIONALITY
Array(Array&& x):m_size(x.m_size),m_array(x.m_array)
{
std::cout << ">>>(Array&&) move" << std::endl;
x.m_size = 0; // clearing the contents of x
x.m_array = nullptr;
}
#endif
virtual ~Array()
{
std::cout << ">>>delete: " << m_size << std::endl;
delete [] m_array;
}
auto Swap(Array& y) -> void
{
std::cout << ">>>swap" << std::endl;
int n = m_size;
double* v = m_array;
m_size = y.m_size;
m_array = y.m_array;
y.m_size = n;
y.m_array = v;
}
#ifdef MOVE_FUNCTIONALITY
auto operator=(Array&& x) -> Array&
{
Swap(x);
return *this;
}
#endif
auto operator=(const Array& x) -> Array&
{
if (x.m_size == m_size)
{
std::cout << ">>>copy assignment:" << m_size << std::endl;
count_copies += m_size;
std::copy(x.m_array, x.m_array+x.m_size, m_array);
}
else
{
Array y(x);
Swap(y);
}
return *this;
}
auto operator[](int i) -> double&
{
elem_access++;
return m_array[i];
}
auto operator[](int i) const -> double
{
elem_access++;
return m_array[i];
}
auto size() const ->int { return m_size;}
#ifdef MOVE_FUNCTIONALITY
template<class T>
friend auto operator+(T&& x, const Array& y) -> Array
{
int n = x.m_size;
Array z(std::forward<T>(x));
for (int i = 0; i < n; ++i)
{
elem_access+=2;
z.m_array[i] += y.m_array[i];
}
return z;
}
template<class T>
friend auto operator+(T&& x, Array&& y) -> Array
{
return std::move(y)+x;
}
#else
friend auto operator+(const Array& x, const Array& y) -> Array
{
int n = x.m_size;
Array z(n);
for (int i = 0; i < n; ++i)
{
elem_access += 3;
z.m_array[i] = x.m_array[i] + y.m_array[i];
}
return z;
}
#endif
void print(const std::string& title) const
{
std::cout << title;
for (int i = 0; i < m_size; ++i)
{
elem_access++;
std::cout << " " << m_array[i];
};
std::cout << std::endl;
}
};
const Array f()
{
Array z(2);
z[0] = 2.1;
z[1] = 33.2;
return z;
}
Array f1()
{
Array z(2);
z[0] = 2.1;
z[1] = 33.2;
return z;
}
void g(Array&& a)
{
a.print("g(Array&&)");
}
void g(const Array& a)
{
a.print("g(const Array&)");
}
void pf(Array a)
{
a.print("pf(Array)");
}
int main()
{
{
Array p(f());
p.print("p");
g(f());
g(f1());
pf(f());
}
std::cout << "total allocations (elements):" << count_allocations << std::endl;
int total_elem_access = count_copies*2 + elem_access;
std::cout << "total elem access (elements):" << total_elem_access << std::endl;
return 0;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.