1<?php 2 3declare(strict_types=1); 4 5/* 6 * This file is part of the league/commonmark package. 7 * 8 * (c) Colin O'Dell <colinodell@gmail.com> 9 * 10 * For the full copyright and license information, please view the LICENSE 11 * file that was distributed with this source code. 12 */ 13 14namespace League\CommonMark\Util; 15 16/** 17 * Array collection 18 * 19 * Provides a wrapper around a standard PHP array. 20 * 21 * @internal 22 * 23 * @phpstan-template T 24 * @phpstan-implements \IteratorAggregate<int, T> 25 * @phpstan-implements \ArrayAccess<int, T> 26 */ 27final class ArrayCollection implements \IteratorAggregate, \Countable, \ArrayAccess 28{ 29 /** 30 * @var array<int, mixed> 31 * @phpstan-var array<int, T> 32 */ 33 private array $elements; 34 35 /** 36 * Constructor 37 * 38 * @param array<int|string, mixed> $elements 39 * 40 * @phpstan-param array<int, T> $elements 41 */ 42 public function __construct(array $elements = []) 43 { 44 $this->elements = $elements; 45 } 46 47 /** 48 * @return mixed|false 49 * 50 * @phpstan-return T|false 51 */ 52 public function first() 53 { 54 return \reset($this->elements); 55 } 56 57 /** 58 * @return mixed|false 59 * 60 * @phpstan-return T|false 61 */ 62 public function last() 63 { 64 return \end($this->elements); 65 } 66 67 /** 68 * Retrieve an external iterator 69 * 70 * @return \ArrayIterator<int, mixed> 71 * 72 * @phpstan-return \ArrayIterator<int, T> 73 */ 74 #[\ReturnTypeWillChange] 75 public function getIterator(): \ArrayIterator 76 { 77 return new \ArrayIterator($this->elements); 78 } 79 80 /** 81 * Count elements of an object 82 * 83 * @return int The count as an integer. 84 */ 85 public function count(): int 86 { 87 return \count($this->elements); 88 } 89 90 /** 91 * Whether an offset exists 92 * 93 * {@inheritDoc} 94 * 95 * @phpstan-param int $offset 96 */ 97 public function offsetExists($offset): bool 98 { 99 return \array_key_exists($offset, $this->elements); 100 } 101 102 /** 103 * Offset to retrieve 104 * 105 * {@inheritDoc} 106 * 107 * @phpstan-param int $offset 108 * 109 * @phpstan-return T|null 110 */ 111 #[\ReturnTypeWillChange] 112 public function offsetGet($offset) 113 { 114 return $this->elements[$offset] ?? null; 115 } 116 117 /** 118 * Offset to set 119 * 120 * {@inheritDoc} 121 * 122 * @phpstan-param int|null $offset 123 * @phpstan-param T $value 124 */ 125 #[\ReturnTypeWillChange] 126 public function offsetSet($offset, $value): void 127 { 128 if ($offset === null) { 129 $this->elements[] = $value; 130 } else { 131 $this->elements[$offset] = $value; 132 } 133 } 134 135 /** 136 * Offset to unset 137 * 138 * {@inheritDoc} 139 * 140 * @phpstan-param int $offset 141 */ 142 #[\ReturnTypeWillChange] 143 public function offsetUnset($offset): void 144 { 145 if (! \array_key_exists($offset, $this->elements)) { 146 return; 147 } 148 149 unset($this->elements[$offset]); 150 } 151 152 /** 153 * Returns a subset of the array 154 * 155 * @return array<int, mixed> 156 * 157 * @phpstan-return array<int, T> 158 */ 159 public function slice(int $offset, ?int $length = null): array 160 { 161 return \array_slice($this->elements, $offset, $length, true); 162 } 163 164 /** 165 * @return array<int, mixed> 166 * 167 * @phpstan-return array<int, T> 168 */ 169 public function toArray(): array 170 { 171 return $this->elements; 172 } 173} 174