#include <vector>
#include <iostream>
#include <utility>
/**-------------------------------------------------------------*
   niepotrzebne kopiowanie                               *
 *--------------------------------------------------------------*/

// A = std::move(B);
// Now A contains the elements that were previously held by B, and B is now empty. This avoids copying: the internal representation is simply moved from B to A, so this is an O(1) solution.

using namespace std;

class Point3D {
    vector<double> v_;
    static const int X = 0;
    static const int Y = 1;
    static const int Z = 2;
public:
    Point3D(double x = 0.0, double y = 0.0, double z = 0.0) {
        cout << "c-tor" << endl;
        v_.push_back(x);
        v_.push_back(y);
        v_.push_back(z);
    }
    Point3D(const Point3D& p) : v_(p.v_) { cout << "copy c-tor" << endl; }
    Point3D(Point3D&& p) { v_ = std::move(p.v_); cout << "move c-tor" << endl; }
    ~Point3D() {}
    friend bool operator==(const Point3D& a, const Point3D& b);

    //przesuwa w kierunku wskazanego punktu
    Point3D& moveToCenter(const Point3D& p) {
        v_[X] += p.v_[X];
        v_[X] /= 2.0;
        v_[Y] += p.v_[Y];
        v_[Y] /= 2.0;
        v_[Z] += p.v_[Z];
        v_[Z] /= 2.0;
        return *this;
    }

    //zwraca punkt centralny
    Point3D center(const Point3D& p) const {
        Point3D out(*this);
        out.moveToCenter(p);
        return out;
    }

    Point3D center(Point3D&& p) const {
        p.moveToCenter(*this);
        return std::move(p);
    }
};

bool operator==(const Point3D& a, const Point3D& b) {
    return a.v_[0] == b.v_[0] && a.v_[1] == b.v_[1] && a.v_[2] == b.v_[2];
}

int main() {
    const Point3D p1(1.0, 1.0, 1.0);
    Point3D p2 = p1.center(p1.center(Point3D(2.0,2.0,2.0)));
    //tutaj uzywamy p2
     cout << (p2 == p1) << endl;
    return 0;
}
