1use core::{marker::Destruct, ptr::Pointee};
2
3use array_trait::length::{self, Length, LengthValue};
4
5use crate::{Bulk, DoubleEndedBulk, SplitBulk};
6
7
8#[derive(Clone, Debug)]
13#[must_use = "bulks are lazy and do nothing unless consumed"]
14pub struct Rev<I>
15where
16 I: DoubleEndedBulk
17{
18 bulk: I,
19}
20
21impl<I> Rev<I>
22where
23 I: DoubleEndedBulk
24{
25 pub(crate) const fn new(bulk: I) -> Self
26 {
27 Self {
28 bulk
29 }
30 }
31
32 pub const fn into_inner(self) -> I
48 {
49 let Self { bulk } = self;
50 bulk
51 }
52}
53
54impl<I> const Default for Rev<I>
55where
56 I: ~const Bulk + DoubleEndedBulk + ~const Default
57{
58 fn default() -> Self
59 {
60 I::default().rev()
61 }
62}
63
64impl<I> IntoIterator for Rev<I>
65where
66 I: DoubleEndedBulk
67{
68 type IntoIter = core::iter::Rev<I::IntoIter>;
69 type Item = I::Item;
70
71 fn into_iter(self) -> Self::IntoIter
72 {
73 self.into_inner().into_iter().rev()
74 }
75}
76impl<I> const Bulk for Rev<I>
77where
78 I: ~const Bulk + ~const DoubleEndedBulk
79{
80 type MinLength = I::MinLength;
81 type MaxLength = I::MaxLength;
82
83 fn len(&self) -> usize
84 {
85 let Self { bulk } = self;
86 bulk.len()
87 }
88 fn is_empty(&self) -> bool
89 {
90 let Self { bulk } = self;
91 bulk.is_empty()
92 }
93 fn for_each<F>(self, f: F)
94 where
95 Self: Sized,
96 F: ~const FnMut(Self::Item) + ~const Destruct
97 {
98 let Self { bulk } = self;
99 bulk.rev_for_each(f);
100 }
101 fn try_for_each<F, R>(self, f: F) -> R
102 where
103 Self: Sized,
104 Self::Item: ~const Destruct,
105 F: ~const FnMut(Self::Item) -> R + ~const Destruct,
106 R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
107 {
108 let Self { bulk } = self;
109 bulk.try_rev_for_each(f)
110 }
111}
112impl<I> const DoubleEndedBulk for Rev<I>
113where
114 I: ~const Bulk + DoubleEndedBulk
115{
116 fn rev_for_each<F>(self, f: F)
117 where
118 Self: Sized,
119 F: ~const FnMut(Self::Item) + ~const Destruct
120 {
121 let Self { bulk } = self;
122 bulk.for_each(f);
123 }
124 fn try_rev_for_each<F, R>(self, f: F) -> R
125 where
126 Self: Sized,
127 Self::Item: ~const Destruct,
128 F: ~const FnMut(Self::Item) -> R + ~const Destruct,
129 R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
130 {
131 let Self { bulk } = self;
132 bulk.try_for_each(f)
133 }
134}
135impl<I, N, L, R> const SplitBulk<L> for Rev<I>
136where
137 I: ~const SplitBulk<R, Left: ~const Bulk + DoubleEndedBulk, Right: ~const Bulk + DoubleEndedBulk> + ~const Bulk<Length: Length<Value = N> + Pointee<Metadata = N::Metadata>> + DoubleEndedBulk,
138 N: LengthValue<SaturatingSub<L> = R>,
139 L: LengthValue,
140 R: LengthValue
141{
142 type Left = Rev<I::Right>;
143 type Right = Rev<I::Left>;
144
145 fn split_at(self, m: L) -> (Self::Left, Self::Right)
146 where
147 Self: Sized
148 {
149 let Self { bulk } = self;
150 let n = N::or_len(bulk.len());
151 let (left, right) = bulk.split_at(length::value::saturating_sub(n, m));
152 (
153 right.rev(),
154 left.rev()
155 )
156 }
157}
158
159#[cfg(test)]
160mod test
161{
162 use crate::*;
163
164 #[test]
165 fn it_works()
166 {
167 let a = [1, 2, 3, 4, 5, 6];
168 let (a, b) = a.into_bulk()
169 .rev()
170 .split_at([(); 2]);
171 let a = a.collect_array();
172 let b = b.collect_array();
173
174 println!("a = {a:?}");
175 println!("b = {b:?}");
176 }
177}