use crate::numeric::{Numeric, NumericRef, ZeroOne, FromUsize};
use crate::numeric::extra::{Real, RealRef, Sin, Cos, Exp, Pow, Ln, Sqrt, Pi};
use crate::differentiation::{Primitive, Record, WengertList};
use std::ops::{Add, Sub, Mul, Neg, Div};
use std::cmp::Ordering;
use std::iter::Sum;
impl <'a, T: std::fmt::Display + Primitive> std::fmt::Display for Record<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.number)
}
}
impl <'a, T: Numeric + Primitive> ZeroOne for Record<'a, T> {
#[inline]
fn zero() -> Record<'a, T> {
Record::constant(T::zero())
}
#[inline]
fn one() -> Record<'a, T> {
Record::constant(T::one())
}
}
impl <'a, T: Numeric + Primitive> FromUsize for Record<'a, T> {
#[inline]
fn from_usize(n: usize) -> Option<Record<'a, T>> {
Some(Record::constant(T::from_usize(n)?))
}
}
impl <'a, T: Clone + Primitive> Clone for Record<'a, T> {
fn clone(&self) -> Self {
Record {
number: self.number.clone(),
history: self.history,
index: self.index,
}
}
}
impl <'a, T: Copy + Primitive> Copy for Record<'a, T> { }
pub(crate) fn same_list<'a, 'b, T: Primitive>(a: &Record<'a, T>, b: &Record<'b, T>) -> bool {
match (a.history, b.history) {
(None, None) => true,
(Some(_), None) => true,
(None, Some(_)) => true,
(Some(list_a), Some(list_b)) => (
list_a as *const WengertList<T> == list_b as *const WengertList<T>
),
}
}
impl <'a, 'l, 'r, T: Numeric + Primitive> Add<&'r Record<'a, T>> for &'l Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn add(self, rhs: &Record<'a, T>) -> Self::Output {
assert!(same_list(self, rhs), "Records must be using the same WengertList");
match (self.history, rhs.history) {
(None, None) => Record {
number: self.number.clone() + rhs.number.clone(),
history: None,
index: 0,
},
(Some(_), None) => self + &rhs.number,
(None, Some(_)) => rhs + &self.number,
(Some(history), Some(_)) => Record {
number: self.number.clone() + rhs.number.clone(),
history: Some(history),
index: history.append_binary(
self.index,
T::one(),
rhs.index,
T::one()
),
},
}
}
}
impl <'a, T: Numeric + Primitive> Add<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn add(self, rhs: &T) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone() + rhs.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone() + rhs.clone(),
history: Some(history),
index: history.append_unary(
self.index,
T::one()
),
}
}
}
}
}
macro_rules! record_operator_impl_value_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
(&self).$method(&rhs)
}
}
}
}
macro_rules! record_operator_impl_value_reference {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op<&Record<'a, T>> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: &Record<'a, T>) -> Self::Output {
(&self).$method(rhs)
}
}
}
}
macro_rules! record_operator_impl_reference_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op<Record<'a, T>> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
self.$method(&rhs)
}
}
}
}
record_operator_impl_value_value!(impl Add for Record { fn add });
record_operator_impl_reference_value!(impl Add for Record { fn add });
record_operator_impl_value_reference!(impl Add for Record { fn add });
macro_rules! record_number_operator_impl_value_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op<T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: T) -> Self::Output {
(&self).$method(&rhs)
}
}
}
}
macro_rules! record_number_operator_impl_value_reference {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op<&T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: &T) -> Self::Output {
(&self).$method(rhs)
}
}
}
}
macro_rules! record_number_operator_impl_reference_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Primitive> $op<T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: T) -> Self::Output {
self.$method(&rhs)
}
}
}
}
record_number_operator_impl_value_value!(impl Add for Record { fn add });
record_number_operator_impl_reference_value!(impl Add for Record { fn add });
record_number_operator_impl_value_reference!(impl Add for Record { fn add });
impl <'a, 'l, 'r, T: Numeric + Primitive> Mul<&'r Record<'a, T>> for &'l Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn mul(self, rhs: &Record<'a, T>) -> Self::Output {
assert!(same_list(self, rhs), "Records must be using the same WengertList");
match (self.history, rhs.history) {
(None, None) => Record {
number: self.number.clone() * rhs.number.clone(),
history: None,
index: 0,
},
(Some(_), None) => self * &rhs.number,
(None, Some(_)) => rhs * &self.number,
(Some(history), Some(_)) => Record {
number: self.number.clone() * rhs.number.clone(),
history: Some(history),
index: history.append_binary(
self.index,
rhs.number.clone(),
rhs.index,
self.number.clone()
),
},
}
}
}
record_operator_impl_value_value!(impl Mul for Record { fn mul });
record_operator_impl_reference_value!(impl Mul for Record { fn mul });
record_operator_impl_value_reference!(impl Mul for Record { fn mul });
impl <'a, T: Numeric + Primitive> Mul<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn mul(self, rhs: &T) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone() * rhs.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone() * rhs.clone(),
history: Some(history),
index: history.append_unary(
self.index,
rhs.clone()
),
}
}
}
}
}
record_number_operator_impl_value_value!(impl Mul for Record { fn mul });
record_number_operator_impl_reference_value!(impl Mul for Record { fn mul });
record_number_operator_impl_value_reference!(impl Mul for Record { fn mul });
impl <'a, 'l, 'r, T: Numeric + Primitive> Sub<&'r Record<'a, T>> for &'l Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub(self, rhs: &Record<'a, T>) -> Self::Output {
assert!(same_list(self, rhs), "Records must be using the same WengertList");
match (self.history, rhs.history) {
(None, None) => Record {
number: self.number.clone() - rhs.number.clone(),
history: None,
index: 0,
},
(Some(_), None) => self - &rhs.number,
(None, Some(_)) => rhs.sub_swapped(self.number.clone()),
(Some(history), Some(_)) => Record {
number: self.number.clone() - rhs.number.clone(),
history: Some(history),
index: history.append_binary(
self.index,
T::one(),
rhs.index,
-T::one()
),
},
}
}
}
record_operator_impl_value_value!(impl Sub for Record { fn sub });
record_operator_impl_reference_value!(impl Sub for Record { fn sub });
record_operator_impl_value_reference!(impl Sub for Record { fn sub });
impl <'a, T: Numeric + Primitive> Sub<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub(self, rhs: &T) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone() - rhs.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone() - rhs.clone(),
history: Some(history),
index: history.append_unary(
self.index,
T::one()
),
}
}
}
}
}
record_number_operator_impl_value_value!(impl Sub for Record { fn sub });
record_number_operator_impl_reference_value!(impl Sub for Record { fn sub });
record_number_operator_impl_value_reference!(impl Sub for Record { fn sub });
pub trait SwappedOperations<Lhs = Self> {
type Output;
fn sub_swapped(self, lhs: Lhs) -> Self::Output;
fn div_swapped(self, lhs: Lhs) -> Self::Output;
}
impl <'a, T: Numeric + Primitive> SwappedOperations<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub_swapped(self, lhs: &T) -> Self::Output {
match self.history {
None => Record {
number: lhs.clone() - self.number.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: lhs.clone() - self.number.clone(),
history: Some(history),
index: history.append_unary(
self.index,
-T::one()
),
}
}
}
}
#[inline]
fn div_swapped(self, lhs: &T) -> Self::Output {
match self.history {
None => Record {
number: lhs.clone() / self.number.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: lhs.clone() / self.number.clone(),
history: Some(history),
index: history.append_unary(
self.index,
-&lhs.clone() / (self.number.clone() * self.number.clone())
),
}
}
}
}
}
impl <'a, T: Numeric + Primitive> SwappedOperations<T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub_swapped(self, lhs: T) -> Self::Output {
self.sub_swapped(&lhs)
}
#[inline]
fn div_swapped(self, lhs: T) -> Self::Output {
self.div_swapped(&lhs)
}
}
impl <'a, T: Numeric + Primitive> SwappedOperations<T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub_swapped(self, lhs: T) -> Self::Output {
(&self).sub_swapped(&lhs)
}
#[inline]
fn div_swapped(self, lhs: T) -> Self::Output {
(&self).div_swapped(&lhs)
}
}
impl <'a, T: Numeric + Primitive> SwappedOperations<&T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sub_swapped(self, lhs: &T) -> Self::Output {
(&self).sub_swapped(lhs)
}
#[inline]
fn div_swapped(self, lhs: &T) -> Self::Output {
(&self).div_swapped(lhs)
}
}
impl <'a, 'l, 'r, T: Numeric + Primitive> Div<&'r Record<'a, T>> for &'l Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn div(self, rhs: &Record<'a, T>) -> Self::Output {
assert!(same_list(self, rhs), "Records must be using the same WengertList");
match (self.history, rhs.history) {
(None, None) => Record {
number: self.number.clone() / rhs.number.clone(),
history: None,
index: 0,
},
(Some(_), None) => self / &rhs.number,
(None, Some(_)) => rhs.div_swapped(self.number.clone()),
(Some(history), Some(_)) => Record {
number: self.number.clone() / rhs.number.clone(),
history: Some(history),
index: history.append_binary(
self.index,
T::one() / rhs.number.clone(),
rhs.index,
-&self.number / (rhs.number.clone() * rhs.number.clone())
),
},
}
}
}
record_operator_impl_value_value!(impl Div for Record { fn div });
record_operator_impl_reference_value!(impl Div for Record { fn div });
record_operator_impl_value_reference!(impl Div for Record { fn div });
impl <'a, T: Numeric + Primitive> Div<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn div(self, rhs: &T) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone() / rhs.clone(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone() / rhs.clone(),
history: Some(history),
index: history.append_unary(
self.index,
T::one() / rhs.clone()
),
}
}
}
}
}
record_number_operator_impl_value_value!(impl Div for Record { fn div });
record_number_operator_impl_reference_value!(impl Div for Record { fn div });
record_number_operator_impl_value_reference!(impl Div for Record { fn div });
impl <'a, T: Numeric + Primitive> Neg for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn neg(self) -> Self::Output {
match self.history {
None => Record {
number: -self.number.clone(),
history: None,
index: 0,
},
Some(_) => {
Record::constant(T::zero()) - self
}
}
}
}
impl <'a, T: Numeric + Primitive> Neg for Record<'a, T>
where for<'t> &'t T: NumericRef<T> {
type Output = Record<'a, T>;
#[inline]
fn neg(self) -> Self::Output {
match self.history {
None => Record {
number: -self.number,
history: None,
index: 0,
},
Some(_) => {
Record::constant(T::zero()) - self
}
}
}
}
impl <'a, T: PartialEq + Primitive> PartialEq for Record<'a, T> {
fn eq(&self, other: &Self) -> bool {
self.number == other.number
}
}
impl <'a, T: PartialOrd + Primitive> PartialOrd for Record<'a, T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.number.partial_cmp(&other.number)
}
}
impl <'a, T: Numeric + Primitive> Sum for Record<'a, T> {
fn sum<I>(mut iter: I) -> Record<'a, T> where I: Iterator<Item = Record<'a, T>> {
let mut total = Record::<'a, T>::zero();
loop {
match iter.next() {
None => return total,
Some(next) => total = match (total.history, next.history) {
(None, None) => Record {
number: total.number.clone() + next.number.clone(),
history: None,
index: 0,
},
(Some(history), None) => {
Record {
number: total.number.clone() + next.number.clone(),
history: Some(history),
index: history.append_unary(
total.index,
T::one()
),
}
},
(None, Some(history)) => {
Record {
number: total.number.clone() + next.number.clone(),
history: Some(history),
index: history.append_unary(
next.index,
T::one()
),
}
}
(Some(history), Some(_)) => {
assert!(same_list(&total, &next), "Records must be using the same WengertList");
Record {
number: total.number.clone() + next.number.clone(),
history: Some(history),
index: history.append_binary(
total.index,
T::one(),
next.index,
T::one()
),
}
},
},
}
}
}
}
impl <'a, T: Numeric + Real + Primitive> Sin for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sin(self) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().sin(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().sin(),
history: Some(history),
index: history.append_unary(
self.index,
self.number.clone().cos()
),
}
}
}
}
}
macro_rules! record_real_operator_impl_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op for Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self) -> Self::Output {
(&self).$method()
}
}
}
}
record_real_operator_impl_value!(impl Sin for Record { fn sin });
impl <'a, T: Numeric + Real + Primitive> Cos for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn cos(self) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().cos(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().cos(),
history: Some(history),
index: history.append_unary(
self.index,
-self.number.clone().sin()
),
}
}
}
}
}
record_real_operator_impl_value!(impl Cos for Record { fn cos });
impl <'a, T: Numeric + Real + Primitive> Exp for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn exp(self) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().exp(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().exp(),
history: Some(history),
index: history.append_unary(
self.index,
self.number.clone().exp()
),
}
}
}
}
}
record_real_operator_impl_value!(impl Exp for Record { fn exp });
impl <'a, T: Numeric + Real + Primitive> Ln for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn ln(self) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().ln(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().ln(),
history: Some(history),
index: history.append_unary(
self.index,
T::one() / self.number.clone()
),
}
}
}
}
}
record_real_operator_impl_value!(impl Ln for Record { fn ln });
impl <'a, T: Numeric + Real + Primitive> Sqrt for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn sqrt(self) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().sqrt(),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().sqrt(),
history: Some(history),
index: history.append_unary(
self.index,
T::one() / ((T::one() + T::one()) * self.number.clone().sqrt())
),
}
}
}
}
}
record_real_operator_impl_value!(impl Sqrt for Record { fn sqrt });
impl <'a, 'l, 'r, T: Numeric + Real + Primitive> Pow<&'r Record<'a, T>> for &'l Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn pow(self, rhs: &Record<'a, T>) -> Self::Output {
assert!(same_list(self, rhs), "Records must be using the same WengertList");
match (self.history, rhs.history) {
(None, None) => Record {
number: self.number.clone().pow(rhs.number.clone()),
history: None,
index: 0,
},
(Some(_), None) => self.pow(&rhs.number),
(None, Some(_)) => (&self.number).pow(rhs),
(Some(history), Some(_)) => Record {
number: self.number.clone().pow(rhs.number.clone()),
history: Some(history),
index: history.append_binary(
self.index,
rhs.number.clone() * self.number.clone().pow(rhs.number.clone() - T::one()),
rhs.index,
(self.number.clone().pow(rhs.number.clone())) * self.number.clone().ln()
),
},
}
}
}
macro_rules! record_real_operator_impl_value_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op for Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
(&self).$method(&rhs)
}
}
}
}
macro_rules! record_real_operator_impl_value_reference {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<&Record<'a, T>> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: &Record<'a, T>) -> Self::Output {
(&self).$method(rhs)
}
}
}
}
macro_rules! record_real_operator_impl_reference_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<Record<'a, T>> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
self.$method(&rhs)
}
}
}
}
record_real_operator_impl_value_value!(impl Pow for Record { fn pow });
record_real_operator_impl_reference_value!(impl Pow for Record { fn pow });
record_real_operator_impl_value_reference!(impl Pow for Record { fn pow });
impl <'a, T: Numeric + Real + Primitive> Pow<&T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn pow(self, rhs: &T) -> Self::Output {
match self.history {
None => Record {
number: self.number.clone().pow(rhs.clone()),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.number.clone().pow(rhs.clone()),
history: Some(history),
index: history.append_unary(
self.index,
rhs.clone() * self.number.clone().pow(rhs.clone() - T::one())
),
}
}
}
}
}
impl <'a, T: Numeric + Real + Primitive> Pow<&Record<'a, T>> for &T
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn pow(self, rhs: &Record<'a, T>) -> Self::Output {
match rhs.history {
None => Record {
number: self.clone().pow(rhs.number.clone()),
history: None,
index: 0,
},
Some(history) => {
Record {
number: self.clone().pow(rhs.number.clone()),
history: Some(history),
index: history.append_unary(
rhs.index,
(self.clone().pow(rhs.number.clone())) * self.clone().ln()
),
}
}
}
}
}
macro_rules! record_real_number_operator_impl_value_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: T) -> Self::Output {
(&self).$method(&rhs)
}
}
}
}
macro_rules! record_real_number_operator_impl_value_reference {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<&T> for Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: &T) -> Self::Output {
(&self).$method(rhs)
}
}
}
}
macro_rules! record_real_number_operator_impl_reference_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<T> for &Record<'a, T>
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: T) -> Self::Output {
self.$method(&rhs)
}
}
}
}
record_real_number_operator_impl_value_value!(impl Pow for Record { fn pow });
record_real_number_operator_impl_reference_value!(impl Pow for Record { fn pow });
record_real_number_operator_impl_value_reference!(impl Pow for Record { fn pow });
macro_rules! real_number_record_operator_impl_value_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<Record<'a, T>> for T
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
(&self).$method(&rhs)
}
}
}
}
macro_rules! real_number_record_operator_impl_value_reference {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<&Record<'a, T>> for T
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: &Record<'a, T>) -> Self::Output {
(&self).$method(rhs)
}
}
}
}
macro_rules! real_number_record_operator_impl_reference_value {
(impl $op:tt for Record { fn $method:ident }) => {
impl <'a, T: Numeric + Real + Primitive> $op<Record<'a, T>> for &T
where for<'t> &'t T: NumericRef<T> + RealRef<T> {
type Output = Record<'a, T>;
#[inline]
fn $method(self, rhs: Record<'a, T>) -> Self::Output {
self.$method(&rhs)
}
}
}
}
real_number_record_operator_impl_value_value!(impl Pow for Record { fn pow });
real_number_record_operator_impl_reference_value!(impl Pow for Record { fn pow });
real_number_record_operator_impl_value_reference!(impl Pow for Record { fn pow });
impl <'a, T: Numeric + Real + Primitive> Pi for Record<'a, T> {
#[inline]
fn pi() -> Record<'a, T> {
Record::constant(T::pi())
}
}