PluginProbe ʕ •ᴥ•ʔ
FAPI Member / trunk
FAPI Member vtrunk
2.2.33 2.2.32 trunk 1.9.47 2.1.18 2.2.24 2.2.25 2.2.26 2.2.28 2.2.29 2.2.30 2.2.31
fapi-member / libs / nette / utils / src / Iterators / CachingIterator.php
fapi-member / libs / nette / utils / src / Iterators Last commit date
CachingIterator.php 2 years ago Mapper.php 2 years ago
CachingIterator.php
134 lines
1 <?php
2
3 /**
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7 declare (strict_types=1);
8 namespace FapiMember\Library\Nette\Iterators;
9
10 use FapiMember\Library\Nette;
11 /**
12 * Smarter caching iterator.
13 *
14 * @property-read bool $first
15 * @property-read bool $last
16 * @property-read bool $empty
17 * @property-read bool $odd
18 * @property-read bool $even
19 * @property-read int $counter
20 * @property-read mixed $nextKey
21 * @property-read mixed $nextValue
22 */
23 class CachingIterator extends \CachingIterator implements \Countable
24 {
25 use Nette\SmartObject;
26 /** @var int */
27 private $counter = 0;
28 public function __construct($iterator)
29 {
30 if (is_array($iterator) || $iterator instanceof \stdClass) {
31 $iterator = new \ArrayIterator($iterator);
32 } elseif ($iterator instanceof \IteratorAggregate) {
33 do {
34 $iterator = $iterator->getIterator();
35 } while ($iterator instanceof \IteratorAggregate);
36 assert($iterator instanceof \Iterator);
37 } elseif ($iterator instanceof \Iterator) {
38 } elseif ($iterator instanceof \Traversable) {
39 $iterator = new \IteratorIterator($iterator);
40 } else {
41 throw new Nette\InvalidArgumentException(sprintf('Invalid argument passed to %s; array or Traversable expected, %s given.', self::class, is_object($iterator) ? get_class($iterator) : gettype($iterator)));
42 }
43 parent::__construct($iterator, 0);
44 }
45 /**
46 * Is the current element the first one?
47 */
48 public function isFirst(?int $gridWidth = null): bool
49 {
50 return $this->counter === 1 || $gridWidth && $this->counter !== 0 && ($this->counter - 1) % $gridWidth === 0;
51 }
52 /**
53 * Is the current element the last one?
54 */
55 public function isLast(?int $gridWidth = null): bool
56 {
57 return !$this->hasNext() || $gridWidth && $this->counter % $gridWidth === 0;
58 }
59 /**
60 * Is the iterator empty?
61 */
62 public function isEmpty(): bool
63 {
64 return $this->counter === 0;
65 }
66 /**
67 * Is the counter odd?
68 */
69 public function isOdd(): bool
70 {
71 return $this->counter % 2 === 1;
72 }
73 /**
74 * Is the counter even?
75 */
76 public function isEven(): bool
77 {
78 return $this->counter % 2 === 0;
79 }
80 /**
81 * Returns the counter.
82 */
83 public function getCounter(): int
84 {
85 return $this->counter;
86 }
87 /**
88 * Returns the count of elements.
89 */
90 public function count(): int
91 {
92 $inner = $this->getInnerIterator();
93 if ($inner instanceof \Countable) {
94 return $inner->count();
95 } else {
96 throw new Nette\NotSupportedException('Iterator is not countable.');
97 }
98 }
99 /**
100 * Forwards to the next element.
101 */
102 public function next(): void
103 {
104 parent::next();
105 if (parent::valid()) {
106 $this->counter++;
107 }
108 }
109 /**
110 * Rewinds the Iterator.
111 */
112 public function rewind(): void
113 {
114 parent::rewind();
115 $this->counter = parent::valid() ? 1 : 0;
116 }
117 /**
118 * Returns the next key.
119 * @return mixed
120 */
121 public function getNextKey()
122 {
123 return $this->getInnerIterator()->key();
124 }
125 /**
126 * Returns the next element.
127 * @return mixed
128 */
129 public function getNextValue()
130 {
131 return $this->getInnerIterator()->current();
132 }
133 }
134