Skip to content

Commit 32f146b

Browse files
committed
initial EnumSet
1 parent 58d6533 commit 32f146b

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

src/MabeEnum/EnumSet.php

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
3+
namespace MabeEnum;
4+
5+
use Iterator;
6+
use Countable;
7+
use InvalidArgumentException;
8+
use RuntimeException;
9+
10+
/**
11+
* EnumSet implementation in base of SplObjectStorage
12+
*
13+
* @link http://github.com/marc-mabe/php-enum for the canonical source repository
14+
* @copyright Copyright (c) 2012 Marc Bennewitz
15+
* @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
16+
*/
17+
class EnumSet implements Iterator, Countable
18+
{
19+
private $enumClass = 'EnumInheritance';
20+
private $list = array();
21+
private $index = 0;
22+
23+
/**
24+
* Constructor
25+
* @param string $enumClass The classname of an enumeration the map is for
26+
*/
27+
public function __construct($enumClass)
28+
{
29+
if (!is_subclass_of($enumClass, __NAMESPACE__ . '\Enum')) {
30+
throw new InvalidArgumentException(sprintf(
31+
"This EnumMap can handle subclasses of '%s' only",
32+
__NAMESPACE__ . '\Enum'
33+
));
34+
}
35+
$this->enumClass = $enumClass;
36+
}
37+
38+
/**
39+
* Get the classname of enumeration this map is for
40+
* @return string
41+
*/
42+
public function getEnumClass()
43+
{
44+
return $this->enumClass;
45+
}
46+
47+
/**
48+
* Attach a new enumeration or overwrite an existing one
49+
* @param Enum|scalar $enum
50+
* @param mixed $data
51+
* @return void
52+
* @throws InvalidArgumentException On an invalid given enum
53+
*/
54+
public function attach($enum, $data = null)
55+
{
56+
$this->initEnum($enum);
57+
$ordinal = $enum->getOrdinal();
58+
if (!in_array($ordinal, $this->list, true)) {
59+
$this->list[] = $ordinal;
60+
}
61+
}
62+
63+
/**
64+
* Test if the given enumeration exists
65+
* @param Enum|scalar $enum
66+
* @return boolean
67+
*/
68+
public function contains($enum)
69+
{
70+
$this->initEnum($enum);
71+
return in_array($enum->getOrdinal(), $this->list, true);
72+
}
73+
74+
/**
75+
* Detach an enumeration
76+
* @param Enum|scalar $enum
77+
* @return void
78+
* @throws InvalidArgumentException On an invalid given enum
79+
*/
80+
public function detach($enum)
81+
{
82+
$this->initEnum($enum);
83+
$index = array_search($enum->getOrdinal(), $this->list, true);
84+
if ($index) {
85+
unset($this->list[$index]);
86+
}
87+
}
88+
89+
/* Iterator */
90+
91+
/**
92+
* Get the current Enum
93+
* @return Enum|null Returns the current Enum or NULL on an invalid iterator position
94+
*/
95+
public function current()
96+
{
97+
if (!$this->valid()) {
98+
return null;
99+
}
100+
101+
$enumClass = $this->enumClass;
102+
return $enumClass::getByOrdinal($this->list[$this->index]);
103+
}
104+
105+
/**
106+
* Get the current iterator position
107+
* @return int
108+
*/
109+
public function key()
110+
{
111+
return $this->index;
112+
}
113+
114+
public function next()
115+
{
116+
++$this->index;
117+
}
118+
119+
public function rewind()
120+
{
121+
$this->index = 0;
122+
}
123+
124+
public function valid()
125+
{
126+
return isset($this->list[$this->index]);
127+
}
128+
129+
/* Countable */
130+
131+
public function count()
132+
{
133+
return count($this->list);
134+
}
135+
136+
/**
137+
* Initialize an enumeration
138+
* @param Enum|scalar $enum
139+
* @return Enum
140+
* @throws InvalidArgumentException On an invalid given enum
141+
*/
142+
private function initEnum(&$enum)
143+
{
144+
// auto instantiate
145+
if (is_scalar($enum)) {
146+
$enumClass = $this->enumClass;
147+
$enum = $enumClass::get($enum);
148+
return;
149+
}
150+
151+
// allow only enums of the same type
152+
// (don't allow instance of)
153+
$enumClass = get_class($enum);
154+
if ($enumClass && strcasecmp($enumClass, $this->enumClass) === 0) {
155+
return;
156+
}
157+
158+
throw new InvalidArgumentException(sprintf(
159+
"The given enum of type '%s' isn't same as the required type '%s'",
160+
get_class($enum) ?: gettype($enum),
161+
$this->enumClass
162+
));
163+
}
164+
}

0 commit comments

Comments
 (0)