1use std::marker::PhantomData;
2use std::ops::Mul;
3
4use num_traits::PrimInt;
5use rayon::prelude::*;
6use smol_str::SmolStr;
7
8pub type IndexTuple = Box<[IndexKey]>;
17
18#[derive(Clone, Debug)]
22enum SetRepr {
23 Range(Vec<i64>),
24 Strings(Vec<SmolStr>),
25 Tuples(Vec<IndexTuple>),
26}
27
28impl SetRepr {
29 fn len(&self) -> usize {
30 match self {
31 Self::Range(v) => v.len(),
32 Self::Strings(v) => v.len(),
33 Self::Tuples(v) => v.len(),
34 }
35 }
36}
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
43pub struct Axis {
44 pub start: i64,
45 pub len: usize,
46}
47
48pub struct Set<K = IndexKey> {
63 repr: SetRepr,
64 axes: Option<Box<[Axis]>>,
65 _k: PhantomData<fn() -> K>,
66}
67
68impl<K> Clone for Set<K> {
70 fn clone(&self) -> Self {
71 Self { repr: self.repr.clone(), axes: self.axes.clone(), _k: PhantomData }
72 }
73}
74
75impl<K> std::fmt::Debug for Set<K> {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 std::fmt::Debug::fmt(&self.repr, f)
78 }
79}
80
81impl<K> Set<K> {
82 fn from_repr(repr: SetRepr) -> Self {
83 Self { repr, axes: None, _k: PhantomData }
84 }
85
86 fn from_repr_with_axes(repr: SetRepr, axes: Box<[Axis]>) -> Self {
87 Self { repr, axes: Some(axes), _k: PhantomData }
88 }
89
90 pub(crate) fn axes(&self) -> Option<&[Axis]> {
94 self.axes.as_deref()
95 }
96
97 pub fn tuples<I, T>(iter: I) -> Self
99 where
100 I: IntoIterator<Item = T>,
101 T: Into<IndexTuple>,
102 {
103 Self::from_repr(SetRepr::Tuples(iter.into_iter().map(Into::into).collect()))
104 }
105
106 #[must_use]
109 pub fn filter<F>(&self, mut f: F) -> Self
110 where
111 F: FnMut(&IndexKey) -> bool,
112 {
113 let repr = match &self.repr {
114 SetRepr::Range(v) => {
115 SetRepr::Range(v.iter().copied().filter(|i| f(&IndexKey::Int(*i))).collect())
116 }
117 SetRepr::Strings(v) => SetRepr::Strings(
118 v.iter()
119 .filter_map(|s| {
120 let key = IndexKey::Str(s.clone());
121 if f(&key) {
122 match key {
123 IndexKey::Str(owned) => Some(owned),
124 _ => unreachable!(),
125 }
126 } else {
127 None
128 }
129 })
130 .collect(),
131 ),
132 SetRepr::Tuples(v) => SetRepr::Tuples(
133 v.iter()
134 .filter_map(|t| {
135 let key = IndexKey::Tuple(t.clone());
136 f(&key).then(|| match key {
137 IndexKey::Tuple(owned) => owned,
138 _ => unreachable!(),
139 })
140 })
141 .collect(),
142 ),
143 };
144 Self::from_repr(repr)
145 }
146
147 #[must_use]
149 pub fn into_filter<F>(self, mut f: F) -> Self
150 where
151 F: FnMut(&IndexKey) -> bool,
152 {
153 let repr = match self.repr {
154 SetRepr::Range(v) => {
155 SetRepr::Range(v.into_iter().filter(|i| f(&IndexKey::Int(*i))).collect())
156 }
157 SetRepr::Strings(v) => SetRepr::Strings(
158 v.into_iter()
159 .filter_map(|s| {
160 let key = IndexKey::Str(s);
161 let keep = f(&key);
162 match key {
163 IndexKey::Str(owned) => keep.then_some(owned),
164 _ => unreachable!(),
165 }
166 })
167 .collect(),
168 ),
169 SetRepr::Tuples(v) => SetRepr::Tuples(
170 v.into_iter()
171 .filter_map(|t| {
172 let key = IndexKey::Tuple(t);
173 let keep = f(&key);
174 match key {
175 IndexKey::Tuple(owned) => keep.then_some(owned),
176 _ => unreachable!(),
177 }
178 })
179 .collect(),
180 ),
181 };
182 Self::from_repr(repr)
183 }
184
185 #[must_use]
200 pub fn filter_typed<F>(&self, mut pred: F) -> Self
201 where
202 K: FromIndexKey,
203 F: FnMut(K) -> bool,
204 {
205 self.filter(|k| pred(K::from_index_key(k)))
206 }
207
208 #[must_use]
212 pub fn filter_ref<F>(&self, mut f: F) -> Self
213 where
214 F: FnMut(IndexKeyRef<'_>) -> bool,
215 {
216 let repr = match &self.repr {
217 SetRepr::Range(v) => {
218 SetRepr::Range(v.iter().copied().filter(|i| f(IndexKeyRef::Int(*i))).collect())
219 }
220 SetRepr::Strings(v) => {
221 SetRepr::Strings(v.iter().filter(|s| f(IndexKeyRef::Str(s))).cloned().collect())
222 }
223 SetRepr::Tuples(v) => {
224 SetRepr::Tuples(v.iter().filter(|t| f(IndexKeyRef::Tuple(t))).cloned().collect())
225 }
226 };
227 Self::from_repr(repr)
228 }
229
230 #[must_use]
232 pub fn into_filter_ref<F>(self, mut f: F) -> Self
233 where
234 F: FnMut(IndexKeyRef<'_>) -> bool,
235 {
236 let repr = match self.repr {
237 SetRepr::Range(v) => {
238 SetRepr::Range(v.into_iter().filter(|i| f(IndexKeyRef::Int(*i))).collect())
239 }
240 SetRepr::Strings(v) => {
241 SetRepr::Strings(v.into_iter().filter(|s| f(IndexKeyRef::Str(s))).collect())
242 }
243 SetRepr::Tuples(v) => SetRepr::Tuples(
244 v.into_iter().filter(|t| f(IndexKeyRef::Tuple(t.as_ref()))).collect(),
245 ),
246 };
247 Self::from_repr(repr)
248 }
249
250 #[must_use]
252 pub fn into_filter_typed<F>(self, mut pred: F) -> Self
253 where
254 K: FromIndexKey,
255 F: FnMut(K) -> bool,
256 {
257 self.into_filter(|k| pred(K::from_index_key(k)))
258 }
259
260 pub fn len(&self) -> usize {
261 self.repr.len()
262 }
263
264 pub fn is_empty(&self) -> bool {
265 self.len() == 0
266 }
267
268 pub fn is_range(&self) -> bool {
270 matches!(self.repr, SetRepr::Range(_))
271 }
272
273 pub fn is_strings(&self) -> bool {
275 matches!(self.repr, SetRepr::Strings(_))
276 }
277
278 pub fn is_tuples(&self) -> bool {
280 matches!(self.repr, SetRepr::Tuples(_))
281 }
282
283 #[must_use]
289 pub fn product<B>(a: &Set<K>, b: &Set<B>) -> Set<<K as KeyCat<B>>::Out>
290 where
291 K: KeyCat<B>,
292 {
293 let a_len = a.len();
294 let b_len = b.len();
295 let total = a_len.checked_mul(b_len).expect("Set::product size overflow");
296
297 let axes = match (a.axes(), b.axes()) {
298 (Some(aa), Some(bb)) => {
299 let mut v = Vec::with_capacity(aa.len() + bb.len());
300 v.extend_from_slice(aa);
301 v.extend_from_slice(bb);
302 Some(v.into_boxed_slice())
303 }
304 _ => None,
305 };
306
307 const PAR_THRESHOLD: usize = 4096;
310 let out: Vec<IndexTuple> = if total < PAR_THRESHOLD {
311 let mut out = Vec::with_capacity(total);
312 for ka in a {
313 for kb in b {
314 let mut parts: Vec<IndexKey> = Vec::new();
315 push_flat(&mut parts, ka.clone());
316 push_flat(&mut parts, kb);
317 out.push(parts.into_boxed_slice());
318 }
319 }
320 out
321 } else {
322 let a_keys: Vec<IndexKey> = a.iter().collect();
323 let b_keys: Vec<IndexKey> = b.iter().collect();
324 (0..total)
325 .into_par_iter()
326 .map(|i| {
327 let mut parts: Vec<IndexKey> = Vec::new();
328 push_flat(&mut parts, a_keys[i / b_len].clone());
329 push_flat(&mut parts, b_keys[i % b_len].clone());
330 parts.into_boxed_slice()
331 })
332 .collect()
333 };
334
335 match axes {
336 Some(axes) => Set::from_repr_with_axes(SetRepr::Tuples(out), axes),
337 None => Set::from_repr(SetRepr::Tuples(out)),
338 }
339 }
340}
341
342impl Set<usize> {
343 #[must_use]
353 pub fn range<T: PrimInt>(r: std::ops::Range<T>) -> Self {
354 let start = r.start.to_i64().expect("range start out of i64 range");
355 let end = r.end.to_i64().expect("range end out of i64 range");
356 Self::dense_i64(start, end)
357 }
358
359 pub(crate) fn dense_i64(start: i64, end: i64) -> Self {
363 let vals: Vec<i64> = (start..end).collect();
364 let len = vals.len();
365 Self::from_repr_with_axes(SetRepr::Range(vals), Box::from([Axis { start, len }]))
366 }
367
368 pub fn from_ints<T, I>(iter: I) -> Self
374 where
375 T: PrimInt,
376 I: IntoIterator<Item = T>,
377 {
378 Self::from_repr(SetRepr::Range(
379 iter.into_iter().map(|v| v.to_i64().expect("element out of i64 range")).collect(),
380 ))
381 }
382}
383
384impl Set<String> {
385 pub fn strings<I, S>(iter: I) -> Self
386 where
387 I: IntoIterator<Item = S>,
388 S: Into<SmolStr>,
389 {
390 Self::from_repr(SetRepr::Strings(iter.into_iter().map(Into::into).collect()))
391 }
392}
393
394fn push_flat(dst: &mut Vec<IndexKey>, k: IndexKey) {
395 match k {
396 IndexKey::Tuple(inner) => dst.extend(inner.into_vec()),
397 other => dst.push(other),
398 }
399}
400
401fn make_tuple<I: IntoIterator<Item = IndexKey>>(items: I) -> IndexTuple {
402 let mut v: Vec<IndexKey> = Vec::new();
403 for k in items {
404 push_flat(&mut v, k);
405 }
406 v.into_boxed_slice()
407}
408
409impl<A, B> Mul<&Set<B>> for &Set<A>
410where
411 A: KeyCat<B>,
412{
413 type Output = Set<<A as KeyCat<B>>::Out>;
414 fn mul(self, rhs: &Set<B>) -> Self::Output {
415 Set::product(self, rhs)
416 }
417}
418
419#[diagnostic::on_unimplemented(
423 message = "cannot form a Cartesian product index key from `{Self}` and `{Rhs}`",
424 label = "no product key for `{Self}` * `{Rhs}`",
425 note = "`&a * &b` composes scalar keys (`usize`/`i64`/`i32`/`String`) into flat tuples up to arity 4. A 5th axis or a non-scalar operand is unsupported"
426)]
427pub trait KeyCat<Rhs> {
428 type Out;
429}
430
431pub trait ScalarKey {}
434impl ScalarKey for usize {}
435impl ScalarKey for i32 {}
436impl ScalarKey for i64 {}
437impl ScalarKey for String {}
438impl ScalarKey for IndexKey {}
439
440impl<A: ScalarKey, B: ScalarKey> KeyCat<B> for A {
441 type Out = (A, B);
442}
443
444impl<A, B, C: ScalarKey> KeyCat<C> for (A, B) {
445 type Out = (A, B, C);
446}
447
448impl<A, B, C, D: ScalarKey> KeyCat<D> for (A, B, C) {
449 type Out = (A, B, C, D);
450}
451
452impl<A: ScalarKey, B, C> KeyCat<(B, C)> for A {
457 type Out = (A, B, C);
458}
459
460impl<A: ScalarKey, B, C, D> KeyCat<(B, C, D)> for A {
461 type Out = (A, B, C, D);
462}
463
464impl<A, B, C, D> KeyCat<(C, D)> for (A, B) {
465 type Out = (A, B, C, D);
466}
467
468#[derive(Clone, Debug, PartialEq, Eq, Hash)]
470pub enum IndexKey {
471 Int(i64),
472 Str(SmolStr),
473 Tuple(IndexTuple),
474}
475
476impl IndexKey {
477 pub fn tuple<I, T>(iter: I) -> Self
480 where
481 I: IntoIterator<Item = T>,
482 T: Into<IndexKey>,
483 {
484 Self::Tuple(make_tuple(iter.into_iter().map(Into::into)))
485 }
486
487 pub fn as_i64(&self) -> Option<i64> {
488 if let Self::Int(v) = self { Some(*v) } else { None }
489 }
490
491 pub fn as_str(&self) -> Option<&str> {
492 if let Self::Str(s) = self { Some(s.as_str()) } else { None }
493 }
494
495 pub fn as_tuple(&self) -> Option<&[IndexKey]> {
496 if let Self::Tuple(t) = self { Some(&t[..]) } else { None }
497 }
498}
499
500#[derive(Clone, Copy, Debug, PartialEq, Eq)]
502pub enum IndexKeyRef<'a> {
503 Int(i64),
504 Str(&'a SmolStr),
505 Tuple(&'a [IndexKey]),
506}
507
508impl<'a> IndexKeyRef<'a> {
509 pub fn as_i64(self) -> Option<i64> {
510 if let Self::Int(v) = self { Some(v) } else { None }
511 }
512 pub fn as_str(self) -> Option<&'a str> {
513 if let Self::Str(s) = self { Some(s.as_str()) } else { None }
514 }
515 pub fn as_tuple(self) -> Option<&'a [IndexKey]> {
516 if let Self::Tuple(t) = self { Some(t) } else { None }
517 }
518}
519
520pub trait FromIndexKeyRef<'a>: Sized {
523 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self;
524}
525
526impl<'a> FromIndexKeyRef<'a> for IndexKey {
527 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
528 match k {
529 IndexKeyRef::Int(v) => IndexKey::Int(v),
530 IndexKeyRef::Str(s) => IndexKey::Str(s.clone()),
531 IndexKeyRef::Tuple(t) => IndexKey::Tuple(t.to_vec().into_boxed_slice()),
532 }
533 }
534}
535
536impl<'a> FromIndexKeyRef<'a> for i64 {
537 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
538 k.as_i64().unwrap_or_else(|| panic!("expected Int key, got {k:?}"))
539 }
540}
541
542impl<'a> FromIndexKeyRef<'a> for i32 {
543 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
544 let v = i64::from_index_key_ref(k);
545 i32::try_from(v).unwrap_or_else(|_| panic!("key {v} out of i32 range"))
546 }
547}
548
549impl<'a> FromIndexKeyRef<'a> for usize {
550 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
551 let v = i64::from_index_key_ref(k);
552 usize::try_from(v).unwrap_or_else(|_| panic!("key {v} out of usize range"))
553 }
554}
555
556impl<'a> FromIndexKeyRef<'a> for String {
557 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
558 k.as_str().unwrap_or_else(|| panic!("expected Str key, got {k:?}")).to_owned()
559 }
560}
561
562impl<'a> FromIndexKeyRef<'a> for &'a str {
563 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
564 k.as_str().unwrap_or_else(|| panic!("expected Str key, got {k:?}"))
565 }
566}
567
568impl<'a> FromIndexKeyRef<'a> for &'a SmolStr {
569 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
570 match k {
571 IndexKeyRef::Str(s) => s,
572 _ => panic!("expected Str key, got {k:?}"),
573 }
574 }
575}
576
577fn tuple_parts_ref<'a>(k: IndexKeyRef<'a>, expected: usize) -> &'a [IndexKey] {
578 let p = k.as_tuple().unwrap_or_else(|| panic!("expected Tuple key, got {k:?}"));
579 assert_eq!(p.len(), expected, "expected tuple of arity {expected}, got arity {}", p.len());
580 p
581}
582
583impl<'a, A, B> FromIndexKeyRef<'a> for (A, B)
584where
585 A: FromIndexKeyRef<'a>,
586 B: FromIndexKeyRef<'a>,
587{
588 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
589 let p = tuple_parts_ref(k, 2);
590 (
591 A::from_index_key_ref(IndexKeyRef::from(&p[0])),
592 B::from_index_key_ref(IndexKeyRef::from(&p[1])),
593 )
594 }
595}
596
597impl<'a, A, B, C> FromIndexKeyRef<'a> for (A, B, C)
598where
599 A: FromIndexKeyRef<'a>,
600 B: FromIndexKeyRef<'a>,
601 C: FromIndexKeyRef<'a>,
602{
603 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
604 let p = tuple_parts_ref(k, 3);
605 (
606 A::from_index_key_ref(IndexKeyRef::from(&p[0])),
607 B::from_index_key_ref(IndexKeyRef::from(&p[1])),
608 C::from_index_key_ref(IndexKeyRef::from(&p[2])),
609 )
610 }
611}
612
613impl<'a, A, B, C, D> FromIndexKeyRef<'a> for (A, B, C, D)
614where
615 A: FromIndexKeyRef<'a>,
616 B: FromIndexKeyRef<'a>,
617 C: FromIndexKeyRef<'a>,
618 D: FromIndexKeyRef<'a>,
619{
620 fn from_index_key_ref(k: IndexKeyRef<'a>) -> Self {
621 let p = tuple_parts_ref(k, 4);
622 (
623 A::from_index_key_ref(IndexKeyRef::from(&p[0])),
624 B::from_index_key_ref(IndexKeyRef::from(&p[1])),
625 C::from_index_key_ref(IndexKeyRef::from(&p[2])),
626 D::from_index_key_ref(IndexKeyRef::from(&p[3])),
627 )
628 }
629}
630
631impl<'a> From<&'a IndexKey> for IndexKeyRef<'a> {
632 fn from(k: &'a IndexKey) -> Self {
633 match k {
634 IndexKey::Int(v) => IndexKeyRef::Int(*v),
635 IndexKey::Str(s) => IndexKeyRef::Str(s),
636 IndexKey::Tuple(t) => IndexKeyRef::Tuple(t),
637 }
638 }
639}
640
641impl From<i64> for IndexKey {
642 fn from(v: i64) -> Self {
643 Self::Int(v)
644 }
645}
646
647impl From<i32> for IndexKey {
648 fn from(v: i32) -> Self {
649 Self::Int(i64::from(v))
650 }
651}
652
653impl From<usize> for IndexKey {
654 fn from(v: usize) -> Self {
655 Self::Int(i64::try_from(v).expect("usize -> i64 overflow"))
656 }
657}
658
659impl From<&str> for IndexKey {
660 fn from(s: &str) -> Self {
661 Self::Str(SmolStr::new(s))
662 }
663}
664
665impl From<String> for IndexKey {
666 fn from(s: String) -> Self {
667 Self::Str(SmolStr::from(s))
668 }
669}
670
671impl From<&String> for IndexKey {
672 fn from(s: &String) -> Self {
673 Self::Str(SmolStr::new(s.as_str()))
674 }
675}
676
677impl From<&usize> for IndexKey {
679 fn from(v: &usize) -> Self {
680 Self::from(*v)
681 }
682}
683
684impl From<&i64> for IndexKey {
685 fn from(v: &i64) -> Self {
686 Self::Int(*v)
687 }
688}
689
690impl From<&i32> for IndexKey {
691 fn from(v: &i32) -> Self {
692 Self::Int(i64::from(*v))
693 }
694}
695
696impl From<&&str> for IndexKey {
697 fn from(s: &&str) -> Self {
698 Self::Str(SmolStr::new(*s))
699 }
700}
701
702impl From<&&String> for IndexKey {
703 fn from(s: &&String) -> Self {
704 Self::Str(SmolStr::new(s.as_str()))
705 }
706}
707
708impl<A, B> From<(A, B)> for IndexKey
709where
710 A: Into<IndexKey>,
711 B: Into<IndexKey>,
712{
713 fn from(t: (A, B)) -> Self {
714 Self::Tuple(make_tuple([t.0.into(), t.1.into()]))
715 }
716}
717
718impl<A, B, C> From<(A, B, C)> for IndexKey
719where
720 A: Into<IndexKey>,
721 B: Into<IndexKey>,
722 C: Into<IndexKey>,
723{
724 fn from(t: (A, B, C)) -> Self {
725 Self::Tuple(make_tuple([t.0.into(), t.1.into(), t.2.into()]))
726 }
727}
728
729impl<A, B, C, D> From<(A, B, C, D)> for IndexKey
730where
731 A: Into<IndexKey>,
732 B: Into<IndexKey>,
733 C: Into<IndexKey>,
734 D: Into<IndexKey>,
735{
736 fn from(t: (A, B, C, D)) -> Self {
737 Self::Tuple(make_tuple([t.0.into(), t.1.into(), t.2.into(), t.3.into()]))
738 }
739}
740
741#[diagnostic::on_unimplemented(
755 message = "`{Self}` is not a valid index key type",
756 label = "cannot be decoded from an index key",
757 note = "index keys decode to `usize`, `i64`, `i32`, `String`, `IndexKey`, or a tuple of those up to arity 4",
758 note = "annotate the binding to one of these (e.g. `for k: usize in set`) or match the `Set`'s key type"
759)]
760pub trait FromIndexKey: Sized {
761 fn from_index_key(k: &IndexKey) -> Self;
762}
763
764impl FromIndexKey for IndexKey {
765 fn from_index_key(k: &IndexKey) -> Self {
766 k.clone()
767 }
768}
769
770impl FromIndexKey for i64 {
771 fn from_index_key(k: &IndexKey) -> Self {
772 k.as_i64().unwrap_or_else(|| panic!("expected Int key, got {k:?}"))
773 }
774}
775
776impl FromIndexKey for i32 {
777 fn from_index_key(k: &IndexKey) -> Self {
778 let v = i64::from_index_key(k);
779 i32::try_from(v).unwrap_or_else(|_| panic!("key {v} out of i32 range"))
780 }
781}
782
783impl FromIndexKey for usize {
784 fn from_index_key(k: &IndexKey) -> Self {
785 let v = i64::from_index_key(k);
786 usize::try_from(v).unwrap_or_else(|_| panic!("key {v} out of usize range"))
787 }
788}
789
790impl FromIndexKey for String {
791 fn from_index_key(k: &IndexKey) -> Self {
792 k.as_str().unwrap_or_else(|| panic!("expected Str key, got {k:?}")).to_owned()
793 }
794}
795
796fn tuple_parts<'a>(k: &'a IndexKey, expected: usize) -> &'a [IndexKey] {
797 let p = k.as_tuple().unwrap_or_else(|| panic!("expected Tuple key, got {k:?}"));
798 assert_eq!(p.len(), expected, "expected tuple of arity {expected}, got arity {}", p.len());
799 p
800}
801
802impl<A, B> FromIndexKey for (A, B)
803where
804 A: FromIndexKey,
805 B: FromIndexKey,
806{
807 fn from_index_key(k: &IndexKey) -> Self {
808 let p = tuple_parts(k, 2);
809 (A::from_index_key(&p[0]), B::from_index_key(&p[1]))
810 }
811}
812
813impl<A, B, C> FromIndexKey for (A, B, C)
814where
815 A: FromIndexKey,
816 B: FromIndexKey,
817 C: FromIndexKey,
818{
819 fn from_index_key(k: &IndexKey) -> Self {
820 let p = tuple_parts(k, 3);
821 (A::from_index_key(&p[0]), B::from_index_key(&p[1]), C::from_index_key(&p[2]))
822 }
823}
824
825impl<A, B, C, D> FromIndexKey for (A, B, C, D)
826where
827 A: FromIndexKey,
828 B: FromIndexKey,
829 C: FromIndexKey,
830 D: FromIndexKey,
831{
832 fn from_index_key(k: &IndexKey) -> Self {
833 let p = tuple_parts(k, 4);
834 (
835 A::from_index_key(&p[0]),
836 B::from_index_key(&p[1]),
837 C::from_index_key(&p[2]),
838 D::from_index_key(&p[3]),
839 )
840 }
841}
842
843impl<'a, K> IntoIterator for &'a Set<K> {
844 type Item = IndexKey;
845 type IntoIter = SetIter<'a>;
846 fn into_iter(self) -> Self::IntoIter {
847 self.iter()
848 }
849}
850
851impl<K> Set<K> {
852 pub fn iter(&self) -> SetIter<'_> {
853 SetIter { repr: &self.repr, pos: 0 }
854 }
855
856 pub fn par_iter(&self) -> impl ParallelIterator<Item = IndexKey> + '_ {
857 (0..self.len()).into_par_iter().map(|i| match &self.repr {
858 SetRepr::Range(v) => IndexKey::Int(v[i]),
859 SetRepr::Strings(v) => IndexKey::Str(v[i].clone()),
860 SetRepr::Tuples(v) => IndexKey::Tuple(v[i].clone()),
861 })
862 }
863}
864
865#[derive(Debug)]
866pub struct SetIter<'a> {
867 repr: &'a SetRepr,
868 pos: usize,
869}
870
871impl<'a> Iterator for SetIter<'a> {
872 type Item = IndexKey;
873
874 fn size_hint(&self) -> (usize, Option<usize>) {
875 let remaining = self.repr.len() - self.pos;
876 (remaining, Some(remaining))
877 }
878
879 fn next(&mut self) -> Option<Self::Item> {
880 let out = match self.repr {
881 SetRepr::Range(v) => v.get(self.pos).copied().map(IndexKey::Int),
882 SetRepr::Strings(v) => v.get(self.pos).cloned().map(IndexKey::Str),
883 SetRepr::Tuples(v) => v.get(self.pos).cloned().map(IndexKey::Tuple),
884 };
885 if out.is_some() {
886 self.pos += 1;
887 }
888 out
889 }
890}