Passed
Push — 1.x ( b940fd...56076d )
by Ulises Jeremias
03:27 queued 58s
created

Set   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 219
rs 10
c 1
b 0
f 1
wmc 26

19 Methods

Rating   Name   Duplication   Size   Complexity  
A first() 0 3 1
A count() 0 3 1
A isEmpty() 0 3 1
A __construct() 0 6 2
A capacity() 0 3 1
A contains() 0 9 3
A add() 0 4 2
A allocate() 0 3 1
A get() 0 3 1
A copy() 0 3 1
A last() 0 3 1
A clear() 0 3 1
A offsetUnset() 0 3 1
A offsetExists() 0 3 1
A offsetGet() 0 3 1
A toArray() 0 3 1
A getIterator() 0 4 2
A remove() 0 4 2
A offsetSet() 0 8 2
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
use OutOfRangeException;
18
19
/**
20
 * A sequence of unique values.
21
 *
22
 * @package structures
23
 * @author Ulises Jeremias Cornejo Fandos <[email protected]>
24
 */
25
class Set implements ArrayAccess, CollectionInterface, IteratorAggregate
26
{
27
    use Traits\Collection;
28
29
    const MIN_CAPACITY = Map::MIN_CAPACITY;
30
31
    /**
32
     * @var Map internal map to store the values.
33
     */
34
    private $table;
35
36
    /**
37
     * Creates a new set using the values of an array or Traversable object.
38
     * The keys of either will not be preserved.
39
     *
40
     * @param array|Traversable|null $values
41
     */
42
    public function __construct($values = null)
43
    {
44
        $this->table = new Map();
45
46
        if (func_num_args()) {
47
            $this->add(...$values);
48
        }
49
    }
50
51
    /**
52
     * Adds zero or more values to the set.
53
     *
54
     * @param mixed ...$values
55
     */
56
    public function add(...$values)
57
    {
58
        foreach ($values as $value) {
59
            $this->table->put($value, null);
60
        }
61
    }
62
63
    /**
64
     * Ensures that enough memory is allocated for a specified capacity. This
65
     * potentially reduces the number of reallocations as the size increases.
66
     *
67
     * @param int $capacity The number of values for which capacity should be
68
     *                      allocated. Capacity will stay the same if this value
69
     *                      is less than or equal to the current capacity.
70
     */
71
    public function allocate(int $capacity)
72
    {
73
        $this->table->allocate($capacity);
74
    }
75
76
    /**
77
     * Returns the current capacity of the set.
78
     *
79
     * @return int
80
     */
81
    public function capacity(): int
82
    {
83
        return $this->table->capacity();
84
    }
85
86
    /**
87
     * Clear all elements in the Set
88
     */
89
    public function clear()
90
    {
91
        $this->table->clear();
92
    }
93
94
    /**
95
     * Determines whether the set contains all of zero or more values.
96
     *
97
     * @param mixed ...$values
98
     *
99
     * @return bool true if at least one value was provided and the set
100
     *              contains all given values, false otherwise.
101
     */
102
    public function contains(...$values): bool
103
    {
104
        foreach ($values as $value) {
105
            if (!$this->table->hasKey($value)) {
106
                return false;
107
            }
108
        }
109
110
        return true;
111
    }
112
113
    /**
114
     * @inheritDoc
115
     */
116
    public function copy()
117
    {
118
        return new self($this);
119
    }
120
121
    /**
122
     * Returns the number of elements in the Stack
123
     *
124
     * @return int
125
     */
126
    public function count(): int
127
    {
128
        return count($this->table);
129
    }
130
131
    /**
132
     * Returns the first value in the set.
133
     *
134
     * @return mixed the first value in the set.
135
     */
136
    public function first()
137
    {
138
        return $this->table->first()->key;
139
    }
140
141
    /**
142
     * Returns the value at a specified position in the set.
143
     *
144
     * @param int $position
145
     *
146
     * @return mixed|null
147
     *
148
     * @throws OutOfRangeException
149
     */
150
    public function get(int $position)
151
    {
152
        return $this->table->skip($position)->key;
153
    }
154
155
    /**
156
     * @inheritDoc
157
     */
158
    public function isEmpty(): bool
159
    {
160
        return $this->table->isEmpty();
161
    }
162
163
    /**
164
     * Returns the last value in the set.
165
     *
166
     * @return mixed the last value in the set.
167
     */
168
    public function last()
169
    {
170
        return $this->table->last()->key;
171
    }
172
173
    /**
174
     * Removes zero or more values from the set.
175
     *
176
     * @param mixed ...$values
177
     */
178
    public function remove(...$values)
179
    {
180
        foreach ($values as $value) {
181
            $this->table->remove($value, null);
182
        }
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    public function toArray(): array
189
    {
190
        return iterator_to_array($this);
191
    }
192
193
    /**
194
     * Get iterator
195
     */
196
    public function getIterator()
197
    {
198
        foreach ($this->table as $key => $value) {
199
            yield $key;
200
        }
201
    }
202
203
    /**
204
     * @inheritdoc
205
     *
206
     * @throws OutOfBoundsException
207
     */
208
    public function offsetSet($offset, $value)
209
    {
210
        if ($offset === null) {
211
            $this->add($value);
212
            return;
213
        }
214
215
        throw new OutOfBoundsException();
216
    }
217
218
    /**
219
     * @inheritdoc
220
     */
221
    public function offsetGet($offset)
222
    {
223
        return $this->table->skip($offset)->key;
224
    }
225
226
    /**
227
     * @inheritdoc
228
     *
229
     * @throws Error
230
     */
231
    public function offsetExists($offset)
232
    {
233
        throw new Error();
234
    }
235
236
    /**
237
     * @inheritdoc
238
     *
239
     * @throws Error
240
     */
241
    public function offsetUnset($offset)
242
    {
243
        throw new Error();
244
    }
245
}
246