devela/data/list/array/d2/
definitions.rs

1// devela::data::list::array::d2::definitions
2//
3//! 2-dimensional array definitions
4//
5
6use crate::{Array, Bare, Storage};
7// #[cfg(feature = "dep_rkyv")] // DEP_DISABLED
8// use rkyv::{Archive, Deserialize, Serialize};
9
10#[doc = crate::TAG_DATA_STRUCTURE!()]
11/// A static 2-dimensional [`Array`].
12///
13/// It is generic in respect to its:
14/// - elements (`T`),
15/// - number of columns (`C`),
16/// - number of rows (`R`),
17/// - total capacity (`CR`),
18/// - storage order (`RMAJ`)
19/// - storage abstraction (`S`).
20///
21/// The total lenght `CR` must be equal to the product `C` * `R`.
22///
23/// The
24/// [*storage order*](https://en.wikipedia.org/wiki/Row-_and_column-major_order)
25/// is row-major by default (`RMAJ = true`). It can be column-major if set to false.
26///
27/// ## Methods
28///
29/// - Construct:
30///   [`with_cloned`][Self::with_cloned],
31///   [`with_copied`][Self::with_copied].
32/// - Deconstruct:
33///   [`as_slice`][Self::as_slice],
34///   [`as_mut_slice`][Self::as_mut_slice],
35///   [`into_array`][Self::into_array]*([`const`][Self::into_array_copy])*,
36///   [`into_slice`][Self::into_slice]*(`alloc`)*,
37///   [`into_vec`][Self::into_vec]*(`alloc`)*.
38/// - Query:
39///   [`capacity`][Self::capacity],
40///   [`cap_col`][Self::cap_col],
41///   [`cap_row`][Self::cap_row],
42///   [`contains`][Self::contains].
43/// - Indexing and coordinates (for the current order):
44///   - [`get_ref`][Self::get_ref]*([`uc`][Self::get_ref_unchecked])*,
45///   [`get_mut`][Self::get_mut]*([`uc`][Self::get_mut_unchecked])*,
46///   [`set`][Self::set]*([`uc`][Self::set_unchecked])*,
47///   [`get_index`][Self::get_index]*([`uc`][Self::get_index_unchecked])*,
48///   [`get_coords`][Self::get_coords]*([`uc`][Self::get_coords_unchecked])*.
49/// - Indexing and coordinates (specific for the **opposite** order):
50///   - row-major:
51///   [`get_ref_cmaj`][Self::get_ref_cmaj]*([`uc`][Self::get_ref_cmaj_unchecked])*,
52///   [`get_mut_cmaj`][Self::get_mut_cmaj]*([`uc`][Self::get_mut_cmaj_unchecked])*,
53///   [`set_cmaj`][Self::set_cmaj]*([`uc`][Self::set_cmaj_unchecked])*,
54///   [`get_index_cmaj`][Self::get_index_cmaj]*([`uc`][Self::get_index_cmaj_unchecked])*,
55///   [`get_coords_cmaj`][Self::get_coords_cmaj]*([`uc`][Self::get_coords_cmaj_unchecked])*.
56///   - column-major:
57///   [`get_ref_rmaj`][Self::get_ref_rmaj]*([`uc`][Self::get_ref_rmaj_unchecked])*,
58///   [`get_mut_rmaj`][Self::get_mut_rmaj]*([`uc`][Self::get_mut_rmaj_unchecked])*,
59///   [`set_rmaj`][Self::set_rmaj]*([`uc`][Self::set_rmaj_unchecked])*,
60///   [`get_index_rmaj`][Self::get_index_rmaj]*([`uc`][Self::get_index_rmaj_unchecked])*,
61///   [`get_coords_rmaj`][Self::get_coords_rmaj]*([`uc`][Self::get_coords_rmaj_unchecked])*.
62///
63/// ## Panics
64/// Note that the `Default` and `ConstDefault` constructors will panic if `C * R != CR`.
65//
66// WAIT: [adt_const_params](https://github.com/rust-lang/rust/issues/95174)
67//       would allow to use enums and arrays as const-generic parameters.
68// WAIT: [generic_const_exprs](https://github.com/rust-lang/rust/issues/76560)
69//       would allow calculating CR automatically from C and R.
70// #[cfg_attr(feature = "dep_rkyv", derive(Archive, Serialize, Deserialize))]
71// rkyv(archived = Array2dArchived, attr(doc = crate::TAG_RKYV![])))]
72// #[cfg_attr(
73//     all(feature = "dep_rkyv", feature = "nightly_doc"),
74//     rkyv(attr(doc(cfg(feature = "dep_rkiv"))))
75// )]
76pub struct Array2d<
77    T,
78    const C: usize,
79    const R: usize,
80    const CR: usize,
81    const RMAJ: bool = true,
82    S: Storage = Bare,
83> {
84    pub(super) data: Array<T, CR, S>,
85}
86
87// SEE: https://docs.rs/rkyv/latest/rkyv/trait.Archive.html
88// #[cfg(feature = "dep_rkyv")]
89// #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "dep_rkyv")))]
90// mod impl_rkyv {
91//     use rkyv::{
92//         access_unchecked,
93//         munge::munge,
94//         rancor::{Error, Fallible},
95//         ser::Writer,
96//         to_bytes, Archive, ArchiveUnsized, Archived, Place, Portable, RelPtr, Serialize,
97//         SerializeUnsized,
98//     };
99//
100//     /// XXX
101//     #[repr(transparent)]
102//     struct Array2dArchived {
103//         ptr: RelPtr<str>,
104//     }
105//     impl Array2dArchived {}
106//
107//     /// YYY
108//     struct Array2dResolver {
109//         // This will be the position that the bytes of our string are stored at.
110//         pos: usize,
111//     }
112//
113//     impl Archive for Array2d {
114//         type Archived = Array2dArchived;
115//         type Resolver = Array2dResolver;
116//
117//         // The resolve function consumes the resolver and produces the archived
118//         // value at the given position.
119//         fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
120//             munge!(let Array2dArchived { ptr } = out);
121//             RelPtr::emplace_unsized(resolver.pos, self.inner.archived_metadata(), ptr);
122//         }
123//     }
124//
125//     // We restrict our serializer types with Writer because we need its
126//     // capabilities to serialize the inner string. For other types, we might
127//     // need more or less restrictive bounds on the type of S.
128//     impl<S: Fallible + Writer + ?Sized> Serialize<S> for Array2d {
129//         fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
130//             // This is where we want to write the bytes of our string and return
131//             // a resolver that knows where those bytes were written.
132//             // We also need to serialize the metadata for our str.
133//             Ok(OwnedStrResolver { pos: self.inner.serialize_unsized(serializer)? })
134//         }
135//     }
136//
137//     #[cfg(test)]
138//     fn test_array2d_arkyv() {
139//         let value = Array2d::<_, 2, 2, 4>::with_cloned('€');
140//         let buf = to_bytes::<Error>(&value).expect("failed to serialize");
141//         #[cfg(feature = "unsafe")]
142//         let archived = unsafe { access_unchecked::<ArchivedOwnedStr>(buf.as_ref()) };
143//         // Let's make sure our data got written correctly TODO
144//         // assert_eq!(archived.as_str(), STR_VAL);
145//     }
146// }