113 lines
3.3 KiB
PHP
113 lines
3.3 KiB
PHP
|
<?php
|
||
|
namespace nur\b\coll;
|
||
|
|
||
|
use nur\A;
|
||
|
use nur\b\IllegalAccessException;
|
||
|
|
||
|
/**
|
||
|
* Class ArrayStack: une vue vers un ensemble d'instances de {@link IArray}
|
||
|
* organisées en pile. Seule l'instance sur la pile du haut est modifiable
|
||
|
*/
|
||
|
class ArrayStack implements IArray {
|
||
|
use TArrayMdBasic, TAutomethods;
|
||
|
|
||
|
const _AUTO_GETTERS = null;
|
||
|
const _AUTO_SETTERS = null;
|
||
|
const _AUTO_DELETERS = null;
|
||
|
const _AUTO_CI_GETTERS = null;
|
||
|
const _AUTO_CI_SETTERS = null;
|
||
|
const _AUTOGEN_LITERALS = null;
|
||
|
const _AUTOGEN_METHODS = null;
|
||
|
|
||
|
/** @var array schéma des données de cette vue */
|
||
|
const SCHEMA = null;
|
||
|
|
||
|
function __construct(?IArray $array=null) {
|
||
|
if ($array !== null) $this->push($array);
|
||
|
}
|
||
|
|
||
|
/** @var IArray[] */
|
||
|
protected $stack = [];
|
||
|
|
||
|
function stackDepth(): int {
|
||
|
return count($this->stack);
|
||
|
}
|
||
|
|
||
|
function &root(): array {
|
||
|
return $this->stack;
|
||
|
}
|
||
|
|
||
|
function push(IArray $array): self {
|
||
|
array_unshift($this->stack, null);
|
||
|
$this->stack[0] = $array;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
function pop(): IArray {
|
||
|
$array = $this->stack[0];
|
||
|
array_shift($this->stack);
|
||
|
return $array;
|
||
|
}
|
||
|
|
||
|
function peek(int $index=1): IArray {
|
||
|
$count = count($this->stack);
|
||
|
if ($count > 0) {
|
||
|
while ($index < 0) $index += $count;
|
||
|
}
|
||
|
return $this->stack[$index];
|
||
|
}
|
||
|
|
||
|
function __toString(): string { return $this->stack[0]->__toString(); }
|
||
|
function &array(): ?array { return $this->stack[0]->array(); }
|
||
|
function keys(): array {
|
||
|
$keys = [];
|
||
|
foreach ($this->stack as $array) {
|
||
|
A::merge2($keys, array_fill_keys($array->keys(), true));
|
||
|
}
|
||
|
return array_keys($keys);
|
||
|
}
|
||
|
function count(): int { return count($this->keys()); }
|
||
|
function has($key): bool {
|
||
|
foreach ($this->stack as $array) {
|
||
|
if ($array->has($key)) return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
function &get($key, $default=null) {
|
||
|
foreach ($this->stack as $array) {
|
||
|
if ($array->has($key)) return $array->get($key);
|
||
|
}
|
||
|
return $default;
|
||
|
}
|
||
|
function set($key, $value): IArray { $this->stack[0]->set($key, $value); return $this; }
|
||
|
function add($value): IArray { $this->stack[0]->add($value); return $this; }
|
||
|
function del($key): IArray { $this->stack[0]->del($key); return $this; }
|
||
|
|
||
|
function addAll(?array $values): IArray { $this->stack[0]->addAll($values); return $this; }
|
||
|
function resetAll(?array $values): IArray { $this->stack[0]->resetAll($values); return $this; }
|
||
|
|
||
|
function offsetExists($key) { return $this->has($key); }
|
||
|
function &offsetGet($key) { return $this->get($key); }
|
||
|
function offsetSet($key, $value) { $this->set($key, $value); }
|
||
|
function offsetUnset($key) { $this->del($key); }
|
||
|
|
||
|
function __isset($name) { return $this->has($name); }
|
||
|
function &__get($name) { return $this->get($name); }
|
||
|
function __set($name, $value) { $this->set($name, $value); }
|
||
|
function __unset($name) { $this->del($name); }
|
||
|
|
||
|
function __call(string $name, array $args) {
|
||
|
foreach ($this->stack as $array) {
|
||
|
if ($array->_haveMethod($name)) {
|
||
|
return call_user_func_array([$array, $name], $args);
|
||
|
}
|
||
|
}
|
||
|
throw IllegalAccessException::not_implemented($name);
|
||
|
}
|
||
|
|
||
|
# Rajouter ceci dans les classes dérivées:
|
||
|
#use TArrayMd, TAutoconstsStatic; // ou TArrayMdDynamic, TAutoconstsDynamic
|
||
|
#const _AUTOGEN_CONSTS = ["" => [self::class, "_AUTOGEN_CONSTS"]];
|
||
|
##--autogen-dynamic--
|
||
|
}
|