33
33
#include " sus/num/overflow_integer.h"
34
34
#include " sus/ops/eq.h"
35
35
#include " sus/prelude.h"
36
+ #include " sus/test/no_copy_move.h"
36
37
37
38
using sus::containers::Array;
38
39
using sus::iter::IteratorBase;
39
40
using sus::option::Option;
41
+ using sus::result::Result;
42
+ using sus::test::NoCopyMove;
40
43
41
44
namespace sus ::test::iter {
42
45
@@ -45,6 +48,10 @@ struct CollectSum {
45
48
T sum;
46
49
};
47
50
51
+ struct CollectRefs {
52
+ sus::Vec<const NoCopyMove*> vec;
53
+ };
54
+
48
55
} // namespace sus::test::iter
49
56
50
57
template <class T >
@@ -57,6 +64,16 @@ struct sus::iter::FromIteratorImpl<sus::test::iter::CollectSum<T>> {
57
64
}
58
65
};
59
66
67
+ template <>
68
+ struct sus ::iter::FromIteratorImpl<sus::test::iter::CollectRefs> {
69
+ static sus::test::iter::CollectRefs from_iter (
70
+ sus::iter::IntoIterator<const NoCopyMove&> auto iter) noexcept {
71
+ auto v = sus::Vec<const NoCopyMove*>();
72
+ for (const NoCopyMove& t : sus::move (iter).into_iter ()) v.push (&t);
73
+ return sus::test::iter::CollectRefs (sus::move (v));
74
+ }
75
+ };
76
+
60
77
namespace {
61
78
using namespace sus ::test::iter;
62
79
@@ -460,6 +477,10 @@ TEST(Iterator, Collect) {
460
477
ArrayIterator<i32, 5 >::with_array (nums).collect <CollectSum<i32>>();
461
478
EXPECT_EQ (collected.sum , 1 + 2 + 3 + 4 + 5 );
462
479
480
+ auto from = sus::iter::from_iter<CollectSum<i32>>(
481
+ ArrayIterator<i32, 5 >::with_array (nums));
482
+ EXPECT_EQ (from.sum , 1 + 2 + 3 + 4 + 5 );
483
+
463
484
static_assert (sus::Array<i32, 5 >::with (1 , 2 , 3 , 4 , 5 )
464
485
.into_iter ()
465
486
.collect <CollectSum<i32>>()
@@ -481,6 +502,97 @@ TEST(Iterator, CollectVec) {
481
502
sus::Vec<i32>::with (1 , 2 , 3 , 4 , 5 ));
482
503
}
483
504
505
+ TEST (Iterator, TryCollect) {
506
+ // Option.
507
+ {
508
+ auto collected = sus::Array<Option<i32>, 3 >::with (
509
+ ::sus::some (1 ), ::sus::some(2 ), ::sus::some(3 ))
510
+ .into_iter()
511
+ .try_collect<Vec<i32>>();
512
+ static_assert (std::same_as<decltype (collected), Option<Vec<i32>>>);
513
+ EXPECT_EQ (collected.is_some (), true );
514
+ EXPECT_EQ (collected.as_value (), sus::Vec<i32>::with (1 , 2 , 3 ));
515
+
516
+ auto it = sus::Array<Option<i32>, 3 >::with (::sus::some (1 ), ::sus::none (),
517
+ ::sus::some (3 ))
518
+ .into_iter();
519
+ auto up_to_none = it.try_collect <Vec<i32>>();
520
+ EXPECT_EQ (up_to_none, sus::none ());
521
+ auto after_none = it.try_collect <Vec<i32>>();
522
+ EXPECT_EQ (after_none.as_value (), sus::Vec<i32>::with (3 ));
523
+
524
+ NoCopyMove n[3 ];
525
+ auto refs = sus::Array<Option<const NoCopyMove&>, 3 >::with (
526
+ ::sus::some (n[0 ]), ::sus::some(n[1 ]), ::sus::some(n[2 ]))
527
+ .into_iter()
528
+ .try_collect<CollectRefs>();
529
+ EXPECT_EQ (refs.is_some (), true );
530
+ EXPECT_EQ (refs.as_value ().vec [0u ], &n[0 ]);
531
+ EXPECT_EQ (refs.as_value ().vec [1u ], &n[1 ]);
532
+ EXPECT_EQ (refs.as_value ().vec [2u ], &n[2 ]);
533
+ }
534
+ // Result.
535
+ enum Error { ERROR };
536
+ {
537
+ auto collected = sus::Array<Result<i32, Error>, 3 >::with (
538
+ ::sus::ok (1 ), ::sus::ok(2 ), ::sus::ok(3 ))
539
+ .into_iter()
540
+ .try_collect<Vec<i32>>();
541
+ static_assert (std::same_as<decltype (collected), Result<Vec<i32>, Error>>);
542
+ EXPECT_EQ (collected.as_ok (), sus::Vec<i32>::with (1 , 2 , 3 ));
543
+
544
+ auto it = sus::Array<Result<i32, Error>, 3 >::with (
545
+ ::sus::ok (1 ), ::sus::err(ERROR), ::sus::ok(3 ))
546
+ .into_iter();
547
+ auto up_to_err = it.try_collect <Vec<i32>>();
548
+ EXPECT_EQ (up_to_err, sus::err (ERROR));
549
+ auto after_err = it.try_collect <Vec<i32>>();
550
+ EXPECT_EQ (after_err.as_ok (), sus::Vec<i32>::with (3 ));
551
+ }
552
+
553
+ auto from =
554
+ sus::iter::try_from_iter<Vec<i32>>(sus::Array<Option<i32>, 3 >::with (
555
+ ::sus::some (1 ), ::sus::some(2 ), ::sus::some(3 )));
556
+ EXPECT_EQ (from.as_value (), sus::Vec<i32>::with (1 , 2 , 3 ));
557
+
558
+ static_assert (
559
+ sus::Array<Option<i32>, 3 >::with (sus::some (1 ), sus::some (2 ), sus::some (3 ))
560
+ .into_iter ()
561
+ .try_collect <Vec<i32>>()
562
+ .unwrap ()
563
+ .into_iter ()
564
+ .sum () == 1 + 2 + 3 );
565
+ }
566
+
567
+ TEST (Iterator, TryCollect_Example) {
568
+ using sus::none;
569
+ using sus::ok;
570
+ using sus::err;
571
+ using sus::Option;
572
+ using sus::result::Result;
573
+ using sus::some;
574
+ using sus::Vec;
575
+ {
576
+ auto u = Vec<Option<i32>>::with (some (1 ), some (2 ), some (3 ));
577
+ auto v = sus::move (u).into_iter ().try_collect <Vec<i32>>();
578
+ sus::check (v == some (Vec<i32>::with (1 , 2 , 3 )));
579
+ }
580
+ {
581
+ auto u = Vec<Option<i32>>::with (some (1 ), some (2 ), none (), some (3 ));
582
+ auto v = sus::move (u).into_iter ().try_collect <Vec<i32>>();
583
+ sus::check (v == none ());
584
+ }
585
+ {
586
+ enum Error { ERROR };
587
+ auto u = Vec<Result<i32, Error>>::with (ok (1 ), ok (2 ), ok (3 ));
588
+ auto v = sus::move (u).into_iter ().try_collect <Vec<i32>>();
589
+ sus::check (v == ok (Vec<i32>::with (1 , 2 , 3 )));
590
+ auto w = Vec<Result<i32, Error>>::with (ok (1 ), ok (2 ), err (ERROR), ok (3 ));
591
+ auto x = sus::move (w).into_iter ().try_collect <Vec<i32>>();
592
+ sus::check (x == err (ERROR));
593
+ }
594
+ }
595
+
484
596
TEST (Iterator, Rev) {
485
597
i32 nums[5 ] = {1 , 2 , 3 , 4 , 5 };
486
598
0 commit comments