1<?php
2
3/*
4 * This file is part of the league/commonmark package.
5 *
6 * (c) Colin O'Dell <colinodell@gmail.com>
7 *
8 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
9 *  - (c) John MacFarlane
10 *
11 * For the full copyright and license information, please view the LICENSE
12 * file that was distributed with this source code.
13 */
14
15namespace League\CommonMark\Util;
16
17/**
18 * @internal
19 * @phpstan-template T
20 * @phpstan-implements \IteratorAggregate<T>
21 */
22final class PrioritizedList implements \IteratorAggregate
23{
24    /**
25     * @var array<int, array<mixed>>
26     * @phpstan-var array<int, array<T>>
27     */
28    private $list = [];
29
30    /**
31     * @var iterable<mixed>|null
32     * @phpstan-var iterable<T>|null
33     */
34    private $optimized;
35
36    /**
37     * @param mixed $item
38     * @param int   $priority
39     *
40     * @phpstan-param T $item
41     */
42    public function add($item, int $priority): void
43    {
44        $this->list[$priority][] = $item;
45        $this->optimized = null;
46    }
47
48    /**
49     * @return iterable<int, mixed>
50     *
51     * @phpstan-return iterable<int, T>
52     */
53    #[\ReturnTypeWillChange]
54    public function getIterator(): iterable
55    {
56        if ($this->optimized === null) {
57            \krsort($this->list);
58
59            $sorted = [];
60            foreach ($this->list as $group) {
61                foreach ($group as $item) {
62                    $sorted[] = $item;
63                }
64            }
65
66            $this->optimized = new \ArrayIterator($sorted);
67        }
68
69        return $this->optimized;
70    }
71}
72