Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor EnumMap - fixes #91 #92

Merged
merged 6 commits into from
Oct 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 54 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,23 @@ class UserStatus extends Enum
const ACTIVE = 'a';
const DELETED = 'd';

// all scalar datatypes are supported
// all scalar data types and arrays are supported as enumerator values
const NIL = null;
const BOOLEAN = true;
const INT = 1234;
const STR = 'string';
const FLOAT = 0.123;

// Arrays are supported since PHP-5.6
const ARR = array('this', 'is', array('an', 'array'));
const ARR = ['this', 'is', ['an', 'array']];

// Enumerators will be generated from public constants only
public const PUBLIC_CONST = 'public constant'; // this will be an enumerator
protected const PROTECTED_CONST = 'protected constant'; // this will NOT be an enumerator
private const PRIVATE_CONST = 'private constant'; // this will NOT be an enumerator

// works since PHP-7.0 - see https://wiki.php.net/rfc/context_sensitive_lexer
const TRUE = true;
const FALSE = false;
const NULL = null;
const TRUE = 'true';
const FALSE = 'false';
const NULL = 'null';
const PUBLIC = 'public';
const PRIVATE = 'private';
const PROTECTED = 'protected';
Expand All @@ -85,11 +83,11 @@ $status->getName(); // returns the selected constant name
$status->getOrdinal(); // returns the ordinal number of the selected constant

// basic methods to list defined enumerators
UserStatus::getEnumerators() // returns a list of enumerator instances
UserStatus::getValues() // returns a list of enumerator values
UserStatus::getNames() // returns a list of enumerator names
UserStatus::getOrdinals() // returns a list of ordinal numbers
UserStatus::getConstants() // returns an associative array of enumerator names to enumerator values
UserStatus::getEnumerators(); // returns a list of enumerator instances
UserStatus::getValues(); // returns a list of enumerator values
UserStatus::getNames(); // returns a list of enumerator names
UserStatus::getOrdinals(); // returns a list of ordinal numbers
UserStatus::getConstants(); // returns an associative array of enumerator names to enumerator values

// same enumerators (of the same enumeration class) holds the same instance
UserStatus::get(UserStatus::ACTIVE) === UserStatus::ACTIVE()
Expand Down Expand Up @@ -135,11 +133,12 @@ Because in normal OOP the above example allows `UserStatus` and types inherited
Please think about the following example:

```php
class ExtendedUserStatus
class ExtendedUserStatus extends UserStatus
{
const EXTENDED = 'extended';
}

$user = new User();
$user->setStatus(ExtendedUserStatus::EXTENDED());
```

Expand Down Expand Up @@ -209,10 +208,10 @@ $enumSet->isEqual($other); // Check if the EnumSet is the same as other
$enumSet->isSubset($other); // Check if the EnumSet is a subset of other
$enumSet->isSuperset($other); // Check if the EnumSet is a superset of other

