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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
use crate::{mat::*, utils::slice::*, Conj};
use coe::Coerce;
use core::{marker::PhantomData, ptr::NonNull};
use faer_entity::*;
use reborrow::*;

#[repr(C)]
pub(crate) struct VecImpl<E: Entity> {
    pub(crate) ptr: GroupCopyFor<E, NonNull<E::Unit>>,
    pub(crate) len: usize,
    pub(crate) stride: isize,
}
#[repr(C)]
pub(crate) struct VecOwnImpl<E: Entity> {
    pub(crate) ptr: GroupCopyFor<E, NonNull<E::Unit>>,
    pub(crate) len: usize,
}

impl<E: Entity> Copy for VecImpl<E> {}
impl<E: Entity> Clone for VecImpl<E> {
    #[inline(always)]
    fn clone(&self) -> Self {
        *self
    }
}

unsafe impl<E: Entity> Sync for VecImpl<E> {}
unsafe impl<E: Entity> Send for VecImpl<E> {}
unsafe impl<E: Entity> Sync for VecOwnImpl<E> {}
unsafe impl<E: Entity> Send for VecOwnImpl<E> {}

/// Represents a type that can be used to slice a column, such as an index or a range of indices.
pub trait ColIndex<RowRange>: crate::seal::Seal + Sized {
    /// Resulting type of the indexing operation.
    type Target;

    /// Index the column at `row`, without bound checks.
    #[allow(clippy::missing_safety_doc)]
    unsafe fn get_unchecked(this: Self, row: RowRange) -> Self::Target {
        <Self as ColIndex<RowRange>>::get(this, row)
    }
    /// Index the column at `row`.
    fn get(this: Self, row: RowRange) -> Self::Target;
}

/// Trait for types that can be converted to a column view.
pub trait AsColRef<E: Entity> {
    /// Convert to a column view.
    fn as_col_ref(&self) -> ColRef<'_, E>;
}
/// Trait for types that can be converted to a mutable column view.
pub trait AsColMut<E: Entity>: AsColRef<E> {
    /// Convert to a mutable column view.
    fn as_col_mut(&mut self) -> ColMut<'_, E>;
}

impl<E: Entity, T: AsColRef<E>> AsColRef<E> for &T {
    fn as_col_ref(&self) -> ColRef<'_, E> {
        (**self).as_col_ref()
    }
}
impl<E: Entity, T: AsColRef<E>> AsColRef<E> for &mut T {
    fn as_col_ref(&self) -> ColRef<'_, E> {
        (**self).as_col_ref()
    }
}

impl<E: Entity, T: AsColMut<E>> AsColMut<E> for &mut T {
    fn as_col_mut(&mut self) -> ColMut<'_, E> {
        (**self).as_col_mut()
    }
}

mod col_index;

mod colref;
pub use colref::{
    from_raw_parts, from_ref, from_ref_generic, from_repeated_ref, from_repeated_ref_generic,
    from_slice, from_slice_generic, ColRef,
};

mod colmut;
pub use colmut::{
    from_mut, from_mut_generic, from_raw_parts_mut, from_slice_mut, from_slice_mut_generic, ColMut,
};

mod colown;
pub use colown::Col;

/// Type that can be interpreted as a batch of column vectors. Can be a single column or a matrix.
pub trait ColBatch<E: Conjugate>: As2D<E> {
    /// Corresponding owning type.
    type Owned: ColBatchMut<E::Canonical>;

    /// Constructor of the owned type that initializes the values to zero.
    fn new_owned_zeros(nrows: usize, ncols: usize) -> Self::Owned;

    /// Constructor of the owned type that copies the values.
    fn new_owned_copied(src: &Self) -> Self::Owned;

    /// Resize an owned column or matrix.
    fn resize_owned(owned: &mut Self::Owned, nrows: usize, ncols: usize);
}

/// Type that can be interpreted as a mutable batch of column vectors. Can be a single column or a
/// matrix.
pub trait ColBatchMut<E: Conjugate>: As2DMut<E> + ColBatch<E> {}

impl<E: Conjugate, T: ColBatch<E>> ColBatch<E> for &T {
    type Owned = T::Owned;

    #[inline]
    #[track_caller]
    fn new_owned_zeros(nrows: usize, ncols: usize) -> Self::Owned {
        T::new_owned_zeros(nrows, ncols)
    }

    #[inline]
    fn new_owned_copied(src: &Self) -> Self::Owned {
        T::new_owned_copied(src)
    }

    #[inline]
    fn resize_owned(owned: &mut Self::Owned, nrows: usize, ncols: usize) {
        T::resize_owned(owned, nrows, ncols)
    }
}

impl<E: Conjugate, T: ColBatch<E>> ColBatch<E> for &mut T {
    type Owned = T::Owned;

    #[inline]
    #[track_caller]
    fn new_owned_zeros(nrows: usize, ncols: usize) -> Self::Owned {
        T::new_owned_zeros(nrows, ncols)
    }

    #[inline]
    fn new_owned_copied(src: &Self) -> Self::Owned {
        T::new_owned_copied(src)
    }

    #[inline]
    fn resize_owned(owned: &mut Self::Owned, nrows: usize, ncols: usize) {
        T::resize_owned(owned, nrows, ncols)
    }
}

impl<E: Conjugate, T: ColBatchMut<E>> ColBatchMut<E> for &mut T {}

impl<'a, FromE: Entity, ToE: Entity> Coerce<ColRef<'a, ToE>> for ColRef<'a, FromE> {
    #[inline(always)]
    fn coerce(self) -> ColRef<'a, ToE> {
        assert!(coe::is_same::<FromE, ToE>());
        unsafe { transmute_unchecked::<ColRef<'a, FromE>, ColRef<'a, ToE>>(self) }
    }
}
impl<'a, FromE: Entity, ToE: Entity> Coerce<ColMut<'a, ToE>> for ColMut<'a, FromE> {
    #[inline(always)]
    fn coerce(self) -> ColMut<'a, ToE> {
        assert!(coe::is_same::<FromE, ToE>());
        unsafe { transmute_unchecked::<ColMut<'a, FromE>, ColMut<'a, ToE>>(self) }
    }
}