Add RouterInfo include and dependency to ClientTool
[hiphop-php.git] / hphp / runtime / ext / collections / ext_collections-vector.php
blob3bde1b75eed21bbab87e08cfd9a17683aa4ccfc7
1 <?hh
2 <<file:__EnableUnstableFeatures('readonly')>>
4 namespace {
6 /** An iterator implementation for iterating over a Vector/ImmVector.
7 */
8 <<__NativeData>>
9 final class VectorIterator<T> implements HH\KeyedIterator<int, T> {
11 /** Do nothing */
12 public function __construct()[]: void { }
14 /** Returns the current value that the iterator points to.
15 * @return mixed
17 <<__Native>>
18 public function current()[]: T;
20 /** Returns the current key that the iterator points to.
21 * @return mixed
23 <<__Native>>
24 public function key()[]: int;
26 /** Returns true if the iterator points to a valid value, returns false
27 * otherwise.
28 * @return bool
30 <<__Native>>
31 public function valid()[]: bool;
33 /** Advance this iterator forward one position.
35 <<__Native>>
36 public function next()[write_props]: void;
38 /** Move this iterator back to the first position.
40 <<__Native>>
41 public function rewind()[write_props]: void;
44 } // empty namespace
45 namespace HH {
47 /** An ordered collection where values are keyed using integers 0 thru n-1 in
48 * order.
50 final class Vector<T> implements \MutableVector<T> {
52 /** Returns a Vector built from the values produced by the specified Iterable.
53 * @param mixed $iterable
55 <<__Native>>
56 public function __construct(mixed $iterable = null)[]: void;
58 /** Returns true if the Vector is empty, false otherwise.
59 * @return bool
61 public readonly function isEmpty()[]: bool {
62 return !$this->count();
65 /** Returns the number of values in the Vector.
66 * @return int
68 public readonly function count()[]: int {
69 return \count(vec($this));
72 /** Returns an Iterable that produces the values from this Vector.
73 * @return object
75 /* HH_FIXME[2049] */
76 public function items()[]: \LazyIterableView {
77 /* HH_FIXME[2049] */
78 return new \LazyIterableView($this);
81 /** Returns a Vector built from the keys of this Vector.
82 * @return object
84 public readonly function keys()[]: Vector<int> {
85 return new self($this->toKeysArray());
88 /** Returns a copy of this Vector.
89 * @return object
91 public function values()[]: this {
92 return new self($this);
95 /** Returns a lazy iterable view of this Vector.
96 * @return object
98 /* HH_FIXME[2049] */
99 public function lazy()[]: \LazyKeyedIterableView {
100 /* HH_FIXME[2049] */
101 return new \LazyKeyedIterableView($this);
104 /** Returns the value at the specified key. If the key is not present, an
105 * exception is thrown.
106 * @param mixed $key
107 * @return mixed
109 public function at(mixed $key)[]: T {
110 return $this[HH\FIXME\UNSAFE_CAST<mixed, int>($key)];
113 /** Returns the value at the specified key. If the key is not present, null is
114 * returned.
115 * @param mixed $key
116 * @return mixed
118 public function get(mixed $key)[]: ?T {
119 // TODO(T125421081) `idx` is special cased in the typechecker, I don't think
120 // it quite understands how to deal with the input being `$this`, for some
121 // reason.
122 /* HH_FIXME[4110] */
123 return idx($this, $key);
126 /** Stores a value into the Vector with the specified key, overwriting any
127 * previous value that was associated with the key; if the key is outside the
128 * bounds of the Vector, an exception is thrown.
129 * @param mixed $key
130 * @param mixed $value
131 * @return object
133 public function set(mixed $key, T $value)[write_props]: this {
134 $result = $this;
135 $result[HH\FIXME\UNSAFE_CAST<mixed, int>($key)] = $value;
136 return $result;
139 /** Stores each value produced by the specified KeyedIterable into the Vector
140 * using its corresponding key, overwriting any previous value that was
141 * associated with that key; if the key is outside the bounds of the Vector,
142 * an exception is thrown.
143 * @param mixed $iterable
144 * @return object
146 public function setAll(mixed $iterable)[write_props]: this {
147 if ($iterable === null) {
148 return $this;
150 foreach (
151 HH\FIXME\UNSAFE_CAST<nonnull, KeyedTraversable<int, T>>($iterable)
152 as $key => $value
154 $this->set($key, $value);
156 return $this;
159 <<__Native>>
160 private function clearNative()[write_props]: void;
162 /** Removes all values from the Vector.
163 * @return this
165 public function clear()[write_props]: this {
166 $this->clearNative();
167 return $this;
170 /** Returns true if the specified key is present in the Vector, returns false
171 * otherwise.
172 * @param mixed $key
173 * @return bool
175 <<__Deprecated(
176 "Use Vector::containsKey() for key search or Vector::linearSearch() for value search"
178 public readonly function contains(mixed $key): bool {
179 if (!($key is int)) {
180 throw new \InvalidArgumentException(
181 "Only integer keys may be used with Vectors"
184 return ($key >= 0) && ($key < $this->count());
187 /** Returns true if the specified key is present in the Vector, returns false
188 * otherwise.
189 * @param mixed $key
190 * @return bool
192 public readonly function containsKey(mixed $key)[]: bool {
193 if (!($key is int)) {
194 throw new \InvalidArgumentException(
195 "Only integer keys may be used with Vectors"
198 return ($key >= 0) && ($key < $this->count());
201 <<__Native>>
202 private function removeKeyNative(mixed $key)[write_props]: void;
204 /** Removes the element with the specified key from this Vector and renumbers
205 * the keys of all subsequent elements.
206 * @param mixed $key
207 * @return object
209 public function removeKey(mixed $key)[write_props]: this {
210 $this->removeKeyNative($key);
211 return $this;
214 /** @param mixed $value
215 * @return object
217 public function append(T $value)[write_props]: this {
218 $result = $this;
219 $result[] = $value;
220 return $result;
223 /** Adds the specified value to the end of this Vector using the next available
224 * integer key.
225 * @param mixed $value
226 * @return object
228 public function add(T $value)[write_props]: this {
229 return $this->append($value);
232 /** Adds the values produced by the specified Iterable to the end of this
233 * Vector using the next available integer keys.
234 * @param mixed $iterable
235 * @return object
237 public function addAll(mixed $iterable)[write_props]: this {
238 if ($iterable === null) {
239 return $this;
241 foreach (
242 HH\FIXME\UNSAFE_CAST<nonnull, KeyedTraversable<mixed, T>>($iterable)
243 as $value
245 $this->append($value);
247 return $this;
250 /** Adds the keys of the specified KeyedContainer to the end of this Vector
251 * using the next available integer keys.
252 * @param mixed $container
253 * @return object
255 public function addAllKeysOf(
256 mixed $container,
257 )[write_props]: this {
258 if ($container === null) {
259 return $this;
261 foreach (
262 HH\FIXME\UNSAFE_CAST<nonnull, KeyedTraversable<T, mixed>>($container)
263 as $key => $_
265 $this->append($key);
267 return $this;
270 /** @return mixed
272 <<__Native>>
273 public function pop()[write_props]: mixed;
275 /** @param mixed $size
276 * @param mixed $value
278 <<__Native>>
279 public function resize(mixed $size, mixed $value)[write_props]: void;
281 /** Instructs this Vector to grow its capacity to accommodate the given number
282 * of elements. The caller is expected to make the appropriate add/addAll
283 * calls to fill that reserved capacity.
284 * @param mixed $sz
286 <<__Native>>
287 public function reserve(mixed $sz)[]: void;
289 /** Returns a varray built from the values from this Vector.
290 * @return varray
292 public function toVArray()[]: varray<T> {
293 return varray($this);
296 public function toDArray()[]: darray<int, T> {
297 return darray($this);
300 /** Returns a copy of this Vector.
301 * @return object
303 public function toVector()[]: Vector<T> {
304 return new self($this);
307 /** Returns a ImmVector built from the values of this Vector.
308 * @return object
310 public function toImmVector()[]: ImmVector<T> {
311 return new ImmVector($this);
314 /** Returns an immutable version of this collection.
315 * @return object
317 public function immutable()[]: ImmVector<T> {
318 return $this->toImmVector();
321 /** Returns a Map built from the keys and values of this Vector.
322 * @return object
324 /* HH_FIXME[2049] */
325 public function toMap()[]: Map<int, T> {
326 /* HH_FIXME[2049] */
327 return new Map($this);
330 /** Returns a ImmMap built from the keys and values of this Vector.
331 * @return object
333 /* HH_FIXME[2049] */
334 public function toImmMap()[]: ImmMap<int, T> {
335 /* HH_FIXME[2049] */
336 return new ImmMap($this);
339 /** Returns a Set built from the values of this Vector.
340 * @return object
342 /* HH_FIXME[2049] */
343 public function toSet()[]: Set<T> where T as arraykey {
344 /* HH_FIXME[2049] */
345 return new Set($this);
348 /** Returns a ImmSet built from the values of this Vector.
349 * @return object
351 /* HH_FIXME[2049] */
352 public function toImmSet()[]: ImmSet<T> where T as arraykey {
353 /* HH_FIXME[2049] */
354 return new ImmSet($this);
357 /** Returns a varray built from the keys from this Vector.
358 * @return varray
360 public readonly function toKeysArray()[]: varray<int> {
361 $count = $this->count();
362 return $count
363 ? varray(HH\FIXME\UNSAFE_CAST<mixed, varray<int>>(\range(0, $count - 1)))
364 : vec[];
367 /** Returns a varray built from the values from this Vector.
368 * @return varray
370 public function toValuesArray()[]: varray<T> {
371 return $this->toVArray();
374 /** Returns an iterator that points to beginning of this Vector.
375 * @return object
377 <<__Native>>
378 public function getIterator()[]: Iterator<T>;
380 /** Returns a Vector of the values produced by applying the specified callback
381 * on each value from this Vector.
382 * @param mixed $callback
383 * @return object
385 public function map<To>(
386 (function(T)[_]: To) $callback,
387 )[ctx $callback]: Vector<To> {
388 $ret = vec[];
389 foreach ($this as $v) {
390 $ret[] = $callback($v);
392 return new Vector($ret);
395 /** Returns a Vector of the values produced by applying the specified callback
396 * on each key and value from this Vector.
397 * @param mixed $callback
398 * @return object
400 public function mapWithKey<To>(
401 (function(int, T)[_]: To) $callback,
402 )[ctx $callback]: Vector<To> {
403 $ret = vec[];
404 foreach ($this as $k => $v) {
405 $ret[] = $callback($k, $v);
407 return new Vector($ret);
410 /** Returns a Vector of all the values from this Vector for which the specified
411 * callback returns true.
412 * @param mixed $callback
413 * @return object
415 public function filter(
416 (function(T)[_]: bool) $callback,
417 )[ctx $callback]: this {
418 $ret = vec[];
419 foreach ($this as $v) {
420 if ($callback($v)) {
421 $ret[] = $v;
424 return new Vector($ret);
427 /** Returns a Vector of all the values from this Vector for which the specified
428 * callback returns true.
429 * @param mixed $callback
430 * @return object
432 public function filterWithKey(
433 (function(int, T)[_]: bool) $callback,
434 )[ctx $callback]: this {
435 $ret = vec[];
436 foreach ($this as $k => $v) {
437 if ($callback($k, $v)) {
438 $ret[] = $v;
441 return new Vector($ret);
444 /** Returns a KeyedIterable produced by combined the specified Iterables
445 * pair-wise.
446 * @param mixed $iterable
447 * @return object
449 public function zip<To>(
450 mixed $iterable,
451 )[]: Vector<Pair<T, To>> {
452 $i = 0;
453 $result = vec[];
454 $count = $this->count();
455 foreach (
456 HH\FIXME\UNSAFE_CAST<mixed, Traversable<To>>($iterable) as $value
458 if ($i === $count) {
459 break;
461 $result[] = Pair { $this[$i], $value };
462 $i++;
464 return new self($result);
467 /** Returns a Vector containing the first n values of this Vector.
468 * @param mixed $n
469 * @return object
471 public function take(mixed $n)[]: this {
472 if (!($n is int)) {
473 throw new \InvalidArgumentException("Parameter n must be an integer");
475 $count = $this->count();
476 $n = $n < 0 ? 0 : ($n > $count ? $count : $n);
477 $result = vec[];
478 for ($i = 0; $i < $n; $i++) {
479 $result[] = $this[$i];
481 return new self($result);
484 /** Returns a Vector containing the values of this Vector up to but not
485 * including the first value that produces false when passed to the specified
486 * callback.
487 * @param mixed $callback
488 * @return object
490 public function takeWhile(
491 (function(T)[_]: bool) $callback,
492 )[ctx $callback]: this {
493 $ret = vec[];
494 foreach ($this as $v) {
495 if (!$callback($v)) {
496 break;
498 $ret[] = $v;
500 return new Vector($ret);
503 /** Returns a Vector containing all the values except the first n of this
504 * Vector.
505 * @param mixed $n
506 * @return object
508 public function skip(mixed $n)[]: this {
509 if (!($n is int)) {
510 throw new \InvalidArgumentException("Parameter n must be an integer");
512 $count = $this->count();
513 $n = $n < 0 ? 0 : ($n > $count ? $count : $n);
514 $result = vec[];
515 for ($i = $n; $i < $count; $i++) {
516 $result[] = $this[$i];
518 return new self($result);
521 /** Returns a Vector containing the values of this Vector excluding the first
522 * values that produces true when passed to the specified callback.
523 * @param mixed $fn
524 * @return object
526 public function skipWhile((function(T)[_]: bool) $fn)[ctx $fn]: this {
527 $ret = vec[];
528 $skipping = true;
529 foreach ($this as $v) {
530 if ($skipping) {
531 if ($fn($v)) {
532 continue;
534 $skipping = false;
536 $ret[] = $v;
538 return new Vector($ret);
541 /** Returns a Vector containing the specified range of values from this Vector.
542 * The range is specified by two non-negative integers: a starting position
543 * and a length.
544 * @param mixed $start
545 * @param mixed $len
546 * @return object
548 public function slice(mixed $start, mixed $len)[]: this {
549 if (!($start is int) || $start < 0) {
550 throw new \InvalidArgumentException(
551 "Parameter start must be a non-negative integer");
553 if (!($len is int) || $len < 0) {
554 throw new \InvalidArgumentException(
555 "Parameter len must be a non-negative integer");
557 $count = $this->count();
558 $skip = $start < $count ? $start : $count;
559 $size = $len < $count - $skip ? $len : $count - $skip;
560 $result = vec[];
561 for ($i = $skip; $i < $skip + $size; $i++) {
562 $result[] = $this[$i];
564 return new self($result);
567 /** Builds a new Vector by concatenating the elements of this Vector with the
568 * elements of the specified Iterable.
569 * @param mixed $iterable
570 * @return object
572 public function concat<To super T>(
573 mixed $iterable,
574 )[]: Vector<To> {
575 $result = vec($this);
576 foreach (
577 HH\FIXME\UNSAFE_CAST<mixed, Traversable<To>>($iterable) as $value
579 $result[] = $value;
581 return new self($result);
584 /** Returns the first value from this Vector, or null if this Vector is empty.
585 * @return mixed
587 public function firstValue()[]: mixed {
588 /* HH_FIXME[4110] */
589 return idx($this, 0);
592 /** Returns the first key from this Vector, or null if this Vector is empty.
593 * @return mixed
595 public readonly function firstKey()[]: mixed {
596 return $this->count() ? 0 : null;
599 /** Returns the last value from this Vector, or null if this Vector is empty.
600 * @return mixed
602 public function lastValue()[]: mixed {
603 $count = $this->count();
604 return $count ? $this[$count - 1] : null;
607 /** Returns the last key from this Vector, or null if this Vector is empty.
608 * @return mixed
610 public readonly function lastKey()[]: mixed {
611 $count = $this->count();
612 return $count ? ($count - 1) : null;
615 /** Reverses the values of the Vector in place.
617 <<__Native>>
618 public function reverse()[write_props]: void;
620 /** Splices the values of the Vector in place (see the documentation for
621 * array_splice() on php.net for more details.
622 * @param mixed $offset
623 * @param mixed $len
624 * @param mixed $replacement
626 <<__Native>>
627 public function splice(mixed $offset,
628 mixed $len = null,
629 mixed $replacement = null)[write_props]: void;
631 /** Returns index of the specified value if it is present, -1 otherwise.
632 * @param mixed $search_value
633 * @return int
635 public readonly function linearSearch(mixed $search_value)[]: int {
636 foreach (vec($this) as $i => $value) {
637 if ($value === $search_value) {
638 return $i;
641 return -1;
644 /** Shuffles the values of the Vector randomly in place.
646 <<__Native>>
647 public function shuffle()[leak_safe]: void;
649 /** @return string
651 public function __toString()[]: string { return "Vector"; }
653 /** Returns a Vector built from the values produced by the specified Iterable.
654 * @param mixed $iterable
655 * @return object
657 public static function fromItems(mixed $iterable)[]: this {
658 return new self($iterable);
661 /** Returns a Vector built from the keys of the specified container.
662 * @param mixed $container
663 * @return object
665 public static function fromKeysOf(mixed $container)[]: this {
666 if ($container is null) {
667 return new self();
668 } else if (!($container is KeyedContainer<_,_>)) {
669 throw new \InvalidArgumentException(
670 "Parameter must be a container (array or collection)");
672 $result = vec[];
673 foreach ($container as $key => $_) {
674 $result[] = $key;
676 return new self($result);
679 /** Returns a Vector built from the values from the specified array.
680 * @param mixed $arr
681 * @return object
683 public static function fromArray(mixed $arr): this {
684 return new self($arr);
688 /** An immutable ordered collection where values are keyed using integers 0
689 * thru n-1 in order.
691 final class ImmVector<T> implements \ConstVector<T> {
693 /** Returns a ImmVector built from the values produced by the specified
694 * Iterable.
695 * @param mixed $iterable
697 <<__Native>>
698 public function __construct(mixed $iterable = null)[]: void;
700 /** Returns an ImmVector built from the values produced by the specified
701 * Iterable.
702 * @param mixed $iterable
703 * @return object
705 public static function fromItems(mixed $iterable)[]: this {
706 return new self($iterable);
709 /** Returns a ImmVector built from the keys of the specified container.
710 * @param mixed $container
711 * @return object
713 public static function fromKeysOf(mixed $container)[]: this {
714 if ($container is null) {
715 return new self();
716 } else if (!($container is KeyedContainer<_,_>)) {
717 throw new \InvalidArgumentException(
718 "Parameter must be a container (array or collection)");
720 $result = vec[];
721 foreach ($container as $key => $_) {
722 $result[] = $key;
724 return new self($result);
727 /** Returns true if the ImmVector is empty, false otherwise.
728 * @return bool
730 public readonly function isEmpty()[]: bool {
731 return !$this->count();
734 /** Returns the number of values in the ImmVector.
735 * @return int
737 public readonly function count()[]: int {
738 return \count(vec($this));
741 /** Returns an Iterable that produces the values from this ImmVector.
742 * @return object
744 /* HH_FIXME[2049] */
745 public function items()[]: \LazyIterableView {
746 /* HH_FIXME[2049] */
747 return new \LazyIterableView($this);
750 /** Returns true if the specified key is present in the ImmVector, returns
751 * false otherwise.
752 * @param mixed $key
753 * @return bool
755 public readonly function containsKey(mixed $key)[]: bool {
756 if (!($key is int)) {
757 throw new \InvalidArgumentException(
758 "Only integer keys may be used with Vectors"
761 return ($key >= 0) && ($key < $this->count());
764 /** Returns the value at the specified key. If the key is not present, an
765 * exception is thrown.
766 * @param mixed $key
767 * @return mixed
769 public function at(mixed $key)[]: T {
770 return $this[HH\FIXME\UNSAFE_CAST<mixed, int>($key)];
773 /** Returns the value at the specified key. If the key is not present, null is
774 * returned.
775 * @param mixed $key
776 * @return mixed
778 public function get(mixed $key)[]: ?T {
779 /* HH_FIXME[4110] */
780 return idx($this, $key);
783 /** Returns an iterator that points to beginning of this ImmVector.
784 * @return object
786 <<__Native>>
787 public function getIterator()[]: Iterator<T>;
789 /** Returns a Vector of the values produced by applying the specified callback
790 * on each value from this ImmVector.
791 * @param mixed $callback
792 * @return object
794 public function map<To>(
795 (function(T)[_]: To) $callback,
796 )[ctx $callback]: ImmVector<To> {
797 $ret = vec[];
798 foreach ($this as $v) {
799 $ret[] = $callback($v);
801 return new ImmVector($ret);
804 /** Returns a Vector of the values produced by applying the specified callback
805 * on each key and value from this ImmVector.
806 * @param mixed $callback
807 * @return object
809 public function mapWithKey<To>(
810 (function(int, T)[_]: To) $callback,
811 )[ctx $callback]: ImmVector<To> {
812 $ret = vec[];
813 foreach ($this as $k => $v) {
814 $ret[] = $callback($k, $v);
816 return new ImmVector($ret);
819 /** Returns a Vector of all the values from this ImmVector for which the
820 * specified callback returns true.
821 * @param mixed $callback
822 * @return object
824 public function filter((function(T)[_]: bool) $callback)[ctx $callback]: this {
825 $ret = vec[];
826 foreach ($this as $v) {
827 if ($callback($v)) {
828 $ret[] = $v;
831 return new ImmVector($ret);
834 /** Returns a Vector of all the values from this ImmVector for which the
835 * specified callback returns true.
836 * @param mixed $callback
837 * @return object
839 public function filterWithKey(
840 (function(int, T)[_]: bool) $callback,
841 )[ctx $callback]: this {
842 $ret = vec[];
843 foreach ($this as $k => $v) {
844 if ($callback($k, $v)) {
845 $ret[] = $v;
848 return new ImmVector($ret);
851 /** Returns a KeyedIterable produced by combined the specified Iterables
852 * pair-wise.
853 * @param mixed $iterable
854 * @return object
856 public function zip<To>(
857 mixed $iterable,
858 )[]: ImmVector<Pair<T, To>> {
859 $i = 0;
860 $result = vec[];
861 $count = $this->count();
862 foreach (
863 HH\FIXME\UNSAFE_CAST<mixed, Traversable<To>>($iterable) as $value
865 if ($i === $count) {
866 break;
868 $result[] = Pair { $this[$i], $value };
869 $i++;
871 return new self($result);
874 /** Returns a ImmVector containing the first n values of this ImmVector.
875 * @param mixed $n
876 * @return object
878 public function take(mixed $n)[]: this {
879 if (!($n is int)) {
880 throw new \InvalidArgumentException("Parameter n must be an integer");
882 $count = $this->count();
883 $n = $n < 0 ? 0 : ($n > $count ? $count : $n);
884 $result = vec[];
885 for ($i = 0; $i < $n; $i++) {
886 $result[] = $this[$i];
888 return new self($result);
891 /** Returns a ImmVector containing the values of this ImmVector up to but not
892 * including the first value that produces false when passed to the specified
893 * callback.
894 * @param mixed $callback
895 * @return object
897 public function takeWhile(
898 (function(T)[_]: bool) $callback,
899 )[ctx $callback]: this {
900 $ret = vec[];
901 foreach ($this as $v) {
902 if (!$callback($v)) {
903 break;
905 $ret[] = $v;
907 return new ImmVector($ret);
910 /** Returns a ImmVector containing all values except the first n of this
911 * ImmVector.
912 * @param mixed $n
913 * @return object
915 public function skip(mixed $n)[]: this {
916 if (!($n is int)) {
917 throw new \InvalidArgumentException("Parameter n must be an integer");
919 $count = $this->count();
920 $n = $n < 0 ? 0 : ($n > $count ? $count : $n);
921 $result = vec[];
922 for ($i = $n; $i < $count; $i++) {
923 $result[] = $this[$i];
925 return new self($result);
928 /** Returns a ImmVector containing the values of this ImmVector excluding the
929 * first values that produces true when passed to the specified callback.
930 * @param mixed $fn
931 * @return object
933 public function skipWhile((function(T)[_]: bool) $fn)[ctx $fn]: this {
934 $ret = vec[];
935 $skipping = true;
936 foreach ($this as $v) {
937 if ($skipping) {
938 if ($fn($v)) {
939 continue;
941 $skipping = false;
943 $ret[] = $v;
945 return new ImmVector($ret);
948 /** Returns an ImmVector containing the specified range of values from this
949 * ImmVector. The range is specified by two non-negative integers: a starting
950 * position and a length.
951 * @param mixed $start
952 * @param mixed $len
953 * @return object
955 public function slice(mixed $start, mixed $len)[]: this {
956 if (!($start is int) || $start < 0) {
957 throw new \InvalidArgumentException(
958 "Parameter start must be a non-negative integer");
960 if (!($len is int) || $len < 0) {
961 throw new \InvalidArgumentException(
962 "Parameter len must be a non-negative integer");
964 $count = $this->count();
965 $skip = $start < $count ? $start : $count;
966 $size = $len < $count - $skip ? $len : $count - $skip;
967 $result = vec[];
968 for ($i = $skip; $i < $skip + $size; $i++) {
969 $result[] = $this[$i];
971 return new self($result);
974 /** Builds a new ImmVector by concatenating the elements of this ImmVector with
975 * the elements of the specified Iterable.
976 * @param mixed $iterable
977 * @return object
979 public function concat<To super T>(
980 mixed $iterable,
981 )[]: ImmVector<To> {
982 $result = vec($this);
983 foreach (
984 HH\FIXME\UNSAFE_CAST<mixed, Traversable<To>>($iterable) as $value
986 $result[] = $value;
988 return new self($result);
991 /** Returns the first value from this ImmVector, or null if this ImmVector is
992 * empty.
993 * @return mixed
995 public function firstValue()[]: mixed {
996 /* HH_FIXME[4110] */
997 return idx($this, 0);
1000 /** Returns the first key from this ImmVector, or null if this ImmVector is
1001 * empty.
1002 * @return mixed
1004 public readonly function firstKey()[]: mixed {
1005 return $this->count() ? 0 : null;
1008 /** Returns the last value from this ImmVector, or null if this ImmVector is
1009 * empty.
1010 * @return mixed
1012 public function lastValue()[]: mixed {
1013 $count = $this->count();
1014 return $count ? $this[$count - 1] : null;
1017 /** Returns the last key from this ImmVector, or null if this ImmVector is
1018 * empty.
1019 * @return mixed
1021 public readonly function lastKey()[]: mixed {
1022 $count = $this->count();
1023 return $count ? ($count - 1) : null;
1026 /** Returns an Iterable that produces the keys from this ImmVector.
1027 * @return object
1029 public function keys()[]: ImmVector<int> {
1030 return new self($this->toKeysArray());
1033 /** @return string
1035 public function __toString()[]: string { return "ImmVector"; }
1037 /** Returns a Vector built from the values of this ImmVector.
1038 * @return object
1040 public function toVector()[]: Vector<T> {
1041 return new Vector($this);
1044 /** Returns an immutable version of this collection.
1045 * @return object
1047 public function toImmVector()[]: this {
1048 return $this;
1051 /** Returns a Map built from the keys and values of this ImmVector.
1052 * @return object
1054 /* HH_FIXME[2049] */
1055 public function toMap()[]: Map<int, T> {
1056 /* HH_FIXME[2049] */
1057 return new Map($this);
1060 /** Returns a ImmMap built from the keys and values of this ImmVector.
1061 * @return object
1063 /* HH_FIXME[2049] */
1064 public function toImmMap()[]: ImmMap<int, T> {
1065 /* HH_FIXME[2049] */
1066 return new ImmMap($this);
1069 /** Returns a Set built from the values of this ImmVector.
1070 * @return object
1072 /* HH_FIXME[2049] */
1073 public function toSet()[]: Set<T> where T as arraykey {
1074 /* HH_FIXME[2049] */
1075 return new Set($this);
1078 /** Returns a ImmSet built from the values of this ImmVector.
1079 * @return object
1081 /* HH_FIXME[2049] */
1082 public function toImmSet()[]: ImmSet<T> where T as arraykey {
1083 /* HH_FIXME[2049] */
1084 return new ImmSet($this);
1087 /** Returns an immutable version of this collection.
1088 * @return object
1090 public function immutable()[]: this {
1091 return $this;
1094 /** Returns a copy of this ImmVector.
1095 * @return object
1097 public function values()[]: this {
1098 return new self($this);
1101 /** Returns a lazy iterable view of this ImmVector.
1102 * @return object
1104 /* HH_FIXME[2049] */
1105 public function lazy()[]: \LazyKeyedIterableView {
1106 /* HH_FIXME[2049] */
1107 return new \LazyKeyedIterableView($this);
1110 /** Returns a varray built from the values from this ImmVector.
1111 * @return varray
1113 public function toVArray()[]: varray<T> {
1114 return varray($this);
1117 public function toDArray()[]: darray<int, T> {
1118 return darray($this);
1121 /** Returns a varray built from the keys from this ImmVector.
1122 * @return varray
1124 public readonly function toKeysArray()[]: varray<int> {
1125 $count = $this->count();
1126 return $count
1127 ? varray(HH\FIXME\UNSAFE_CAST<mixed, varray<int>>(\range(0, $count - 1)))
1128 : vec[];
1131 /** Returns a varray built from the values from this ImmVector.
1132 * @return varray
1134 public function toValuesArray()[]: varray<T> {
1135 return $this->toVArray();
1138 /** Returns index of the specified value if it is present, -1 otherwise.
1139 * @param mixed $search_value
1140 * @return int
1142 public readonly function linearSearch(mixed $search_value)[]: int {
1143 foreach (vec($this) as $i => $value) {
1144 if ($value === $search_value) {
1145 return $i;
1148 return -1;
1152 } // namespace HH