From 8cdfa445d6629ffef4cb84967ff7017654045bc2 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 2 Jul 2025 18:36:06 -0600 Subject: chore: add vendor directory --- vendor/overload/src/lib.rs | 257 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 vendor/overload/src/lib.rs (limited to 'vendor/overload/src/lib.rs') diff --git a/vendor/overload/src/lib.rs b/vendor/overload/src/lib.rs new file mode 100644 index 00000000..9364d7a3 --- /dev/null +++ b/vendor/overload/src/lib.rs @@ -0,0 +1,257 @@ +//! Provides a macro to simplify operator overloading. +//! +//! To use, include the following: +//! ``` +//! extern crate overload; +//! use overload::overload; +//! use std::ops; // <- don't forget this or you'll get nasty errors +//! ``` +//! +//! # Introduction +//! +//! Suppose we have the following `struct` definition: +//! ``` +//! #[derive(PartialEq, Debug)] +//! struct Val { +//! v: i32 +//! } +//! ``` +//! We can overload the addition of `Val`s like so: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! overload!((a: Val) + (b: Val) -> Val { Val { v: a.v + b.v } }); +//! ``` +//! The macro call above generates the following code: +//! ```ignore +//! impl ops::Add for Val { +//! type Output = Val; +//! fn add(self, b: Val) -> Self::Output { +//! let a = self; +//! Val { v: a.v + b.v } +//! } +//! } +//! ``` +//! We are now able to add `Val`s: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! # overload!((a: Val) + (b: Val) -> Val { Val { v: a.v + b.v } }); +//! assert_eq!(Val{v:3} + Val{v:5}, Val{v:8}); +//! ``` +//! +//! # Owned and borrowed types +//! +//! If we also wanted to overload addition for the borrowed type `&Val` we could write: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! overload!((a: &Val) + (b: &Val) -> Val { Val { v: a.v + b.v } }); +//! ``` +//! We might also want to overload addition between the owned and borrowed types: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! overload!((a: Val) + (b: &Val) -> Val { Val { v: a.v + b.v } }); +//! overload!((a: &Val) + (b: Val) -> Val { Val { v: a.v + b.v } }); +//! ``` +//! Let's see how we can write these combinations more concisely. +//! +//! We can include a `?` in front of a type to indicate that it should stand in for both the owned and borrowed type. +//! +//! To overload addition for all four combinations between `Val` and `&Val` we can therefore simply include a `?` in front of both types: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! overload!((a: ?Val) + (b: ?Val) -> Val { Val { v: a.v + b.v } }); +//! ``` +//! The macro call above generates the following code: +//! ```ignore +//! impl ops::Add for Val { +//! type Output = Val; +//! fn add(self, b: Val) -> Self::Output { +//! let a = self; +//! Val { v: a.v + b.v } +//! } +//! } +//! +//! impl ops::Add<&Val> for Val { +//! type Output = Val; +//! fn add(self, b: &Val) -> Self::Output { +//! let a = self; +//! Val { v: a.v + b.v } +//! } +//! } +//! +//! impl ops::Add for &Val { +//! type Output = Val; +//! fn add(self, b: Val) -> Self::Output { +//! let a = self; +//! Val { v: a.v + b.v } +//! } +//! } +//! +//! impl ops::Add<&Val> for &Val { +//! type Output = Val; +//! fn add(self, b: &Val) -> Self::Output { +//! let a = self; +//! Val { v: a.v + b.v } +//! } +//! } +//! ``` +//! We are now able to add `Val`s and `&Val`s in any combination: +//! ``` +//! # extern crate overload; +//! # use overload::overload; +//! # use std::ops; +//! # #[derive(PartialEq, Debug)] +//! # struct Val { +//! # v: i32 +//! # } +//! # overload!((a: ?Val) + (b: ?Val) -> Val { Val { v: a.v + b.v } }); +//! assert_eq!(Val{v:3} + Val{v:5}, Val{v:8}); +//! assert_eq!(Val{v:3} + &Val{v:5}, Val{v:8}); +//! assert_eq!(&Val{v:3} + Val{v:5}, Val{v:8}); +//! assert_eq!(&Val{v:3} + &Val{v:5}, Val{v:8}); +//! ``` +//! +//! # Binary operators +//! +//! The general syntax to overload a binary operator between types `` and `` is: +//! ```ignore +//! overload!((: ) (: ) -> { /*body*/ }); +//! ``` +//! Inside the body you can use `` and `` freely to perform any computation. +//! +//! The last line of the body needs to be an expression (i.e. no `;` at the end of the line) of type ``. +//! +//! | Operator | Example | Trait | +//! |----------|-----------------------------------------------------------------|--------| +//! | + | `overload!((a: A) + (b: B) -> C { /*...*/ );` | Add | +//! | - | `overload!((a: A) - (b: B) -> C { /*...*/ );` | Sub | +//! | * | `overload!((a: A) * (b: B) -> C { /*...*/ );` | Mul | +//! | / | `overload!((a: A) / (b: B) -> C { /*...*/ );` | Div | +//! | % | `overload!((a: A) % (b: B) -> C { /*...*/ );` | Rem | +//! | & | `overload!((a: A) & (b: B) -> C { /*...*/ );` | BitAnd | +//! | \| | overload!((a: A) | (b: B) -> C { /\*...*\/ ); | BitOr | +//! | ^ | `overload!((a: A) ^ (b: B) -> C { /*...*/ );` | BitXor | +//! | << | `overload!((a: A) << (b: B) -> C { /*...*/ );` | Shl | +//! | >> | `overload!((a: A) >> (b: B) -> C { /*...*/ );` | Shr | +//! +//! # Assignment operators +//! +//! The general syntax to overload an assignment operator between types `` and `` is: +//! ```ignore +//! overload!((: &mut ) (: ) { /*body*/ }); +//! ``` +//! Inside the body you can use `` and `` freely to perform any computation and mutate `` as desired. +//! +//! | Operator | Example | Trait | +//! |----------|------------------------------------------------------------------|--------------| +//! | += | `overload!((a: &mut A) += (b: B) { /*...*/ );` | AddAssign | +//! | -= | `overload!((a: &mut A) -= (b: B) { /*...*/ );` | SubAssign | +//! | *= | `overload!((a: &mut A) *= (b: B) { /*...*/ );` | MulAssign | +//! | /= | `overload!((a: &mut A) /= (b: B) { /*...*/ );` | DivAssign | +//! | %= | `overload!((a: &mut A) %= (b: B) { /*...*/ );` | RemAssign | +//! | &= | `overload!((a: &mut A) &= (b: B) { /*...*/ );` | BitAndAssign | +//! | \|= | overload!((a: &mut A) |= (b: B) { /\*...*\/ ); | BitOrAssign | +//! | ^= | `overload!((a: &mut A) ^= (b: B) { /*...*/ );` | BitXorAssign | +//! | <<= | `overload!((a: &mut A) <<= (b: B) { /*...*/ );` | ShlAssign | +//! | >>= | `overload!((a: &mut A) >>= (b: B) { /*...*/ );` | ShrAssign | +//! +//! # Unary operators +//! +//! The general syntax to overload a unary operator for type `` is: +//! ```ignore +//! overload!( (: ) -> { /*body*/ }); +//! ``` +//! Inside the body you can use `` freely to perform any computation. +//! +//! The last line of the body needs to be an expression (i.e. no `;` at the end of the line) of type ``. +//! +//! | Operator | Example | Trait | +//! |----------|---------------------------------------------------------|-------| +//! | - | `overload!(- (a: A) -> B { /*...*/ );` | Neg | +//! | ! | `overload!(! (a: A) -> B { /*...*/ );` | Not | +//! +//! # Notes +//! +//! Remember that you can only overload operators between one or more types if at least one of the types is defined in the current crate. + +#[macro_use] +mod unary; + +#[macro_use] +mod assignment; + +#[macro_use] +mod binary; + +/// Overloads an operator. See the [module level documentation](index.html) for more information. +#[macro_export(local_inner_macros)] +macro_rules! overload { + // Unary (both owned and borrowed) + ($op:tt ($i:ident : ? $t:ty) -> $out:ty $body:block) => ( + _overload_unary!($op, $i, $t, $out, $body); + _overload_unary!($op, $i, &$t, $out, $body); + ); + // Unary (either owned or borrowed) + ($op:tt ($i:ident : $t:ty) -> $out:ty $body:block) => ( + _overload_unary!($op, $i, $t, $out, $body); + ); + // Assignment (both owned and borrowed) + (($li:ident : &mut $lt:ty) $op:tt ($ri:ident : ? $rt:ty) $body:block) => ( + _overload_assignment!($op, $li, $lt, $ri, $rt, $body); + _overload_assignment!($op, $li, $lt, $ri, &$rt, $body); + ); + // Assignment (either owned or borrowed) + (($li:ident : &mut $lt:ty) $op:tt ($ri:ident : $rt:ty) $body:block) => ( + _overload_assignment!($op, $li, $lt, $ri, $rt, $body); + ); + // Binary (both - both) + (($li:ident : ? $lt:ty) $op:tt ($ri:ident : ? $rt:ty) -> $out:ty $body:block) => ( + _overload_binary!($op, $li, $lt, $ri, $rt, $out, $body); + _overload_binary!($op, $li, $lt, $ri, &$rt, $out, $body); + _overload_binary!($op, $li, &$lt, $ri, $rt, $out, $body); + _overload_binary!($op, $li, &$lt, $ri, &$rt, $out, $body); + ); + // Binary (both - either) + (($li:ident : ? $lt:ty) $op:tt ($ri:ident : $rt:ty) -> $out:ty $body:block) => ( + _overload_binary!($op, $li, $lt, $ri, $rt, $out, $body); + _overload_binary!($op, $li, &$lt, $ri, $rt, $out, $body); + ); + // Binary (either - both) + (($li:ident : $lt:ty) $op:tt ($ri:ident : ? $rt:ty) -> $out:ty $body:block) => ( + _overload_binary!($op, $li, $lt, $ri, $rt, $out, $body); + _overload_binary!($op, $li, $lt, $ri, &$rt, $out, $body); + ); + // Binary (either - either) + (($li:ident : $lt:ty) $op:tt ($ri:ident : $rt:ty) -> $out:ty $body:block) => ( + _overload_binary!($op, $li, $lt, $ri, $rt, $out, $body); + ); +} -- cgit v1.2.3