I am doing my CG homework using Rust. When it comes to overloading operators, it seems I have to write really verbose code to get it usable.

Say, I have a `pub struct Vec3`

, and I want an element-wise addition and a broadcast addition. I have to write the below, so that `+`

can work with references.

```
#[derive(Debug, Copy, Clone)]
pub struct Vec3
{
data: [f32; 3]
}
impl Vec3
{
pub fn new(x: f32, y: f32, z: f32) -> Self
{
Vec3 {
data: [x, y, z]
}
}
}
// impl ops::Add for Vec3
// {
// type Output = Vec3;
//
// fn add(self, rhs: Self) -> Self::Output {
// let data = [self.data[0] + rhs.data[0], self.data[1] + rhs.data[1], self.data[2] + rhs.data[2]];
// Vec3 {
// data
// }
// }
// }
// impl ops::Add<Vec3> for &Vec3
// {
// type Output = Vec3;
//
// fn add(self, rhs: Vec3) -> Self::Output {
// let data = [self.data[0] + rhs.data[0], self.data[1] + rhs.data[1], self.data[2] + rhs.data[2]];
// Vec3 {
// data
// }
// }
// }
impl ops::Add for &Vec3
{
type Output = Vec3;
fn add(self, rhs: Self) -> Self::Output {
let data = [self.data[0] + rhs.data[0], self.data[1] + rhs.data[1], self.data[2] + rhs.data[2]];
Vec3 {
data
}
}
}
impl ops::Add<&Self> for Vec3
{
type Output = Vec3;
fn add(self, rhs: &Self) -> Self::Output {
let data = [self.data[0] + rhs.data[0], self.data[1] + rhs.data[1], self.data[2] + rhs.data[2]];
Vec3 {
data
}
}
}
// broadcasting
impl ops::Add<f32> for Vec3
{
type Output = Vec3;
fn add(self, rhs: f32) -> Self::Output {
let data = [self.data[0] + rhs, self.data[1] + rhs, self.data[2] + rhs];
Vec3 {
data
}
}
}
impl ops::Add<f32> for &Vec3
{
type Output = Vec3;
fn add(self, rhs: f32) -> Self::Output {
let data = [self.data[0] + rhs, self.data[1] + rhs, self.data[2] + rhs];
Vec3 {
data
}
}
}
```

I understand that the ownership matters, so I commented codes in the middle to avoid taking the ownership, but I think the rest is basically the same (conceptually). Is there any macros or ways to overload operators regardless whether **the left hand side** is a reference or a value?

Since the below lines should be equivalent, it makes sense to ignore whether the left hand side is a reference.

```
let val = Vec3::new(1.0,1.0,1.0);
let reference = &val;
let result1 = val + 1.0;
let result2 = val.add(1.0);
let result3 = reference.add(1.0);
// so why not like below?
let result4 = reference + 1.0; // my code compiles, but I have to explicitly `impl ops::Add<f32> for &Vec3`
```

I tried the below code using blanket implementation, but it cannot compile due to the orphan rule.

```
impl<T: Add<f32>> Add<f32> for &T
{
type Output = T::Output;
fn add(self, rhs: f32) -> Self::Output {
self.add(rhs)
}
}
```