1: <?php declare(strict_types=1);
2:
3: namespace Salient\Iterator;
4:
5: use Salient\Contract\Iterator\FluentIteratorInterface;
6: use Salient\Iterator\Concern\FluentIteratorTrait;
7: use ArrayIterator;
8: use Generator;
9: use IteratorIterator;
10: use Traversable;
11:
12: /**
13: * Iterates over an array or Traversable
14: *
15: * @api
16: *
17: * @template TKey of array-key
18: * @template TValue
19: *
20: * @extends IteratorIterator<TKey,TValue,Traversable<TKey,TValue>>
21: * @implements FluentIteratorInterface<TKey,TValue>
22: */
23: class IterableIterator extends IteratorIterator implements FluentIteratorInterface
24: {
25: /** @use FluentIteratorTrait<TKey,TValue> */
26: use FluentIteratorTrait;
27:
28: /**
29: * @param iterable<TKey,TValue> $iterable
30: */
31: public function __construct(iterable $iterable)
32: {
33: if (is_array($iterable)) {
34: $iterable = new ArrayIterator($iterable);
35: }
36:
37: parent::__construct($iterable);
38: }
39:
40: /**
41: * @template T0 of array-key
42: * @template T1
43: *
44: * @param iterable<T0,T1> $iterable
45: * @return self<T0,T1>
46: */
47: public static function from(iterable $iterable): self
48: {
49: if ($iterable instanceof self) {
50: return $iterable;
51: }
52:
53: return new self($iterable);
54: }
55:
56: /**
57: * @template T
58: *
59: * @param iterable<T> $iterable
60: * @return self<int,T>
61: */
62: public static function fromValues(iterable $iterable): self
63: {
64: return new self(self::yieldValues($iterable));
65: }
66:
67: /**
68: * @template T
69: *
70: * @param iterable<T> $iterable
71: * @return Generator<int,T>
72: */
73: private static function yieldValues(iterable $iterable): Generator
74: {
75: foreach ($iterable as $value) {
76: yield $value;
77: }
78: }
79: }
80: