1use core::{borrow::Borrow, marker::Destruct};
2
3use array_trait::length::LengthValue;
4
5use crate::{Bulk, DoubleEndedBulk, OnceWith, RandomAccessBulk, RepeatN, RepeatNWith, SplitBulk, StaticBulk, util::{FlatRef, TakeOne, YieldOnce}};
6
7pub const fn once<T>(value: T) -> Once<T>
25{
26 Once(value)
27}
28
29#[must_use = "bulks are lazy and do nothing unless consumed"]
33#[derive(Clone, Debug)]
34pub struct Once<T>(T);
35
36impl<T> IntoIterator for Once<T>
37{
38 type Item = T;
39 type IntoIter = core::iter::Once<T>;
40
41 fn into_iter(self) -> Self::IntoIter
42 {
43 core::iter::once(self.0)
44 }
45}
46impl<T> const Bulk for Once<T>
47{
48 type MinLength = [(); 1];
49 type MaxLength = [(); 1];
50
51 fn len(&self) -> usize
52 {
53 1
54 }
55 fn is_empty(&self) -> bool
56 {
57 false
58 }
59
60 fn first(self) -> Option<Self::Item>
61 where
62 Self::Item: ~const Destruct,
63 Self: Sized
64 {
65 Some(self.0)
66 }
67 fn last(self) -> Option<Self::Item>
68 where
69 Self::Item: ~const Destruct,
70 Self: Sized
71 {
72 Some(self.0)
73 }
74
75 fn for_each<FF>(self, mut f: FF)
76 where
77 Self: Sized,
78 FF: ~const FnMut(Self::Item) + ~const Destruct
79 {
80 f(self.0)
81 }
82 fn try_for_each<FF, R>(self, mut f: FF) -> R
83 where
84 Self: Sized,
85 Self::Item: ~const Destruct,
86 FF: ~const FnMut(Self::Item) -> R + ~const Destruct,
87 R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
88 {
89 f(self.0)
90 }
91}
92impl<T> const DoubleEndedBulk for Once<T>
93{
94 fn rev_for_each<FF>(self, f: FF)
95 where
96 Self: Sized,
97 FF: ~const FnMut(Self::Item) + ~const Destruct
98 {
99 self.for_each(f);
100 }
101 fn try_rev_for_each<FF, R>(self, f: FF) -> R
102 where
103 Self: Sized,
104 Self::Item: ~const Destruct,
105 FF: ~const FnMut(Self::Item) -> R + ~const Destruct,
106 R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
107 {
108 self.try_for_each(f)
109 }
110}
111impl<A, L> const SplitBulk<L> for Once<A>
112where
113 L: LengthValue,
114 OnceWith<YieldOnce<A>>: ~const SplitBulk<L, Item = A, Left: ~const Bulk, Right: ~const Bulk>
115{
116 type Left = <OnceWith<YieldOnce<A>> as SplitBulk<L>>::Left;
117 type Right = <OnceWith<YieldOnce<A>> as SplitBulk<L>>::Right;
118
119 fn split_at(bulk: Self, n: L) -> (Self::Left, Self::Right)
120 where
121 Self: Sized
122 {
123 OnceWith::from(bulk).split_at(n)
124 }
125}
126impl<'a, T, R> const RandomAccessBulk<'a> for Once<T>
127where
128 Self: 'a,
129 T: FlatRef<'a, FlatRef = R>,
130 &'a T: ~const Borrow<R>,
131 R: FlatRef<'a, FlatRef = R> + ~const Destruct + Copy + 'a,
132{
133 type ItemRef = R;
134 type EachRef = Once<R>;
135
136 fn each_ref(Self(value): &'a Self) -> Self::EachRef
137 {
138 crate::once(*(&value).borrow())
139 }
140}
141
142pub const trait OnceBulk: ~const DoubleEndedBulk + StaticBulk<Array<<Self as IntoIterator>::Item> = [<Self as IntoIterator>::Item; 1]>
143{
144
145}
146impl<T> const OnceBulk for T
147where
148 T: ~const DoubleEndedBulk + StaticBulk<Array<<Self as IntoIterator>::Item> = [<Self as IntoIterator>::Item; 1]>
149{
150
151}
152impl<A> const From<Once<A>> for OnceWith<YieldOnce<A>>
153{
154 fn from(value: Once<A>) -> Self
155 {
156 crate::once_with(YieldOnce::new(value.0))
157 }
158}
159impl<A> const From<Once<A>> for RepeatN<A, [(); 1]>
160where
161 A: Clone
162{
163 fn from(value: Once<A>) -> Self
164 {
165 crate::repeat_n(value.0, [(); 1])
166 }
167}
168impl<A> const From<Once<A>> for RepeatNWith<TakeOne<YieldOnce<A>>, [(); 1]>
169{
170 fn from(value: Once<A>) -> Self
171 {
172 crate::repeat_n_with(TakeOne::new(YieldOnce::new(value.0)), [(); 1])
173 }
174}
175
176#[cfg(test)]
177mod test
178{
179 use crate::Bulk;
180
181 #[test]
182 fn it_works()
183 {
184 let a = const {
185 crate::once(1).collect::<[_; _], _>()
186 };
187 assert_eq!(a, [1])
188 }
189}