Passed
Push — 1.x ( 09aaed...cb25d4 )
by Ulises Jeremias
02:40
created

DoublyLinkedList::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php namespace Mbh\Collection;
2
3
/**
4
 * MBHFramework
5
 *
6
 * @link      https://github.com/MBHFramework/mbh-framework
7
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
8
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
9
 */
10
11
use Mbh\Collection\Interfaces\Collection as CollectionInterface;
12
use Traversable;
13
use ArrayAccess;
14
use IteratorAggregate;
15
use Error;
16
use OutOfBoundsException;
17
18
/**
19
 * A Doubly Linked List (DLL) is a list of nodes linked in both directions
20
 * to each other. Iterator's operations, access to both ends, addition or
21
 * removal of nodes have a cost of O(1) when the underlying structure is a DLL.
22
 * It hence provides a decent implementation for stacks and queues.
23
 *
24
 * @package structures
25
 * @author Ulises Jeremias Cornejo Fandos <[email protected]>
26
 */
27
28
abstract class DoublyLinkedList implements ArrayAccess, CollectionInterface, IteratorAggregate
29
{
30
    use Traits\Collection;
31
32
    const MIN_CAPACITY = 8;
33
34
    /**
35
     * @var Deque internal deque to store values.
36
     */
37
    protected $deque;
38
39
    /**
40
     * Creates an instance using the values of an array or Traversable object.
41
     *
42
     * @param array|Traversable $values
43
     */
44
    public function __construct($values = [])
45
    {
46
        $this->deque = Deque::fromArray([]);
47
48
        $this->pushAll($values);
49
    }
50
51
    /**
52
     * Ensures that enough memory is allocated for a specified capacity. This
53
     * potentially reduces the number of reallocations as the size increases.
54
     *
55
     * @param int $capacity The number of values for which capacity should be
56
     *                      allocated. Capacity will stay the same if this value
57
     *                      is less than or equal to the current capacity.
58
     */
59
    public function allocate(int $capacity)
60
    {
61
        $this->deque->allocate($capacity);
62
    }
63
64
    /**
65
     * Returns the current capacity of the queue.
66
     *
67
     * @return int
68
     */
69
    public function capacity(): int
70
    {
71
        return $this->deque->capacity();
72
    }
73
74
    /**
75
     * @inheritDoc
76
     */
77
    public function clear()
78
    {
79
        $this->deque->clear();
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85
    public function copy()
86
    {
87
        return new self($this->deque);
88
    }
89
90
    /**
91
     * @inheritDoc
92
     */
93
    public function count(): int
94
    {
95
        return count($this->deque);
96
    }
97
98
    /**
99
     * Returns the value at the front of the queue without removing it.
100
     *
101
     * @return
102
     */
103
    abstract public function peek();
104
105
    /**
106
     * Returns and removes the value at the front of the Queue.
107
     *
108
     * @return mixed
109
     */
110
    abstract public function pop();
111
112
    /**
113
     * Pushes zero or more values into the front of the queue.
114
     *
115
     * @param mixed ...$values
116
     */
117
    public function push(...$values)
118
    {
119
        $this->deque->push(...$values);
120
    }
121
122
    /**
123
     * Creates associations for all keys and corresponding values of either an
124
     * array or iterable object.
125
     *
126
     * @param Traversable|array $values
127
     */
128
    protected function pushAll($values)
129
    {
130
        foreach ($values as &$value) {
131
            $this[] = $value;
132
        }
133
    }
134
135
    /**
136
     * @inheritDoc
137
     */
138
    public function toArray(): array
139
    {
140
        return $this->deque->toArray();
141
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146
    public function unserialize($values)
147
    {
148
        $values = unserialize($values);
149
        $this->deque = Deque::fromArray($values);
150
    }
151
152
    /**
153
     *
154
     */
155
    public function getIterator()
156
    {
157
        while (!$this->isEmpty()) {
158
            yield $this->pop();
159
        }
160
    }
161
162
    /**
163
     * @inheritdoc
164
     *
165
     * @throws OutOfBoundsException
166
     */
167
    public function offsetSet($offset, $value)
168
    {
169
        if ($offset === null) {
170
            $this->push($value);
171
        } else {
172
            throw new OutOfBoundsException();
173
        }
174
    }
175
176
    /**
177
     * @inheritdoc
178
     *
179
     * @throws Error
180
     */
181
    public function offsetGet($offset)
182
    {
183
        throw new Error();
184
    }
185
186
    /**
187
     * @inheritdoc
188
     *
189
     * @throws Error
190
     */
191
    public function offsetUnset($offset)
192
    {
193
        throw new Error();
194
    }
195
196
    /**
197
     * @inheritdoc
198
     *
199
     * @throws Error
200
     */
201
    public function offsetExists($offset)
202
    {
203
        throw new Error();
204
    }
205
}
206