orx_funvec/scalar_as_vec.rs
1/// Nothing but a wrapped value, a tuple struct, that allows to represent its internal scalar value as
2/// an infinite-length vector having the same value at all positions.
3///
4/// # Examples
5///
6/// Say, for instance, we have a function requiring a vector, `FunVec<1, i32>`.
7///
8/// ```rust
9/// use orx_funvec::*;
10/// fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
11/// vec.at(2)
12/// }
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///
26/// There might however be special cases where our input vector is all 42s.
27/// Probably not 42s, but all zeros/ones vectors/matrices are often very useful.
28/// Following would work:
29///
30/// ```rust
31/// # use orx_funvec::*;
32/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
33/// # vec.at(2)
34/// # }
35/// let numbers = vec![42, 42, 42, 42, 42];
36/// assert_eq!(Some(42), third_element(&numbers));
37/// ```
38///
39/// However, this would not be the best way to achieve this:
40///
41/// * we allocate a vector just to return 42, and
42/// * we make method calls just to read 42 and lose compiler optimization potential.
43///
44/// We can instead use `ScalarAsVec` wrapper which implements `FunVec<1, _>`:
45///
46/// ```rust
47/// # use orx_funvec::*;
48/// # fn third_element<V: FunVec<1, i32>>(vec: &V) -> Option<i32> {
49/// # vec.at(2)
50/// # }
51/// let numbers = ScalarAsVec(42);
52/// assert_eq!(Some(42), third_element(&numbers));
53/// ```
54///
55/// Actually, `ScalarAsVec` implements `FunVec` for all dimensions:
56///
57/// ```rust
58/// # use orx_funvec::*;
59///
60/// let numbers = ScalarAsVec(42);
61///
62/// assert_eq!(Some(42), numbers.at(3));
63/// assert_eq!(Some(42), numbers.at([7, 2]));
64/// assert_eq!(Some(42), numbers.at([14, 1, 0]));
65/// assert_eq!(Some(42), numbers.at((4, 1, 3, 6))); // array or tuple indices can be used interchangeably
66/// ```
67pub struct ScalarAsVec<T>(pub T);