friendship ended with social-app. php is my new best friend
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
8declare(strict_types=1);
9
10namespace Nette\Iterators;
11
12use Nette;
13
14
15/**
16 * Smarter caching iterator.
17 *
18 * @property-read bool $first
19 * @property-read bool $last
20 * @property-read bool $empty
21 * @property-read bool $odd
22 * @property-read bool $even
23 * @property-read int $counter
24 * @property-read mixed $nextKey
25 * @property-read mixed $nextValue
26 */
27class CachingIterator extends \CachingIterator implements \Countable
28{
29 use Nette\SmartObject;
30
31 private int $counter = 0;
32
33
34 public function __construct(iterable|\stdClass $iterable)
35 {
36 $iterable = $iterable instanceof \stdClass
37 ? new \ArrayIterator($iterable)
38 : Nette\Utils\Iterables::toIterator($iterable);
39 parent::__construct($iterable, 0);
40 }
41
42
43 /**
44 * Is the current element the first one?
45 */
46 public function isFirst(?int $gridWidth = null): bool
47 {
48 return $this->counter === 1 || ($gridWidth && $this->counter !== 0 && (($this->counter - 1) % $gridWidth) === 0);
49 }
50
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
61 /**
62 * Is the iterator empty?
63 */
64 public function isEmpty(): bool
65 {
66 return $this->counter === 0;
67 }
68
69
70 /**
71 * Is the counter odd?
72 */
73 public function isOdd(): bool
74 {
75 return $this->counter % 2 === 1;
76 }
77
78
79 /**
80 * Is the counter even?
81 */
82 public function isEven(): bool
83 {
84 return $this->counter % 2 === 0;
85 }
86
87
88 /**
89 * Returns the counter.
90 */
91 public function getCounter(): int
92 {
93 return $this->counter;
94 }
95
96
97 /**
98 * Returns the count of elements.
99 */
100 public function count(): int
101 {
102 $inner = $this->getInnerIterator();
103 if ($inner instanceof \Countable) {
104 return $inner->count();
105
106 } else {
107 throw new Nette\NotSupportedException('Iterator is not countable.');
108 }
109 }
110
111
112 /**
113 * Forwards to the next element.
114 */
115 public function next(): void
116 {
117 parent::next();
118 if (parent::valid()) {
119 $this->counter++;
120 }
121 }
122
123
124 /**
125 * Rewinds the Iterator.
126 */
127 public function rewind(): void
128 {
129 parent::rewind();
130 $this->counter = parent::valid() ? 1 : 0;
131 }
132
133
134 /**
135 * Returns the next key.
136 */
137 public function getNextKey(): mixed
138 {
139 return $this->getInnerIterator()->key();
140 }
141
142
143 /**
144 * Returns the next element.
145 */
146 public function getNextValue(): mixed
147 {
148 return $this->getInnerIterator()->current();
149 }
150}