use batch_impl::batch_impl;
use std::borrow::Cow;
use std::rc::Rc;
#[batch_impl([u8] impl{[A]} { fn n(&self) -> usize { self.len() } })]
trait ShapeSlice {
fn n(&self) -> usize;
}
#[test]
fn shape_slice() {
let s: &[u8] = &[1, 2, 3];
assert_eq!(s.n(), 3);
}
#[batch_impl((u8, u16, u32) impl{(A, B, C)} { fn sum(&self) -> u32 { self.0 as u32 + self.1 as u32 + self.2 } })]
trait ShapeTriple {
fn sum(&self) -> u32;
}
#[test]
fn shape_triple_tuple() {
let t = (1u8, 2u16, 3u32);
assert_eq!(t.sum(), 6);
}
#[batch_impl([u8; 3] impl{[A; 3]} { fn n(&self) -> usize { self.len() } })]
trait ShapeArrLit {
fn n(&self) -> usize;
}
#[test]
fn shape_array_literal_len() {
let a = [1u8, 2, 3];
assert_eq!(a.n(), 3);
}
#[batch_impl(&'static u8 impl{&'static A} { fn val(&self) -> A { **self } })]
trait ShapeRefLt {
fn val(&self) -> u8;
}
#[test]
fn shape_ref_with_lifetime() {
static X: u8 = 9;
assert_eq!((&X).val(), 9);
}
#[batch_impl([[u8; 2]; 2] impl{[[A; 2]; 2]} { fn n(&self) -> usize { self.len() } })]
trait ShapeNestedArr {
fn n(&self) -> usize;
}
#[test]
fn shape_nested_array() {
let a = [[1u8, 2], [3, 4]];
assert_eq!(a.n(), 2);
}
#[batch_impl(std::rc::Rc<u8> impl{std::rc::Rc<A>} { fn val(&self) -> A { **self } })]
trait ShapePath {
fn val(&self) -> u8;
}
#[test]
fn shape_multi_segment_path() {
let r = std::rc::Rc::new(7u8);
assert_eq!(r.val(), 7);
}
#[batch_impl(fn(u8) -> u16 impl{fn(u8) -> u16} { fn invoke(&self, x: u8) -> u16 { self(x) } })]
trait ShapeFn {
fn invoke(&self, x: u8) -> u16;
}
#[test]
fn shape_fn_ptr_identical() {
let f: fn(u8) -> u16 = |x| x as u16 + 1;
assert_eq!(f.invoke(4), 5);
}
#[batch_impl(dyn Fn(u8) -> u16 + Send impl{dyn Fn(u8) -> u16 + Send} { fn invoke(&self, x: u8) -> u16 { self(x) } })]
trait ShapeDyn {
fn invoke(&self, x: u8) -> u16;
}
#[test]
fn shape_trait_object_identical() {
fn f(x: u8) -> u16 {
x as u16 + 2
}
let d: &(dyn Fn(u8) -> u16 + Send) = &f;
assert_eq!(d.invoke(4), 6);
}
#[batch_impl(Cow<'_, u8> impl{Cow<'_, A>} { fn val(&self) -> A { **self } })]
trait ShapeCow {
fn val(&self) -> u8;
}
#[test]
fn shape_cow_same_shape() {
let c = std::borrow::Cow::Borrowed(&5u8);
assert_eq!(c.val(), 5);
}
#[batch_impl([Box, Rc]^@num impl{Box<u8>} #mk{Box::new(u8::MAX)})]
trait TMk {
fn mk() -> Self;
}
#[test]
fn prototype_impl_covers_matrix() {
assert_eq!(<Box<u8> as TMk>::mk(), Box::new(u8::MAX));
assert_eq!(<Box<u16> as TMk>::mk(), Box::new(u16::MAX));
assert_eq!(<Box<f32> as TMk>::mk(), Box::new(f32::MAX));
assert_eq!(<Rc<u8> as TMk>::mk(), Rc::new(u8::MAX));
assert_eq!(<Rc<usize> as TMk>::mk(), Rc::new(usize::MAX));
}
#[batch_impl(Cow<'_, [u8, u16]> impl{Cow<'_, A>} { fn tag(&self) -> usize { 12 } })]
trait ShapeCowMatrix {
fn tag(&self) -> usize;
}
#[test]
fn shape_cow_matrix_leaves() {
let c = Cow::Borrowed(&7u8);
assert_eq!(c.tag(), 12);
let d: Cow<'_, u16> = Cow::Owned(9u16);
assert_eq!(d.tag(), 12);
}
#[batch_impl(
[Box, Rc]^@num impl{Box<u8>} #tag{13},
Cow<'_, @num> impl{Cow<'_, u8>} #tag{13}
)]
trait MultiProto {
fn tag() -> usize;
}
#[test]
fn multi_prototype_covers_families() {
assert_eq!(<Box<u8> as MultiProto>::tag(), 13);
assert_eq!(<Box<f64> as MultiProto>::tag(), 13);
assert_eq!(<Rc<u16> as MultiProto>::tag(), 13);
assert_eq!(<Cow<'_, u8> as MultiProto>::tag(), 13);
assert_eq!(<Cow<'_, i32> as MultiProto>::tag(), 13);
}
#[batch_impl(
[[Box, Rc]^@num impl{Box<u8>},
Cow<'_, @num> impl{Cow<'_, u8>}] #tag{14}
)]
trait ProtoListShared {
fn tag() -> usize;
}
#[test]
fn prototype_list_shared_body() {
assert_eq!(<Box<u8> as ProtoListShared>::tag(), 14);
assert_eq!(<Box<f64> as ProtoListShared>::tag(), 14);
assert_eq!(<Rc<u16> as ProtoListShared>::tag(), 14);
assert_eq!(<Cow<'_, u8> as ProtoListShared>::tag(), 14);
assert_eq!(<Cow<'_, i32> as ProtoListShared>::tag(), 14);
}
#[batch_impl(
[[Box, Rc] impl{Box<u8>},
Cow<'_> impl{Cow<'_, u8>}]^@num #tag{15}
)]
trait ProtoListPow {
fn tag() -> usize;
}
#[test]
fn prototype_list_pow() {
assert_eq!(<Box<u8> as ProtoListPow>::tag(), 15);
assert_eq!(<Box<f64> as ProtoListPow>::tag(), 15);
assert_eq!(<Rc<u16> as ProtoListPow>::tag(), 15);
assert_eq!(<Cow<'_, u8> as ProtoListPow>::tag(), 15);
assert_eq!(<Cow<'_, i32> as ProtoListPow>::tag(), 15);
}
#[batch_impl([u8; 3] impl{[A; N]} { fn n16(&self) -> usize { N } })]
trait ShapeArrLenBound {
fn n16(&self) -> usize;
}
#[test]
fn shape_array_length_binding() {
let a = [1u8, 2, 3];
assert_eq!(a.n16(), 3);
}
#[batch_impl(<'a> Cow<'a, u8> impl{Cow<'_, A>} { fn val17(&self) -> A { **self } })]
trait ShapeCowWildcard {
fn val17(&self) -> u8;
}
#[test]
fn shape_cow_lifetime_wildcard() {
let c = Cow::Borrowed(&1u8);
assert_eq!(c.val17(), 1);
fn assert_trait<T: ShapeCowWildcard>() {}
assert_trait::<Cow<'static, u8>>();
}