<?php

namespace Doctrine\Common\Collections;

use ArrayAccess;
use Closure;
use Countable;
use IteratorAggregate;

/**
 * @template TKey of array-key
 * @template T
 * @extends IteratorAggregate<TKey, T>
 * @extends ArrayAccess<TKey, T>
 * @extends ReadableCollection<TKey, T>
 */
interface Collection extends Countable, IteratorAggregate, ArrayAccess, ReadableCollection
{

    /**
     * @phpstan-impure
     *
     * @param T $element
     *
     * @return void
     */
    public function add($element) {}

    /**
     * @phpstan-impure
     *
     * @param TKey $key
     *
     * @return T|null
     */
    public function remove($key) {}

    /**
     * @phpstan-impure
     *
     * @param T $element
     *
     * @return bool
     */
    public function removeElement($element) {}

    /**
     * @param-immediately-invoked-callable $p
     *
     * @param Closure(T, TKey):bool $p
     *
     * @return Collection<TKey, T>
     */
    public function filter(Closure $p);

    /**
     * @param-immediately-invoked-callable $func
     *
     * @param Closure(T):U $func
     *
     * @return Collection<TKey, U>
     *
     * @template U
     */
    public function map(Closure $func);

    /**
     * @param-immediately-invoked-callable $p
     *
     * @param Closure(TKey, T):bool $p
     *
     * @return array{0: Collection<TKey, T>, 1: Collection<TKey, T>}
     */
    public function partition(Closure $p);

}