$enumSet->union($other[, ...]); // Produce a new set with enumerators from both this and other (this | other)
$enumSet->intersect($other[, ...]); // Produce a new set with enumerators common to both this and other (this & other)
$enumSet->diff($other[, ...]); // Produce a new set with enumerators in this but not in other (this - other)
$enumSet->symDiff($other[, ...]); // Produce a new set with enumerators in either this and other but not in both (this ^ (other | other))
$enumSet->union($other); // Produce a new set with enumerators from both this and other (this | other)
$enumSet->intersect($other); // Produce a new set with enumerators common to both this and other (this & other)
$enumSet->diff($other); // Produce a new set with enumerators in this but not in other (this - other)
$enumSet->symDiff($other); // Produce a new set with enumerators in either this and other but not in both (this ^ other)
```

## EnumMap
Expand All @@ -227,20 +226,48 @@ use MabeEnum\EnumMap;
// create a new EnumMap
$enumMap = new EnumMap('UserStatus');

// attach entries (by value or by instance)
$enumMap->attach(UserStatus::INACTIVE, 'inaktiv');
$enumMap->attach(UserStatus::ACTIVE(), 'aktiv');
$enumMap->attach(UserStatus::DELETED(), 'gelöscht');
// read and write key-value-pairs like an array
$enumMap[UserStatus::INACTIVE] = 'inaktiv';
$enumMap[UserStatus::ACTIVE] = 'aktiv';
$enumMap[UserStatus::DELETED] = 'gelöscht';
$enumMap[UserStatus::INACTIVE]; // 'inaktiv';
$enumMap[UserStatus::ACTIVE]; // 'aktiv';
$enumMap[UserStatus::DELETED]; // 'gelöscht';

isset($enumMap[UserStatus::DELETED]); // true
unset($enumMap[UserStatus::DELETED]);
isset($enumMap[UserStatus::DELETED]); // false

// ... no matter if you use enumerator values or enumerator objects
$enumMap[UserStatus::INACTIVE()] = 'inaktiv';
$enumMap[UserStatus::ACTIVE()] = 'aktiv';
$enumMap[UserStatus::DELETED()] = 'gelöscht';
$enumMap[UserStatus::INACTIVE()]; // 'inaktiv';
$enumMap[UserStatus::ACTIVE()]; // 'aktiv';
$enumMap[UserStatus::DELETED()]; // 'gelöscht';

isset($enumMap[UserStatus::DELETED()]); // true
unset($enumMap[UserStatus::DELETED()]);
isset($enumMap[UserStatus::DELETED()]); // false

// detach entries (by value or by instance)
$enumMap->detach(UserStatus::INACTIVE);
$enumMap->detach(UserStatus::DELETED());

// iterate
// support for null aware exists check
$enumMap[UserStatus::NULL] = null;
isset($enumMap[UserStatus::NULL]); // false
$enumMap->contains(UserStatus::NULL); // true


// iterating over the map
foreach ($enumMap as $enum => $value) {
var_dump(get_class($enum)); // UserStatus
var_dump(gettype($value)) // string
get_class($enum); // UserStatus (enumerator object)
gettype($value); // string (the value the enumerators maps to)
}

// get a list of keys (= a list of enumerator objects)
$enumMap->getKeys();

// get a list of values (= a list of values the enumerator maps to)
$enumMap->getValues();
```

## Serializing
Expand Down
48 changes: 39 additions & 9 deletions bench/EnumMapBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ public function init()
}
}

public function benchGetKeysEmpty()
{
$this->emptyMap->getKeys();
}

public function benchGetKeysFull()
{
$this->fullMap->getKeys();
}

public function benchGetValuesEmpty()
{
$this->emptyMap->getValues();
}

public function benchGetValuesFull()
{
$this->fullMap->getValues();
}

public function benchSearchTypeJuggling()
{
$this->fullMap->search('31');
}

public function benchSearchStrict()
{
$this->fullMap->search(31, true);
}

public function benchOffsetSetEnumerator()
{
foreach ($this->enumerators as $enumerator) {
Expand Down Expand Up @@ -81,31 +111,31 @@ public function benchOffsetUnsetValue()
}
}

public function benchOffsetExistsEnumeratorTrue()
public function benchOffsetExistsEnumerator()
{
foreach ($this->enumerators as $enumerator) {
$this->fullMap->offsetExists($enumerator);
}
}

public function benchOffsetExistsEnumeratorFalse()
public function benchOffsetExistsValue()
{
foreach ($this->enumerators as $enumerator) {
$this->fullMap->offsetExists($enumerator);
foreach ($this->values as $value) {
$this->fullMap->offsetExists($value);
}
}

public function benchOffsetExistsValueTrue()
public function benchContainsEnumerator()
{
foreach ($this->values as $value) {
$this->fullMap->offsetExists($value);
foreach ($this->enumerators as $enumerator) {
$this->fullMap->contains($enumerator);
}
}

public function benchOffsetExistsValueFalse()
public function benchContainsValue()
{
foreach ($this->values as $value) {
$this->fullMap->offsetExists($value);
$this->fullMap->contains($value);
}
}

Expand Down
3 changes: 0 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
"php": ">=5.6",
"ext-reflection": "*"
},
"suggest": {
"php": "PHP>=5.4 will be required for using trait EnumSerializableTrait"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.0",
"phpbench/phpbench": "@dev",
Expand Down
2 changes: 1 addition & 1 deletion src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ final public static function byOrdinal($ordinal)
}

if (!isset(self::$names[$class][$ordinal])) {
throw new InvalidArgumentException(sprintf(
throw new InvalidArgumentException(\sprintf(
'Invalid ordinal number, must between 0 and %s',
\count(self::$names[$class]) - 1
));
Expand Down
Loading