macros.rs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. macro_rules! forward_val_val_binop {
  2. (impl $imp:ident for $res:ty, $method:ident) => {
  3. impl $imp<$res> for $res {
  4. type Output = $res;
  5. #[inline]
  6. fn $method(self, other: $res) -> $res {
  7. // forward to val-ref
  8. $imp::$method(self, &other)
  9. }
  10. }
  11. }
  12. }
  13. macro_rules! forward_val_val_binop_commutative {
  14. (impl $imp:ident for $res:ty, $method:ident) => {
  15. impl $imp<$res> for $res {
  16. type Output = $res;
  17. #[inline]
  18. fn $method(self, other: $res) -> $res {
  19. // forward to val-ref, with the larger capacity as val
  20. if self.data.capacity() >= other.data.capacity() {
  21. $imp::$method(self, &other)
  22. } else {
  23. $imp::$method(other, &self)
  24. }
  25. }
  26. }
  27. }
  28. }
  29. macro_rules! forward_ref_val_binop {
  30. (impl $imp:ident for $res:ty, $method:ident) => {
  31. impl<'a> $imp<$res> for &'a $res {
  32. type Output = $res;
  33. #[inline]
  34. fn $method(self, other: $res) -> $res {
  35. // forward to ref-ref
  36. $imp::$method(self, &other)
  37. }
  38. }
  39. }
  40. }
  41. macro_rules! forward_ref_val_binop_commutative {
  42. (impl $imp:ident for $res:ty, $method:ident) => {
  43. impl<'a> $imp<$res> for &'a $res {
  44. type Output = $res;
  45. #[inline]
  46. fn $method(self, other: $res) -> $res {
  47. // reverse, forward to val-ref
  48. $imp::$method(other, self)
  49. }
  50. }
  51. }
  52. }
  53. macro_rules! forward_val_ref_binop {
  54. (impl $imp:ident for $res:ty, $method:ident) => {
  55. impl<'a> $imp<&'a $res> for $res {
  56. type Output = $res;
  57. #[inline]
  58. fn $method(self, other: &$res) -> $res {
  59. // forward to ref-ref
  60. $imp::$method(&self, other)
  61. }
  62. }
  63. }
  64. }
  65. macro_rules! forward_ref_ref_binop {
  66. (impl $imp:ident for $res:ty, $method:ident) => {
  67. impl<'a, 'b> $imp<&'b $res> for &'a $res {
  68. type Output = $res;
  69. #[inline]
  70. fn $method(self, other: &$res) -> $res {
  71. // forward to val-ref
  72. $imp::$method(self.clone(), other)
  73. }
  74. }
  75. }
  76. }
  77. macro_rules! forward_ref_ref_binop_commutative {
  78. (impl $imp:ident for $res:ty, $method:ident) => {
  79. impl<'a, 'b> $imp<&'b $res> for &'a $res {
  80. type Output = $res;
  81. #[inline]
  82. fn $method(self, other: &$res) -> $res {
  83. // forward to val-ref, choosing the larger to clone
  84. if self.data.len() >= other.data.len() {
  85. $imp::$method(self.clone(), other)
  86. } else {
  87. $imp::$method(other.clone(), self)
  88. }
  89. }
  90. }
  91. }
  92. }
  93. macro_rules! forward_scalar_val_val_binop_commutative {
  94. (impl $imp:ident<$scalar:ty> for $res:ty, $method: ident) => {
  95. impl $imp<$res> for $scalar {
  96. type Output = $res;
  97. #[inline]
  98. fn $method(self, other: $res) -> $res {
  99. $imp::$method(other, self)
  100. }
  101. }
  102. }
  103. }
  104. macro_rules! forward_scalar_val_ref_binop {
  105. (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
  106. impl<'a> $imp<&'a $scalar> for $res {
  107. type Output = $res;
  108. #[inline]
  109. fn $method(self, other: &$scalar) -> $res {
  110. $imp::$method(self, *other)
  111. }
  112. }
  113. impl<'a> $imp<$res> for &'a $scalar {
  114. type Output = $res;
  115. #[inline]
  116. fn $method(self, other: $res) -> $res {
  117. $imp::$method(*self, other)
  118. }
  119. }
  120. }
  121. }
  122. macro_rules! forward_scalar_ref_val_binop {
  123. (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
  124. impl<'a> $imp<$scalar> for &'a $res {
  125. type Output = $res;
  126. #[inline]
  127. fn $method(self, other: $scalar) -> $res {
  128. $imp::$method(self.clone(), other)
  129. }
  130. }
  131. impl<'a> $imp<&'a $res> for $scalar {
  132. type Output = $res;
  133. #[inline]
  134. fn $method(self, other: &$res) -> $res {
  135. $imp::$method(self, other.clone())
  136. }
  137. }
  138. }
  139. }
  140. macro_rules! forward_scalar_ref_ref_binop {
  141. (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
  142. impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
  143. type Output = $res;
  144. #[inline]
  145. fn $method(self, other: &$scalar) -> $res {
  146. $imp::$method(self.clone(), *other)
  147. }
  148. }
  149. impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
  150. type Output = $res;
  151. #[inline]
  152. fn $method(self, other: &$res) -> $res {
  153. $imp::$method(*self, other.clone())
  154. }
  155. }
  156. }
  157. }
  158. macro_rules! promote_scalars {
  159. (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
  160. $(
  161. forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
  162. impl $imp<$scalar> for $res {
  163. type Output = $res;
  164. #[inline]
  165. fn $method(self, other: $scalar) -> $res {
  166. $imp::$method(self, other as $promo)
  167. }
  168. }
  169. impl $imp<$res> for $scalar {
  170. type Output = $res;
  171. #[inline]
  172. fn $method(self, other: $res) -> $res {
  173. $imp::$method(self as $promo, other)
  174. }
  175. }
  176. )*
  177. }
  178. }
  179. macro_rules! promote_unsigned_scalars {
  180. (impl $imp:ident for $res:ty, $method:ident) => {
  181. promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
  182. promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
  183. }
  184. }
  185. macro_rules! promote_signed_scalars {
  186. (impl $imp:ident for $res:ty, $method:ident) => {
  187. promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
  188. promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
  189. }
  190. }
  191. // Forward everything to ref-ref, when reusing storage is not helpful
  192. macro_rules! forward_all_binop_to_ref_ref {
  193. (impl $imp:ident for $res:ty, $method:ident) => {
  194. forward_val_val_binop!(impl $imp for $res, $method);
  195. forward_val_ref_binop!(impl $imp for $res, $method);
  196. forward_ref_val_binop!(impl $imp for $res, $method);
  197. };
  198. }
  199. // Forward everything to val-ref, so LHS storage can be reused
  200. macro_rules! forward_all_binop_to_val_ref {
  201. (impl $imp:ident for $res:ty, $method:ident) => {
  202. forward_val_val_binop!(impl $imp for $res, $method);
  203. forward_ref_val_binop!(impl $imp for $res, $method);
  204. forward_ref_ref_binop!(impl $imp for $res, $method);
  205. };
  206. }
  207. // Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
  208. macro_rules! forward_all_binop_to_val_ref_commutative {
  209. (impl $imp:ident for $res:ty, $method:ident) => {
  210. forward_val_val_binop_commutative!(impl $imp for $res, $method);
  211. forward_ref_val_binop_commutative!(impl $imp for $res, $method);
  212. forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
  213. };
  214. }
  215. macro_rules! forward_all_scalar_binop_to_val_val {
  216. (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
  217. forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
  218. forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
  219. forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
  220. }
  221. }
  222. macro_rules! forward_all_scalar_binop_to_val_val_commutative {
  223. (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
  224. forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
  225. forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
  226. }
  227. }
  228. macro_rules! promote_all_scalars {
  229. (impl $imp:ident for $res:ty, $method:ident) => {
  230. promote_unsigned_scalars!(impl $imp for $res, $method);
  231. promote_signed_scalars!(impl $imp for $res, $method);
  232. }
  233. }