hphp/system/php/collections/collections.ns.php (1,896 lines of code) (raw):
<?hh // partial
<<file:__EnableUnstableFeatures('readonly')>>
namespace {
<<__Sealed(\HH\Collection::class, ConstMap::class, ConstSet::class, ConstVector::class)>>
interface ConstCollection extends HH\Rx\Countable {
public readonly function isEmpty()[];
public readonly function count()[];
public function items()[];
}
<<__Sealed(\HH\Collection::class)>>
interface OutputCollection {
public function add($e)[write_props];
public function addAll(
$iterable
)[write_props];
}
}
namespace HH {
<<__Sealed(\MutableMap::class, \MutableSet::class, \MutableVector::class)>>
interface Collection extends \ConstCollection,
\OutputCollection {
public function clear()[write_props];
}
}
namespace {
<<__Sealed(ConstMapAccess::class, SetAccess::class, ConstSet::class)>>
interface ConstSetAccess {
public function contains($m)[];
}
<<__Sealed(MapAccess::class, MutableSet::class)>>
interface SetAccess extends ConstSetAccess {
public function remove($m)[write_props];
}
<<__Sealed(ConstMapAccess::class, IndexAccess::class, ConstVector::class)>>
interface ConstIndexAccess {
public function at($k)[];
public function get($k)[];
public function containsKey($k)[];
}
<<__Sealed(MapAccess::class, MutableVector::class)>>
interface IndexAccess extends ConstIndexAccess {
public function set($k,$v)[write_props];
public function setAll(
$iterable
)[write_props];
public function removeKey($k)[write_props];
}
<<__Sealed(ConstMap::class, MapAccess::class)>>
interface ConstMapAccess extends ConstSetAccess,
ConstIndexAccess {
}
<<__Sealed(MutableMap::class)>>
interface MapAccess extends ConstMapAccess,
SetAccess,
IndexAccess {
}
<<__Sealed(ImmVector::class, MutableVector::class, Pair::class)>>
interface ConstVector extends ConstCollection,
ConstIndexAccess,
\HH\Rx\KeyedIterable,
\HH\KeyedContainer {
}
<<__Sealed(Vector::class)>>
interface MutableVector extends ConstVector,
\HH\Collection,
IndexAccess {
}
<<__Sealed(ImmMap::class, MutableMap::class)>>
interface ConstMap extends ConstCollection,
ConstMapAccess,
\HH\Rx\KeyedIterable,
\HH\KeyedContainer {
}
<<__Sealed(Map::class)>>
interface MutableMap extends ConstMap,
\HH\Collection,
MapAccess {
}
<<__Sealed(ImmSet::class, MutableSet::class)>>
interface ConstSet extends ConstCollection,
ConstSetAccess,
\HH\Rx\KeyedIterable,
\HH\KeyedContainer {
}
<<__Sealed(Set::class)>>
interface MutableSet extends ConstSet,
\HH\Collection,
SetAccess {
}
trait StrictIterable<+Tv> implements \HH\Iterable<Tv> {
public function toArray() {
$arr = varray[];
foreach ($this as $v) {
$arr[] = $v;
}
return $arr;
}
public function toValuesArray() {
return $this->toArray();
}
public function toVector() {
return new Vector($this);
}
public function toImmVector() {
return new ImmVector($this);
}
public function toSet() {
return new Set($this);
}
public function toImmSet() {
return new ImmSet($this);
}
public function lazy() {
return new LazyIterableView($this);
}
public function values() {
return new Vector($this);
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\Iterable<Tu> {
$res = vec[];
foreach ($this as $v) {
$res[] = $fn($v);
}
return new Vector($res);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
$res = vec[];
foreach ($this as $v) {
if ($fn($v)) $res[] = $v;
}
return new Vector($res);
}
public function zip($iterable) {
$res = Vector {};
$it = $iterable->getIterator();
foreach ($this as $v) {
if (!$it->valid()) break;
$res[] = Pair {$v, $it->current()};
$it->next();
}
return $res;
}
public function take($n) {
$res = Vector {};
if ($n <= 0) return $res;
foreach ($this as $v) {
$res[] = $v;
if (--$n === 0) break;
}
return $res;
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
$res = vec[];
foreach ($this as $v) {
if (!$fn($v)) break;
$res[] = $v;
}
return new Vector($res);
}
public function skip($n) {
$res = Vector {};
foreach ($this as $v) {
if ($n <= 0) {
$res[] = $v;
} else {
--$n;
}
}
return $res;
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
$res = vec[];
$skip = true;
foreach ($this as $v) {
if ($skip) {
if ($fn($v)) continue;
$skip = false;
}
$res[] = $v;
}
return new Vector($res);
}
public function slice($start, $len) {
$res = Vector {};
if ($len <= 0) return $res;
foreach ($this as $v) {
if ($start !== 0) {
--$start;
continue;
}
$res[] = $v;
if (--$len === 0) break;
}
return $res;
}
public function concat($iterable) {
$res = Vector {};
foreach ($this as $v) {
$res[] = $v;
}
foreach ($iterable as $v) {
$res[] = $v;
}
return $res;
}
public function firstValue() {
foreach ($this as $v) {
return $v;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this as $v) {}
return $v;
}
}
trait StrictKeyedIterable<Tk, +Tv> implements \HH\KeyedIterable<Tk, Tv> {
public function toArray() {
$arr = darray[];
foreach ($this as $k => $v) {
$arr[$k] = $v;
}
return $arr;
}
public function toValuesArray() {
$arr = varray[];
foreach ($this as $v) {
$arr[] = $v;
}
return $arr;
}
public function toKeysArray() {
$arr = varray[];
foreach ($this as $k => $_) {
$arr[] = $k;
}
return $arr;
}
public function toVector() {
return new Vector($this);
}
public function toImmVector() {
return new ImmVector($this);
}
public function toMap() {
return new Map($this);
}
public function toImmMap() {
return new ImmMap($this);
}
public function toSet() {
return new Set($this);
}
public function toImmSet() {
return new ImmSet($this);
}
public function lazy() {
return new LazyKeyedIterableView($this);
}
public function values() {
return new Vector($this);
}
public function keys() {
$res = Vector {};
foreach ($this as $k => $_) {
$res[] = $k;
}
return $res;
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tu> {
$res = dict[];
foreach ($this as $k => $v) {
$res[$k] = $fn($v);
}
return new Map($res);
}
public function mapWithKey<Tu>(
(function(Tk, Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tu> {
$res = dict[];
foreach ($this as $k => $v) {
$res[$k] = $fn($k, $v);
}
return new Map($res);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tv> {
$res = dict[];
foreach ($this as $k => $v) {
if ($fn($v)) $res[$k] = $v;
}
return new Map($res);
}
public function filterWithKey(
(function(Tk, Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tv> {
$res = dict[];
foreach ($this as $k => $v) {
if ($fn($k, $v)) $res[$k] = $v;
}
return new Map($res);
}
public function zip($iterable) {
$res = Map {};
$it = $iterable->getIterator();
foreach ($this as $k => $v) {
if (!$it->valid()) break;
$res[$k] = Pair {$v, $it->current()};
$it->next();
}
return $res;
}
public function take($n) {
$res = Map {};
if ($n <= 0) return $res;
foreach ($this as $k => $v) {
$res[$k] = $v;
if (--$n === 0) break;
}
return $res;
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
$res = dict[];
foreach ($this as $k => $v) {
if (!$fn($v)) break;
$res[$k] = $v;
}
return new Map($res);
}
public function skip($n) {
$res = Map {};
foreach ($this as $k => $v) {
if ($n <= 0) {
$res[$k] = $v;
} else {
--$n;
}
}
return $res;
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
$res = dict[];
$skip = true;
foreach ($this as $k => $v) {
if ($skip) {
if ($fn($v)) continue;
$skip = false;
}
$res[$k] = $v;
}
return new Map($res);
}
public function slice($start, $len) {
$res = Map {};
if ($len <= 0) return $res;
foreach ($this as $k => $v) {
if ($start !== 0) {
--$start;
continue;
}
$res[$k] = $v;
if (--$len === 0) break;
}
return $res;
}
public function concat($iterable) {
$res = Vector {};
foreach ($this as $v) {
$res[] = $v;
}
foreach ($iterable as $v) {
$res[] = $v;
}
return $res;
}
public function firstValue() {
foreach ($this as $v) {
return $v;
}
return null;
}
public function firstKey() {
foreach ($this as $k => $_) {
return $k;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this as $v) {}
return $v;
}
public function lastKey() {
$k = null;
foreach ($this as $k => $_) {}
return $k;
}
}
trait LazyIterable<+Tv> implements \HH\Iterable<Tv> {
public function toArray() {
$arr = varray[];
foreach ($this as $v) {
$arr[] = $v;
}
return $arr;
}
public function toValuesArray() {
return $this->toArray();
}
public function toVector() {
return new Vector($this);
}
public function toImmVector() {
return new ImmVector($this);
}
public function toSet() {
return new Set($this);
}
public function toImmSet() {
return new ImmSet($this);
}
public function lazy() {
return $this;
}
public function values() {
return new LazyValuesIterable($this);
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\Iterable<Tu> {
return new LazyMapIterable($this, $fn);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazyFilterIterable($this, $fn);
}
public function zip($iterable)[] {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyZipIterable($this, $iterable);
}
public function take($n) {
return new LazyTakeIterable($this, $n);
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazyTakeWhileIterable($this, $fn);
}
public function skip($n) {
return new LazySkipIterable($this, $n);
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazySkipWhileIterable($this, $fn);
}
public function slice($start, $len) {
return new LazySliceIterable($this, $start, $len);
}
public function concat($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyConcatIterable($this, $iterable);
}
public function firstValue() {
foreach ($this as $v) {
return $v;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this as $v) {}
return $v;
}
}
trait LazyKeyedIterable<Tk, +Tv> implements \HH\KeyedIterable<Tk, Tv> {
public function toArray() {
$arr = darray[];
foreach ($this as $k => $v) {
$arr[$k] = $v;
}
return $arr;
}
public function toValuesArray() {
$arr = varray[];
foreach ($this as $v) {
$arr[] = $v;
}
return $arr;
}
public function toKeysArray() {
$arr = varray[];
foreach ($this as $k => $_) {
$arr[] = $k;
}
return $arr;
}
public function toVector() {
return new Vector($this);
}
public function toImmVector() {
return new ImmVector($this);
}
public function toMap() {
return new Map($this);
}
public function toImmMap() {
return new ImmMap($this);
}
public function toSet() {
return new Set($this);
}
public function toImmSet() {
return new ImmSet($this);
}
public function lazy() {
return $this;
}
public function values() {
return new LazyValuesIterable($this);
}
public function keys() {
return new LazyKeysIterable($this);
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tu> {
return new LazyMapKeyedIterable($this, $fn);
}
public function mapWithKey<Tu>(
(function(Tk, Tv)[_]: Tu) $fn
)[ctx $fn]: \HH\KeyedIterable<Tk,Tu> {
return new LazyMapWithKeyIterable($this, $fn);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tv> {
return new LazyFilterKeyedIterable($this, $fn);
}
public function filterWithKey(
(function(Tk, Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk,Tv> {
return new LazyFilterWithKeyIterable($this, $fn);
}
public function zip($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyZipKeyedIterable($this, $iterable);
}
public function take($n) {
return new LazyTakeKeyedIterable($this, $n);
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazyTakeWhileKeyedIterable($this, $fn);
}
public function skip($n) {
return new LazySkipKeyedIterable($this, $n);
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazySkipWhileKeyedIterable($this, $fn);
}
public function slice($start, $len) {
return new LazySliceKeyedIterable($this, $start, $len);
}
public function concat($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyConcatIterable($this, $iterable);
}
public function firstValue() {
foreach ($this as $v) {
return $v;
}
return null;
}
public function firstKey() {
foreach ($this as $k => $_) {
return $k;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this as $v) {}
return $v;
}
public function lastKey() {
$k = null;
foreach ($this as $k => $_) {}
return $k;
}
}
class LazyMapIterator implements \HH\Iterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return ($this->fn)($this->it->current());
}
}
class LazyMapIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyMapIterator($this->iterable->getIterator(), $this->fn);
}
}
class LazyMapKeyedIterator implements \HH\KeyedIterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return ($this->fn)($this->it->current());
}
}
class LazyMapKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyMapKeyedIterator($this->iterable->getIterator(), $this->fn);
}
}
class LazyMapWithKeyIterator implements \HH\KeyedIterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return ($this->fn)($this->it->key(), $this->it->current());
}
}
class LazyMapWithKeyIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyMapWithKeyIterator($this->iterable->getIterator(),
$this->fn);
}
}
class LazyFilterIterator implements \HH\Iterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$it = $this->it;
$fn = $this->fn;
$it->rewind();
while ($it->valid() && !$fn($it->current())) {
$it->next();
}
}
public function valid() {
return $this->it->valid();
}
public function next() {
$it = $this->it;
$fn = $this->fn;
$it->next();
while ($it->valid() && !$fn($it->current())) {
$it->next();
}
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyFilterIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyFilterIterator($this->iterable->getIterator(), $this->fn);
}
}
class LazyFilterKeyedIterator implements \HH\KeyedIterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$it = $this->it;
$fn = $this->fn;
$it->rewind();
while ($it->valid() && !$fn($it->current())) {
$it->next();
}
}
public function valid() {
return $this->it->valid();
}
public function next() {
$it = $this->it;
$fn = $this->fn;
$it->next();
while ($it->valid() && !$fn($it->current())) {
$it->next();
}
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyFilterKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return
new LazyFilterKeyedIterator($this->iterable->getIterator(), $this->fn);
}
}
class LazyFilterWithKeyIterator implements \HH\KeyedIterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$it = $this->it;
$fn = $this->fn;
$it->rewind();
while ($it->valid() && !$fn($it->key(), $it->current())) {
$it->next();
}
}
public function valid() {
return $this->it->valid();
}
public function next() {
$it = $this->it;
$fn = $this->fn;
$it->next();
while ($it->valid() && !$fn($it->key(), $it->current())) {
$it->next();
}
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyFilterWithKeyIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return
new LazyFilterWithKeyIterator($this->iterable->getIterator(), $this->fn);
}
}
class LazyZipIterator implements \HH\Iterator {
private $it1;
private $it2;
public function __construct($it1, $it2)[] {
$this->it1 = $it1;
$this->it2 = $it2;
}
public function __clone() {
$this->it1 = clone $this->it1;
$this->it2 = clone $this->it2;
}
public function rewind() {
$this->it1->rewind();
$this->it2->rewind();
}
public function valid() {
return ($this->it1->valid() && $this->it2->valid());
}
public function next() {
$this->it1->next();
$this->it2->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return Pair {$this->it1->current(), $this->it2->current()};
}
}
class LazyZipIterable implements \HH\Iterable {
use LazyIterable;
private $iterable1;
private $iterable2;
public function __construct($iterable1, $iterable2)[] {
$this->iterable1 = $iterable1;
$this->iterable2 = $iterable2;
}
public function getIterator()[] {
return new LazyZipIterator($this->iterable1->getIterator(),
$this->iterable2->getIterator());
}
}
class LazyZipKeyedIterator implements \HH\KeyedIterator {
private $it1;
private $it2;
public function __construct($it1, $it2)[] {
$this->it1 = $it1;
$this->it2 = $it2;
}
public function __clone() {
$this->it1 = clone $this->it1;
$this->it2 = clone $this->it2;
}
public function rewind() {
$this->it1->rewind();
$this->it2->rewind();
}
public function valid() {
return ($this->it1->valid() && $this->it2->valid());
}
public function next() {
$this->it1->next();
$this->it2->next();
}
public function key() {
return $this->it1->key();
}
public function current() {
return Pair {$this->it1->current(), $this->it2->current()};
}
}
class LazyZipKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable1;
private $iterable2;
public function __construct($iterable1, $iterable2)[] {
$this->iterable1 = $iterable1;
$this->iterable2 = $iterable2;
}
public function getIterator()[] {
return new LazyZipKeyedIterator($this->iterable1->getIterator(),
$this->iterable2->getIterator());
}
}
class LazyTakeIterator implements \HH\Iterator {
private $it;
private $n;
private $numLeft;
public function __construct($it, $n)[] {
$this->it = $it;
$this->n = $n;
$this->numLeft = $n;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
$this->numLeft = $this->n;
}
public function valid() {
return ($this->numLeft > 0 && $this->it->valid());
}
public function next() {
$this->it->next();
--$this->numLeft;
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyTakeIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $n;
public function __construct($iterable, $n)[] {
$this->iterable = $iterable;
$this->n = $n;
}
public function getIterator()[] {
return new LazyTakeIterator($this->iterable->getIterator(),
$this->n);
}
}
class LazyTakeKeyedIterator implements \HH\KeyedIterator {
private $it;
private $n;
private $numLeft;
public function __construct($it, $n)[] {
$this->it = $it;
$this->n = $n;
$this->numLeft = $n;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
$this->numLeft = $this->n;
}
public function valid() {
return ($this->numLeft > 0 && $this->it->valid());
}
public function next() {
$this->it->next();
--$this->numLeft;
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyTakeKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $n;
public function __construct($iterable, $n)[] {
$this->iterable = $iterable;
$this->n = $n;
}
public function getIterator()[] {
return new LazyTakeKeyedIterator($this->iterable->getIterator(),
$this->n);
}
}
class LazyTakeWhileIterator implements \HH\Iterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
$it = $this->it;
return ($it->valid() && ($this->fn)($it->current()));
}
public function next() {
$this->it->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyTakeWhileIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyTakeWhileIterator($this->iterable->getIterator(),
$this->fn);
}
}
class LazyTakeWhileKeyedIterator<Tk, +Tv>
implements \HH\KeyedIterator<Tk, Tv> {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
$it = $this->it;
return ($it->valid() && ($this->fn)($it->current()));
}
public function next() {
$this->it->next();
}
public function key() {
return $this->it->key();
}
public function current() {
return $this->it->current();
}
}
class LazyTakeWhileKeyedIterable<+Tv> implements \HH\KeyedIterable<Tk, Tv> {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazyTakeWhileKeyedIterator($this->iterable->getIterator(),
$this->fn);
}
}
class LazySkipIterator implements \HH\Iterator {
private $it;
private $n;
public function __construct($it, $n)[] {
$this->it = $it;
$this->n = $n;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$n = $this->n;
$it->rewind();
while ($n > 0 && $it->valid()) {
$it->next();
--$n;
}
}
public function valid() {
$this->impureInit();
return $this->it->valid();
}
public function next() {
$this->impureInit();
$this->it->next();
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$n = $this->n;
while ($n > 0 && $it->valid()) {
$it->next();
--$n;
}
}
}
class LazySkipIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $n;
public function __construct($iterable, $n)[] {
$this->iterable = $iterable;
$this->n = $n;
}
public function getIterator()[] {
return new LazySkipIterator($this->iterable->getIterator(),
$this->n);
}
}
class LazySkipKeyedIterator implements \HH\KeyedIterator {
private $it;
private $n;
public function __construct($it, $n)[] {
$this->it = $it;
$this->n = $n;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$n = $this->n;
$it->rewind();
while ($n > 0 && $it->valid()) {
$it->next();
--$n;
}
}
public function valid() {
$this->impureInit();
return $this->it->valid();
}
public function next() {
$this->impureInit();
$this->it->next();
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$n = $this->n;
while ($n > 0 && $it->valid()) {
$it->next();
--$n;
}
}
}
class LazySkipKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $n;
public function __construct($iterable, $n)[] {
$this->iterable = $iterable;
$this->n = $n;
}
public function getIterator()[] {
return new LazySkipKeyedIterator($this->iterable->getIterator(),
$this->n);
}
}
class LazySkipWhileIterator implements \HH\Iterator {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$fn = $this->fn;
$it->rewind();
while ($it->valid() && $fn($it->current())) {
$it->next();
}
}
public function valid() {
$this->impureInit();
return $this->it->valid();
}
public function next() {
$this->impureInit();
$this->it->next();
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$fn = $this->fn;
while ($it->valid() && $fn($it->current())) {
$it->next();
}
}
}
class LazySkipWhileIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazySkipWhileIterator($this->iterable->getIterator(),
$this->fn);
}
}
class LazySkipWhileKeyedIterator<Tk, +Tv>
implements \HH\KeyedIterator<Tk, Tv> {
private $it;
private $fn;
public function __construct($it, $fn)[] {
$this->it = $it;
$this->fn = $fn;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$fn = $this->fn;
$it->rewind();
while ($it->valid() && $fn($it->current())) {
$it->next();
}
}
public function valid() {
$this->impureInit();
return $this->it->valid();
}
public function next() {
$this->impureInit();
$this->it->next();
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$fn = $this->fn;
while ($it->valid() && $fn($it->current())) {
$it->next();
}
}
}
class LazySkipWhileKeyedIterable<Tk, +Tv>
implements \HH\KeyedIterable<Tk, Tv> {
use LazyKeyedIterable;
private $iterable;
private $fn;
public function __construct($iterable, $fn)[] {
$this->iterable = $iterable;
$this->fn = $fn;
}
public function getIterator()[] {
return new LazySkipWhileKeyedIterator($this->iterable->getIterator(),
$this->fn);
}
}
class LazySliceIterator implements \HH\Iterator {
private $it;
private $start;
private $len;
private $currentLen;
public function __construct($it, $start, $len)[] {
$this->it = $it;
$this->start = $start;
$this->len = $len;
$this->currentLen = $len;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$start = $this->start;
$len = $this->len;
$it->rewind();
$this->currentLen = $len;
while ($start !== 0 && $it->valid()) {
$it->next();
--$start;
}
}
public function valid() {
$this->impureInit();
return $this->it->valid() && $this->currentLen !== 0;
}
public function next() {
$this->impureInit();
$this->it->next();
if ($this->currentLen !== 0) {
--$this->currentLen;
}
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$start = $this->start;
while ($start !== 0 && $it->valid()) {
$it->next();
--$start;
}
}
}
class LazySliceIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
private $start;
private $len;
public function __construct($iterable, $start, $len)[] {
$this->iterable = $iterable;
$this->start = $start;
$this->len = $len;
}
public function getIterator()[] {
return new LazySliceIterator($this->iterable->getIterator(),
$this->start,
$this->len);
}
}
class LazySliceKeyedIterator implements \HH\KeyedIterator {
private $it;
private $start;
private $len;
private $currentLen;
public function __construct($it, $start, $len)[] {
$this->it = $it;
$this->start = $start;
$this->len = $len;
$this->currentLen = $len;
}
public function __clone() {
$this->impureInit();
$this->it = clone $this->it;
}
public function rewind() {
$this->impureInit();
$it = $this->it;
$start = $this->start;
$len = $this->len;
$it->rewind();
$this->currentLen = $len;
while ($start !== 0 && $it->valid()) {
$it->next();
--$start;
}
}
public function valid() {
$this->impureInit();
return $this->it->valid() && $this->currentLen !== 0;
}
public function next() {
$this->impureInit();
$this->it->next();
if ($this->currentLen !== 0) {
--$this->currentLen;
}
}
public function key() {
$this->impureInit();
return $this->it->key();
}
public function current() {
$this->impureInit();
return $this->it->current();
}
<<__Memoize>>
private function impureInit(): void {
$it = $this->it;
$start = $this->start;
while ($start !== 0 && $it->valid()) {
$it->next();
--$start;
}
}
}
class LazySliceKeyedIterable implements \HH\KeyedIterable {
use LazyKeyedIterable;
private $iterable;
private $start;
private $len;
public function __construct($iterable, $start, $len)[] {
$this->iterable = $iterable;
$this->start = $start;
$this->len = $len;
}
public function getIterator()[] {
return new LazySliceKeyedIterator($this->iterable->getIterator(),
$this->start,
$this->len);
}
}
class LazyKeysIterator implements \HH\Iterator {
private $it;
public function __construct($it)[] {
$this->it = $it;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return null;
}
public function current() {
return $this->it->key();
}
}
class LazyKeysIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
public function __construct($iterable)[] {
$this->iterable = $iterable;
}
public function getIterator()[] {
return new LazyKeysIterator($this->iterable->getIterator());
}
}
class LazyValuesIterator implements \HH\Iterator {
private $it;
public function __construct($it)[] {
$this->it = $it;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return null;
}
public function current() {
return $this->it->current();
}
}
class LazyValuesIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
public function __construct($iterable)[] {
$this->iterable = $iterable;
}
public function getIterator()[] {
return new LazyValuesIterator($this->iterable->getIterator());
}
}
class LazyKVZipIterator implements \HH\Iterator {
private $it;
public function __construct($it)[] {
$this->it = $it;
}
public function __clone() {
$this->it = clone $this->it;
}
public function rewind() {
$this->it->rewind();
}
public function valid() {
return $this->it->valid();
}
public function next() {
$this->it->next();
}
public function key() {
return null;
}
public function current() {
return Pair {$this->it->key(), $this->it->current()};
}
}
class LazyKVZipIterable implements \HH\Iterable {
use LazyIterable;
private $iterable;
public function __construct($iterable)[] {
$this->iterable = $iterable;
}
public function getIterator()[] {
return new LazyKVZipIterator($this->iterable->getIterator());
}
}
class LazyConcatIterator implements \HH\Iterator {
private $it1;
private $it2;
private $currentIt;
private $state;
public function __construct($it1, $it2)[] {
$this->it1 = $it1;
$this->it2 = $it2;
}
public function __clone() {
$this->impureInit();
$this->it1 = clone $this->it1;
$this->it2 = clone $this->it2;
$this->currentIt = ($this->state === 1) ? $this->it1 : $this->it2;
}
public function rewind() {
$this->impureInit();
$this->it1->rewind();
$this->it2->rewind();
$this->currentIt = $this->it1;
$this->state = 1;
if (!$this->currentIt->valid()) {
$this->currentIt = $this->it2;
$this->state = 2;
}
}
public function valid() {
$this->impureInit();
return $this->currentIt->valid();
}
public function next() {
$this->impureInit();
$this->currentIt->next();
if ($this->state === 1 && !$this->currentIt->valid()) {
$this->currentIt = $this->it2;
$this->state = 2;
}
}
public function key() {
$this->impureInit();
return $this->currentIt->key();
}
public function current() {
$this->impureInit();
return $this->currentIt->current();
}
<<__Memoize>>
private function impureInit(): void {
$this->currentIt = $this->it1;
$this->state = 1;
if (!$this->currentIt->valid()) {
$this->currentIt = $this->it2;
$this->state = 2;
}
}
}
class LazyConcatIterable implements \HH\Iterable {
use LazyIterable;
private $iterable1;
private $iterable2;
public function __construct($iterable1, $iterable2)[] {
$this->iterable1 = $iterable1;
$this->iterable2 = $iterable2;
}
public function getIterator()[] {
return new LazyConcatIterator($this->iterable1->getIterator(),
$this->iterable2->getIterator());
}
}
class LazyIterableView<+Tv> implements \HH\Iterable<Tv> {
public $iterable;
public function __construct($iterable)[] { $this->iterable = $iterable; }
public function getIterator()[] { return $this->iterable->getIterator(); }
public function toArray() {
$arr = varray[];
foreach ($this->iterable as $v) {
$arr[] = $v;
}
return $arr;
}
public function toValuesArray() {
return $this->toArray();
}
public function toVector() {
return $this->iterable->toVector();
}
public function toImmVector() {
return $this->iterable->toImmVector();
}
public function toSet() {
return $this->iterable->toSet();
}
public function toImmSet() {
return $this->iterable->toImmSet();
}
public function lazy() {
return $this;
}
public function values() {
return new LazyValuesIterable($this->iterable);
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\Iterable<Tu> {
return new LazyMapIterable($this->iterable, $fn);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazyFilterIterable($this->iterable, $fn);
}
public function zip($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyZipIterable($this->iterable, $iterable);
}
public function take($n) {
return new LazyTakeIterable($this->iterable, $n);
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazyTakeWhileIterable($this->iterable, $fn);
}
public function skip($n) {
return new LazySkipIterable($this->iterable, $n);
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\Iterable<Tv> {
return new LazySkipWhileIterable($this->iterable, $fn);
}
public function slice($start, $len) {
return new LazySliceIterable($this->iterable, $start, $len);
}
public function concat($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyConcatIterable($this->iterable, $iterable);
}
public function firstValue() {
foreach ($this->iterable as $v) {
return $v;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this->iterable as $v) {}
return $v;
}
}
class LazyKeyedIterableView<Tk, +Tv> implements \HH\KeyedIterable<Tk, Tv> {
public $iterable;
public function __construct($iterable)[] { $this->iterable = $iterable; }
public function getIterator()[] { return $this->iterable->getIterator(); }
public function toArray() {
$arr = darray[];
foreach ($this->iterable as $k => $v) {
$arr[$k] = $v;
}
return $arr;
}
public function toValuesArray() {
$arr = varray[];
foreach ($this->iterable as $v) {
$arr[] = $v;
}
return $arr;
}
public function toKeysArray() {
$arr = varray[];
foreach ($this->iterable as $k => $_) {
$arr[] = $k;
}
return $arr;
}
public function toVector() {
return $this->iterable->toVector();
}
public function toImmVector() {
return $this->iterable->toImmVector();
}
public function toMap() {
return $this->iterable->toMap();
}
public function toImmMap() {
return $this->iterable->toImmMap();
}
public function toSet() {
return $this->iterable->toSet();
}
public function toImmSet() {
return $this->iterable->toImmSet();
}
public function lazy() {
return $this;
}
public function values() {
return new LazyValuesIterable($this->iterable);
}
public function keys() {
return new LazyKeysIterable($this->iterable);
}
public function map<Tu>(
(function(Tv)[_]: Tu) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tu> {
return new LazyMapKeyedIterable($this->iterable, $fn);
}
public function mapWithKey<Tu>(
(function(Tk, Tv)[_]: Tu) $fn
)[ctx $fn]: \HH\KeyedIterable<Tk, Tu> {
return new LazyMapWithKeyIterable($this->iterable, $fn);
}
public function filter(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazyFilterKeyedIterable($this->iterable, $fn);
}
public function filterWithKey(
(function(Tk, Tv)[_]: bool) $fn
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazyFilterWithKeyIterable($this->iterable, $fn);
}
public function zip($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyZipKeyedIterable($this->iterable, $iterable);
}
public function take($n) {
return new LazyTakeKeyedIterable($this->iterable, $n);
}
public function takeWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazyTakeWhileKeyedIterable($this->iterable, $fn);
}
public function skip($n) {
return new LazySkipKeyedIterable($this->iterable, $n);
}
public function skipWhile(
(function(Tv)[_]: bool) $fn,
)[ctx $fn]: \HH\KeyedIterable<Tk, Tv> {
return new LazySkipWhileKeyedIterable($this->iterable, $fn);
}
public function slice($start, $len) {
return new LazySliceKeyedIterable($this->iterable, $start, $len);
}
public function concat($iterable) {
if (HH\is_any_array($iterable)) {
$iterable = new ImmMap($iterable);
}
return new LazyConcatIterable($this->iterable, $iterable);
}
public function firstValue() {
foreach ($this->iterable as $v) {
return $v;
}
return null;
}
public function firstKey() {
foreach ($this->iterable as $k => $_) {
return $k;
}
return null;
}
public function lastValue() {
$v = null;
foreach ($this->iterable as $v) {}
return $v;
}
public function lastKey() {
$k = null;
foreach ($this->iterable as $k => $_) {}
return $k;
}
}
}