orx_funvec/
empty_vec.rs

1use std::marker::PhantomData;
2
3/// A zero-sized empty vector which returns None for all indices.
4///
5/// # Examples
6///
7/// Say, for instance, we have a function requiring a vector, `FunVec<1, i32>`.
8///
9/// ```rust
10/// use orx_funvec::*;
11/// fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
12///     vec.at(2)
13/// }
14/// ```
15/// We might often call this function with a `Vec<i32>`.
16///
17/// ```rust
18/// # use orx_funvec::*;
19/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
20/// #     vec.at(2)
21/// # }
22/// let numbers = vec![1, 2, 3, 4, 5, 6];
23/// assert_eq!(Some(3), third_element(&numbers));
24/// ```
25/// There might however be special cases where our input vector is empty.
26/// Following could still work:
27///
28/// ```rust
29/// # use orx_funvec::*;
30/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
31/// #    vec.at(2)
32/// # }
33/// let numbers = vec![];
34/// assert_eq!(None, third_element(&numbers));
35/// ```
36///
37/// However, this would not be the best way to achieve this:
38/// * since the `third_element` is already generic, we can take complete benefit of monomorphization and inlining by using a specific type that does nothing but returns `None` for all indices.
39///
40/// We can instead use `EmptyVec` for this purpose which implements `FunVec<1, _>`.
41///
42/// ```rust
43/// # use orx_funvec::*;
44/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
45/// #    vec.at(2)
46/// # }
47/// let numbers = EmptyVec::default();
48/// assert_eq!(None, third_element(&numbers));
49/// ```
50///
51/// Actually, `EmptyVec` implements `FunVec` for all dimensions::
52///
53/// ```rust
54/// # use orx_funvec::*;
55///
56/// let numbers: EmptyVec<&str> = EmptyVec::default();
57///
58/// assert_eq!(None, numbers.at(3));
59/// assert_eq!(None, numbers.at([7, 2]));
60/// assert_eq!(None, numbers.at([14, 1, 0]));
61/// assert_eq!(None, numbers.at((4, 1, 3, 6))); // array or tuple indices can be used interchangeably
62/// ```
63#[derive(derive_new::new, Default)]
64pub struct EmptyVec<T: ?Sized>(PhantomData<T>);