#include <iostream>
class Vec3
{
public:
explicit Vec3(double x = 0, double y = 0, double z = 0) : x_(x), y_(y), z_(z) {}
double x() const { return x_; }
double y() const { return y_; }
double z() const { return z_; }
Vec3& operator += (const Vec3& vec3) { x_ += vec3.x_; y_ += vec3.y_; z_ += vec3.z_; return *this; }
Vec3& operator -= (const Vec3& vec3) { x_ -= vec3.x_; y_ -= vec3.y_; z_ -= vec3.z_; return *this; }
Vec3& operator *= (double s) { x_ *= s; y_ *= s; z_ *= s; return *this; }
Vec3& operator /= (double s) { x_ /= s; y_ /= s; z_ /= s; return *this; }
double dot(const Vec3& vec3) const { return (x_ * vec3.x_) + (y_ * vec3.y_) + (z_ * vec3.z_); }
Vec3 cross(const Vec3& vec3) const { return Vec3((y_ * vec3.z_) - (z_ * vec3.y_), (z_ * vec3.x_) - (x_ * vec3.z_), (x_ * vec3.y_) - (y_ * vec3.x_)); }
private:
double x_;
double y_;
double z_;
};
Vec3 operator + (Vec3 lhs, const Vec3& rhs) { return (lhs += rhs); }
Vec3 operator - (Vec3 lhs, const Vec3& rhs) { return (lhs -= rhs); }
Vec3 operator * (Vec3 lhs, double rhs) { return (lhs *= rhs); }
Vec3 operator / (Vec3 lhs, double rhs) { return (lhs /= rhs); }
std::ostream& operator << (std::ostream& out, const Vec3& vec3)
{
return out << "(" << vec3.x() << ", " << vec3.y() << ", " << vec3.z() << ")";
}
template<typename T>
struct Operator
{
explicit Operator(const Vec3& vec3) : vec3(vec3) {}
const Vec3& vec3;
};
template<typename T>
inline Operator<T> operator % (const Vec3& vec3, T)
{
return Operator<T>(vec3);
}
enum DOT { dot };
enum CROSS { cross };
inline double operator % (const Operator<DOT>& op, const Vec3& vec3)
{
return op.vec3.dot(vec3);
}
inline Vec3 operator % (const Operator<CROSS>& op, const Vec3& vec3)
{
return op.vec3.cross(vec3);
}
int main(int, char* [])
{
Vec3 v1(1, 2, 3);
Vec3 v2(4, 5, 6);
std::cout << "v1 = " << v1 << "\n";
std::cout << "v2 = " << v2 << "\n";
std::cout << "v1 + v2 = " << (v1 + v2) << "\n";
std::cout << "v1 - v2 = " << (v1 - v2) << "\n";
std::cout << "v1 * 2 = " << (v1 * 2) << "\n";
std::cout << "v2 / 2 = " << (v2 / 2) << "\n";
std::cout << "v1 dot v2 = " << (v1 %dot% v2) << "\n";
std::cout << "v1 cross v2 = " << (v1 %cross% v2) << "\n";
return 0;
}