1
|
|
|
<?php |
2
|
|
|
namespace Ds; |
3
|
|
|
|
4
|
|
|
use Error; |
5
|
|
|
use UnderflowException; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Stack |
9
|
|
|
* |
10
|
|
|
* @package Ds |
11
|
|
|
*/ |
12
|
|
View Code Duplication |
final class Stack implements \IteratorAggregate, \ArrayAccess, Collection |
|
|
|
|
13
|
|
|
{ |
14
|
|
|
use Traits\Collection; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var Vector |
18
|
|
|
*/ |
19
|
|
|
private $internal; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Creates an instance using the values of an array or Traversable object. |
23
|
|
|
* |
24
|
|
|
* @param array|\Traversable $values |
|
|
|
|
25
|
|
|
*/ |
26
|
95 |
|
public function __construct($values = null) |
27
|
|
|
{ |
28
|
95 |
|
$this->internal = new Vector($values ?: []); |
29
|
95 |
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Clear all elements in the Stack |
33
|
|
|
*/ |
34
|
2 |
|
public function clear() |
35
|
|
|
{ |
36
|
2 |
|
$this->internal->clear(); |
37
|
2 |
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @inheritdoc |
41
|
|
|
*/ |
42
|
5 |
|
public function copy(): Collection |
43
|
|
|
{ |
44
|
5 |
|
return new self($this->internal); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Returns the number of elements in the Stack |
49
|
|
|
* |
50
|
|
|
* @return int |
51
|
|
|
*/ |
52
|
40 |
|
public function count(): int |
53
|
|
|
{ |
54
|
40 |
|
return count($this->internal); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Ensures that enough memory is allocated for a specified capacity. This |
59
|
|
|
* potentially reduces the number of reallocations as the size increases. |
60
|
|
|
* |
61
|
|
|
* @param int $capacity The number of values for which capacity should be |
62
|
|
|
* allocated. Capacity will stay the same if this value |
63
|
|
|
* is less than or equal to the current capacity. |
64
|
|
|
*/ |
65
|
6 |
|
public function allocate(int $capacity) |
66
|
|
|
{ |
67
|
6 |
|
$this->internal->allocate($capacity); |
68
|
6 |
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Returns the current capacity of the stack. |
72
|
|
|
* |
73
|
|
|
* @return int |
74
|
|
|
*/ |
75
|
9 |
|
public function capacity(): int |
76
|
|
|
{ |
77
|
9 |
|
return $this->internal->capacity(); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Returns the value at the top of the stack without removing it. |
82
|
|
|
* |
83
|
|
|
* @return mixed |
84
|
|
|
* |
85
|
|
|
* @throws UnderflowException if the stack is empty. |
86
|
|
|
*/ |
87
|
3 |
|
public function peek() |
88
|
|
|
{ |
89
|
3 |
|
return $this->internal->last(); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Returns and removes the value at the top of the stack. |
94
|
|
|
* |
95
|
|
|
* @return mixed |
96
|
|
|
* |
97
|
|
|
* @throws UnderflowException if the stack is empty. |
98
|
|
|
*/ |
99
|
12 |
|
public function pop() |
100
|
|
|
{ |
101
|
12 |
|
return $this->internal->pop(); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Pushes zero or more values onto the top of the stack. |
106
|
|
|
* |
107
|
|
|
* @param mixed ...$values |
108
|
|
|
*/ |
|
|
|
|
109
|
17 |
|
public function push(...$values) |
110
|
|
|
{ |
111
|
17 |
|
$this->internal->push(...$values); |
112
|
17 |
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @inheritDoc |
116
|
|
|
*/ |
117
|
63 |
|
public function toArray(): array |
118
|
|
|
{ |
119
|
63 |
|
return array_reverse($this->internal->toArray()); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* |
124
|
|
|
*/ |
125
|
7 |
|
public function getIterator() |
126
|
|
|
{ |
127
|
7 |
|
while ( ! $this->isEmpty()) { |
128
|
6 |
|
yield $this->pop(); |
129
|
|
|
} |
130
|
7 |
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* @inheritdoc |
134
|
|
|
* |
135
|
|
|
* @throws Error |
136
|
|
|
*/ |
137
|
4 |
|
public function offsetSet($offset, $value) |
138
|
|
|
{ |
139
|
4 |
|
if ($offset === null) { |
140
|
4 |
|
$this->push($value); |
141
|
|
|
} else { |
142
|
|
|
throw new Error(); |
143
|
|
|
} |
144
|
4 |
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @inheritdoc |
148
|
|
|
* |
149
|
|
|
* @throws Error |
150
|
|
|
*/ |
151
|
1 |
|
public function offsetGet($offset) |
152
|
|
|
{ |
153
|
1 |
|
throw new Error(); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @inheritdoc |
158
|
|
|
* |
159
|
|
|
* @throws Error |
160
|
|
|
*/ |
161
|
1 |
|
public function offsetUnset($offset) |
162
|
|
|
{ |
163
|
1 |
|
throw new Error(); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* @inheritdoc |
168
|
|
|
* |
169
|
|
|
* @throws Error |
170
|
|
|
*/ |
171
|
2 |
|
public function offsetExists($offset) |
172
|
|
|
{ |
173
|
2 |
|
throw new Error(); |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.