1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::marker::PhantomData;

/// A zero-sized empty vector which returns None for all indices.
///
/// # Examples
///
/// Say, for instance, we have a function requiring a vector, `FunVec<1, i32>`.
///
/// ```rust
/// use orx_funvec::*;
/// fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
///     vec.at(2)
/// }
/// ```
/// We might often call this function with a `Vec<i32>`.
///
/// ```rust
/// # use orx_funvec::*;
/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
/// #     vec.at(2)
/// # }
/// let numbers = vec![1, 2, 3, 4, 5, 6];
/// assert_eq!(Some(3), third_element(&numbers));
/// ```
/// There might however be special cases where our input vector is empty.
/// Following could still work:
///
/// ```rust
/// # use orx_funvec::*;
/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
/// #    vec.at(2)
/// # }
/// let numbers = vec![];
/// assert_eq!(None, third_element(&numbers));
/// ```
///
/// However, this would not be the best way to achieve this:
/// * 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.
///
/// We can instead use `EmptyVec` for this purpose which implements `FunVec<1, _>`.
///
/// ```rust
/// # use orx_funvec::*;
/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
/// #    vec.at(2)
/// # }
/// let numbers = EmptyVec::default();
/// assert_eq!(None, third_element(&numbers));
/// ```
///
/// Actually, `EmptyVec` implements `FunVec` for all dimensions::
///
/// ```rust
/// # use orx_funvec::*;
///
/// let numbers: EmptyVec<&str> = EmptyVec::default();
///
/// assert_eq!(None, numbers.at(3));
/// assert_eq!(None, numbers.at([7, 2]));
/// assert_eq!(None, numbers.at([14, 1, 0]));
/// assert_eq!(None, numbers.at((4, 1, 3, 6))); // array or tuple indices can be used interchangeably
/// ```
#[derive(derive_new::new, Default)]
pub struct EmptyVec<T: ?Sized>(PhantomData<T>);