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--
 | |
| }
 |