From 25b62154b281e1043be04457c2ae14fedb536c58 Mon Sep 17 00:00:00 2001 From: Glavo Date: Mon, 6 Jan 2025 23:25:07 +0800 Subject: [PATCH] Convert CRLF to LF --- buildSrc/src/main/kotlin/GeneratePlugin.kt | 16 + buildSrc/src/main/kotlin/GenerateTask.kt | 16 + buildSrc/src/main/kotlin/Primitives.kt | 16 + kala-base/src/main/java/kala/Equatable.java | 48 +- .../java/kala/annotations/Contravariant.java | 48 +- .../java/kala/annotations/ReplaceWith.java | 50 +- .../java/kala/annotations/StaticClass.java | 54 +- .../collection/base/AbstractIterator.java | 80 +- .../collection/base/AbstractMapIterator.java | 44 +- .../kala/collection/base/AnyTraversable.java | 490 +-- .../kala/collection/base/MapIterator.java | 526 ++-- .../kala/collection/base/MapIterators.java | 314 +- .../java/kala/collection/base/Mappable.java | 86 +- .../kala/collection/base/Traversable.java | 2496 ++++++++-------- .../base/primitive/PrimitiveIterator.java | 339 ++- .../base/primitive/PrimitiveTraversable.java | 166 +- .../java/kala/collection/factory/Factory.java | 92 +- .../primitive/PrimitiveComparator.java | 62 +- .../src/main/java/kala/control/AnyOption.java | 52 +- .../java/kala/control/OptionContainer.java | 618 ++-- kala-base/src/main/java/kala/control/Try.java | 1054 +++---- .../kala/control/primitive/BooleanOption.java | 322 +- .../java/kala/function/IndexedConsumer.java | 72 +- .../java/kala/function/IndexedFunction.java | 76 +- .../java/kala/function/IntIntBiFunction.java | 42 +- .../kala/function/LargeIndexedConsumer.java | 72 +- .../kala/function/LargeIndexedFunction.java | 76 +- .../main/java/kala/function/package-info.java | 44 +- kala-base/src/main/java/kala/io/StdOut.java | 1114 +++---- .../src/main/java/kala/tuple/EmptyTuple.java | 84 +- kala-base/src/main/java/kala/tuple/HList.java | 106 +- .../main/java/kala/tuple/NonEmptyTuple.java | 48 +- kala-base/src/main/java/kala/tuple/Tuple.java | 2660 ++++++++--------- .../src/main/java/kala/tuple/Tuple2.java | 288 +- .../src/main/java/kala/tuple/Tuple8.java | 318 +- .../src/main/java/kala/tuple/Tuple9.java | 354 +-- .../src/main/java/kala/tuple/TupleXXL.java | 286 +- .../kala/tuple/primitive/PrimitiveTuple.java | 42 +- .../src/main/java/kala/value/CheckedVar.java | 114 +- .../src/main/java/kala/value/LazyValue.java | 270 +- .../main/java/kala/value/TransientVar.java | 96 +- kala-base/src/main/java/kala/value/Var.java | 110 +- .../src/main/java/kala/value/VolatileVar.java | 96 +- .../base/primitive/PrimitiveIterator.java.ftl | 1766 +++++------ .../primitive/PrimitiveTraversable.java.ftl | 908 +++--- .../primitive/PrimitiveComparators.java.ftl | 436 +-- kala-collection-primitive/build.gradle.kts | 16 + .../AbstractImmutablePrimitiveSet.java.ftl | 100 +- .../primitive/ImmutablePrimitiveSet.java.ftl | 368 +-- .../ImmutableSortedPrimitiveArraySet.java.ftl | 588 ++-- .../primitive/PrimitiveSetLike.java.ftl | 80 +- .../primitive/PrimitiveSetView.java.ftl | 94 +- kala-collection/build.gradle.kts | 22 +- .../kala/collection/AbstractCollection.java | 90 +- .../java/kala/collection/AbstractMap.java | 100 +- .../main/java/kala/collection/SeqLike.java | 656 ++-- .../main/java/kala/collection/SortedSet.java | 138 +- .../collection/mutable/MutableCollection.java | 220 +- .../mutable/MutableCollectionEditor.java | 62 +- kala-common-gson/build.gradle.kts | 16 + settings.gradle.kts | 32 +- src/main/java/module-info.java | 40 +- .../java/kala/collection/SimpleIterable.java | 68 +- src/test/java/kala/collection/TestData.java | 128 +- src/test/java/kala/control/OptionTest.java | 96 +- .../control/primitive/BooleanOptionTest.java | 80 +- 66 files changed, 9785 insertions(+), 9676 deletions(-) diff --git a/buildSrc/src/main/kotlin/GeneratePlugin.kt b/buildSrc/src/main/kotlin/GeneratePlugin.kt index 14bc92c9..92bd0a80 100644 --- a/buildSrc/src/main/kotlin/GeneratePlugin.kt +++ b/buildSrc/src/main/kotlin/GeneratePlugin.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginExtension diff --git a/buildSrc/src/main/kotlin/GenerateTask.kt b/buildSrc/src/main/kotlin/GenerateTask.kt index 3ad884b1..d5bc4927 100644 --- a/buildSrc/src/main/kotlin/GenerateTask.kt +++ b/buildSrc/src/main/kotlin/GenerateTask.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles diff --git a/buildSrc/src/main/kotlin/Primitives.kt b/buildSrc/src/main/kotlin/Primitives.kt index 5852ef76..8d22de18 100644 --- a/buildSrc/src/main/kotlin/Primitives.kt +++ b/buildSrc/src/main/kotlin/Primitives.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import freemarker.template.SimpleScalar import freemarker.template.TemplateMethodModelEx diff --git a/kala-base/src/main/java/kala/Equatable.java b/kala-base/src/main/java/kala/Equatable.java index 9bc0cc51..d87cce01 100644 --- a/kala-base/src/main/java/kala/Equatable.java +++ b/kala-base/src/main/java/kala/Equatable.java @@ -1,24 +1,24 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala; - -public interface Equatable { - default boolean canEqual(Object other) { - return true; - } - - boolean equals(Object other); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala; + +public interface Equatable { + default boolean canEqual(Object other) { + return true; + } + + boolean equals(Object other); +} diff --git a/kala-base/src/main/java/kala/annotations/Contravariant.java b/kala-base/src/main/java/kala/annotations/Contravariant.java index c9d52cb4..97abe458 100644 --- a/kala-base/src/main/java/kala/annotations/Contravariant.java +++ b/kala-base/src/main/java/kala/annotations/Contravariant.java @@ -1,24 +1,24 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.annotations; - -import java.lang.annotation.*; - -@Documented -@Target(ElementType.TYPE_PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface Contravariant { -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.annotations; + +import java.lang.annotation.*; + +@Documented +@Target(ElementType.TYPE_PARAMETER) +@Retention(RetentionPolicy.SOURCE) +public @interface Contravariant { +} diff --git a/kala-base/src/main/java/kala/annotations/ReplaceWith.java b/kala-base/src/main/java/kala/annotations/ReplaceWith.java index a9049723..b6a0bcd6 100644 --- a/kala-base/src/main/java/kala/annotations/ReplaceWith.java +++ b/kala-base/src/main/java/kala/annotations/ReplaceWith.java @@ -1,25 +1,25 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.annotations; - -import java.lang.annotation.*; - -@Documented -@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR}) -@Retention(RetentionPolicy.SOURCE) -public @interface ReplaceWith { - String value(); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.annotations; + +import java.lang.annotation.*; + +@Documented +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.SOURCE) +public @interface ReplaceWith { + String value(); +} diff --git a/kala-base/src/main/java/kala/annotations/StaticClass.java b/kala-base/src/main/java/kala/annotations/StaticClass.java index 4cafdfd4..7aa39dba 100644 --- a/kala-base/src/main/java/kala/annotations/StaticClass.java +++ b/kala-base/src/main/java/kala/annotations/StaticClass.java @@ -1,27 +1,27 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.annotations; - -import java.lang.annotation.*; - -/** - * Annotate a class as a static class, which cannot be instantiated. - */ -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.SOURCE) -public @interface StaticClass { -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.annotations; + +import java.lang.annotation.*; + +/** + * Annotate a class as a static class, which cannot be instantiated. + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface StaticClass { +} diff --git a/kala-base/src/main/java/kala/collection/base/AbstractIterator.java b/kala-base/src/main/java/kala/collection/base/AbstractIterator.java index 2ea87480..402b3028 100644 --- a/kala-base/src/main/java/kala/collection/base/AbstractIterator.java +++ b/kala-base/src/main/java/kala/collection/base/AbstractIterator.java @@ -1,40 +1,40 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.annotations.Covariant; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public abstract class AbstractIterator<@Covariant E> implements Iterator { - - /// @throws NoSuchElementException when `hasNext()` returns `false`. - protected void checkStatus() throws NoSuchElementException { - if (!hasNext()) { - throw new NoSuchElementException("The iterator has no more elements"); - } - } - - @Override - public String toString() { - if (!hasNext()) { - return super.toString() + "[]"; - } else { - return super.toString() + "[]"; - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.annotations.Covariant; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public abstract class AbstractIterator<@Covariant E> implements Iterator { + + /// @throws NoSuchElementException when `hasNext()` returns `false`. + protected void checkStatus() throws NoSuchElementException { + if (!hasNext()) { + throw new NoSuchElementException("The iterator has no more elements"); + } + } + + @Override + public String toString() { + if (!hasNext()) { + return super.toString() + "[]"; + } else { + return super.toString() + "[]"; + } + } +} diff --git a/kala-base/src/main/java/kala/collection/base/AbstractMapIterator.java b/kala-base/src/main/java/kala/collection/base/AbstractMapIterator.java index 35fddb8d..6f79c6e0 100644 --- a/kala-base/src/main/java/kala/collection/base/AbstractMapIterator.java +++ b/kala-base/src/main/java/kala/collection/base/AbstractMapIterator.java @@ -1,22 +1,22 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.tuple.Tuple2; - -public abstract class AbstractMapIterator extends AbstractIterator> implements MapIterator { - -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.tuple.Tuple2; + +public abstract class AbstractMapIterator extends AbstractIterator> implements MapIterator { + +} diff --git a/kala-base/src/main/java/kala/collection/base/AnyTraversable.java b/kala-base/src/main/java/kala/collection/base/AnyTraversable.java index f3cab085..9b8bdaf7 100644 --- a/kala-base/src/main/java/kala/collection/base/AnyTraversable.java +++ b/kala-base/src/main/java/kala/collection/base/AnyTraversable.java @@ -1,245 +1,245 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.collection.factory.CollectionFactory; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Range; - -import java.util.*; -import java.util.stream.BaseStream; -import java.util.stream.Collector; -import java.util.stream.StreamSupport; - -public interface AnyTraversable extends Sized { - - @NotNull Traversable asGeneric(); - - static int knownSize(@NotNull Object c) { - Objects.requireNonNull(c); - if (c instanceof Sized other) { - return other.knownSize(); - } - if (c instanceof Collection other) { - return other.size(); - } - return -1; - } - - @NotNull Iterator iterator(); - - default Spliterator spliterator() { - final int ks = this.knownSize(); - if (ks == 0) { - return Spliterators.emptySpliterator(); - } else if (ks > 0) { - return Spliterators.spliterator(iterator(), ks, characteristics()); - } else { - return Spliterators.spliteratorUnknownSize(iterator(), characteristics()); - } - } - - default int characteristics() { - return 0; - } - - default @NotNull BaseStream stream() { - return StreamSupport.stream(spliterator(), false); - } - - default @NotNull BaseStream parallelStream() { - return StreamSupport.stream(spliterator(), true); - } - - //region Size Info - - @Override - default boolean isEmpty() { - final int knownSize = knownSize(); - if (knownSize < 0) { - return !iterator().hasNext(); - } else { - return knownSize == 0; - } - } - - /** - * Returns the size of this {@code AnyTraversable} if is a finite structure. - * - * @return the number of elements in this {@code AnyTraversable} - */ - @Override - default int size() { - return Iterators.size(iterator()); - } - - @Override - @Range(from = -1, to = Integer.MAX_VALUE) - default int knownSize() { - return -1; - } - - //endregion - - //region Size Compare Operations - - @Override - default int sizeCompare(int otherSize) { - if (otherSize < 0) { - return 1; - } - final int knownSize = knownSize(); - if (knownSize >= 0) { - return Integer.compare(knownSize, otherSize); - } - int i = 0; - Iterator it = iterator(); - while (it.hasNext()) { - it.next(); - if (i == otherSize) { - return 1; - } - i++; - } - return i - otherSize; - } - - default int sizeCompare(@NotNull Iterable other) { - final int os = knownSize(other); - - if (os >= 0) { - return sizeCompare(os); - } - int ks = this.knownSize(); - if (ks == 0) { - return other.iterator().hasNext() ? -1 : 0; - } else if (ks > 0) { - Iterator it = other.iterator(); - while (it.hasNext()) { - it.next(); - --ks; - if (ks == 0) { - return it.hasNext() ? -1 : 0; - } - } - return 1; - } - - Iterator it1 = this.iterator(); - Iterator it2 = other.iterator(); - while (it1.hasNext() && it2.hasNext()) { - it1.next(); - it2.next(); - } - - if (it1.hasNext()) { - return 1; - } - if (it2.hasNext()) { - return -1; - } - return 0; - } - - @ApiStatus.NonExtendable - default boolean sizeEquals(@NotNull Iterable other) { - return sizeCompare(other) == 0; - } - - @ApiStatus.NonExtendable - default boolean sizeLessThan(@NotNull Iterable other) { - return sizeCompare(other) < 0; - } - - @ApiStatus.NonExtendable - default boolean sizeLessThanOrEquals(@NotNull Iterable other) { - return sizeCompare(other) <= 0; - } - - @ApiStatus.NonExtendable - default boolean sizeGreaterThan(@NotNull Iterable other) { - return sizeCompare(other) > 0; - } - - @ApiStatus.NonExtendable - default boolean sizeGreaterThanOrEquals(@NotNull Iterable other) { - return sizeCompare(other) >= 0; - } - - //endregion - - //boolean containsAll(@NotNull Iterable values); - - default R collect(@NotNull Collector collector) { - return Iterators.collect(iterator(), collector); - } - - default R collect(@NotNull CollectionFactory factory) { - return Iterators.collect(iterator(), factory); - } - - @Contract(value = "_ -> param1", mutates = "param1") - default > G collect(G destination) { - Iterator it = this.iterator(); - while (it.hasNext()) { - destination.plusAssign(it.next()); - } - return destination; - } - - @Contract(value = "_ -> param1", mutates = "param1") - default > C collect(C collection) { - Iterator it = this.iterator(); - while (it.hasNext()) { - collection.add(it.next()); - } - return collection; - } - - @NotNull Object toArray(); - - //region String Representation - - default @NotNull A joinTo(@NotNull A buffer) { - return joinTo(buffer, ", "); - } - - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { - return joinTo(buffer, separator, "", ""); - } - - @Contract(value = "_, _, _, _ -> param1", mutates = "param1") - @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix - ); - - default @NotNull String joinToString() { - return joinTo(new StringBuilder()).toString(); - } - - default @NotNull String joinToString(CharSequence separator) { - return joinTo(new StringBuilder(), separator).toString(); - } - - default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { - return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); - } - - //endregion -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.collection.factory.CollectionFactory; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Range; + +import java.util.*; +import java.util.stream.BaseStream; +import java.util.stream.Collector; +import java.util.stream.StreamSupport; + +public interface AnyTraversable extends Sized { + + @NotNull Traversable asGeneric(); + + static int knownSize(@NotNull Object c) { + Objects.requireNonNull(c); + if (c instanceof Sized other) { + return other.knownSize(); + } + if (c instanceof Collection other) { + return other.size(); + } + return -1; + } + + @NotNull Iterator iterator(); + + default Spliterator spliterator() { + final int ks = this.knownSize(); + if (ks == 0) { + return Spliterators.emptySpliterator(); + } else if (ks > 0) { + return Spliterators.spliterator(iterator(), ks, characteristics()); + } else { + return Spliterators.spliteratorUnknownSize(iterator(), characteristics()); + } + } + + default int characteristics() { + return 0; + } + + default @NotNull BaseStream stream() { + return StreamSupport.stream(spliterator(), false); + } + + default @NotNull BaseStream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + //region Size Info + + @Override + default boolean isEmpty() { + final int knownSize = knownSize(); + if (knownSize < 0) { + return !iterator().hasNext(); + } else { + return knownSize == 0; + } + } + + /** + * Returns the size of this {@code AnyTraversable} if is a finite structure. + * + * @return the number of elements in this {@code AnyTraversable} + */ + @Override + default int size() { + return Iterators.size(iterator()); + } + + @Override + @Range(from = -1, to = Integer.MAX_VALUE) + default int knownSize() { + return -1; + } + + //endregion + + //region Size Compare Operations + + @Override + default int sizeCompare(int otherSize) { + if (otherSize < 0) { + return 1; + } + final int knownSize = knownSize(); + if (knownSize >= 0) { + return Integer.compare(knownSize, otherSize); + } + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + if (i == otherSize) { + return 1; + } + i++; + } + return i - otherSize; + } + + default int sizeCompare(@NotNull Iterable other) { + final int os = knownSize(other); + + if (os >= 0) { + return sizeCompare(os); + } + int ks = this.knownSize(); + if (ks == 0) { + return other.iterator().hasNext() ? -1 : 0; + } else if (ks > 0) { + Iterator it = other.iterator(); + while (it.hasNext()) { + it.next(); + --ks; + if (ks == 0) { + return it.hasNext() ? -1 : 0; + } + } + return 1; + } + + Iterator it1 = this.iterator(); + Iterator it2 = other.iterator(); + while (it1.hasNext() && it2.hasNext()) { + it1.next(); + it2.next(); + } + + if (it1.hasNext()) { + return 1; + } + if (it2.hasNext()) { + return -1; + } + return 0; + } + + @ApiStatus.NonExtendable + default boolean sizeEquals(@NotNull Iterable other) { + return sizeCompare(other) == 0; + } + + @ApiStatus.NonExtendable + default boolean sizeLessThan(@NotNull Iterable other) { + return sizeCompare(other) < 0; + } + + @ApiStatus.NonExtendable + default boolean sizeLessThanOrEquals(@NotNull Iterable other) { + return sizeCompare(other) <= 0; + } + + @ApiStatus.NonExtendable + default boolean sizeGreaterThan(@NotNull Iterable other) { + return sizeCompare(other) > 0; + } + + @ApiStatus.NonExtendable + default boolean sizeGreaterThanOrEquals(@NotNull Iterable other) { + return sizeCompare(other) >= 0; + } + + //endregion + + //boolean containsAll(@NotNull Iterable values); + + default R collect(@NotNull Collector collector) { + return Iterators.collect(iterator(), collector); + } + + default R collect(@NotNull CollectionFactory factory) { + return Iterators.collect(iterator(), factory); + } + + @Contract(value = "_ -> param1", mutates = "param1") + default > G collect(G destination) { + Iterator it = this.iterator(); + while (it.hasNext()) { + destination.plusAssign(it.next()); + } + return destination; + } + + @Contract(value = "_ -> param1", mutates = "param1") + default > C collect(C collection) { + Iterator it = this.iterator(); + while (it.hasNext()) { + collection.add(it.next()); + } + return collection; + } + + @NotNull Object toArray(); + + //region String Representation + + default @NotNull A joinTo(@NotNull A buffer) { + return joinTo(buffer, ", "); + } + + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { + return joinTo(buffer, separator, "", ""); + } + + @Contract(value = "_, _, _, _ -> param1", mutates = "param1") + @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix + ); + + default @NotNull String joinToString() { + return joinTo(new StringBuilder()).toString(); + } + + default @NotNull String joinToString(CharSequence separator) { + return joinTo(new StringBuilder(), separator).toString(); + } + + default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { + return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); + } + + //endregion +} diff --git a/kala-base/src/main/java/kala/collection/base/MapIterator.java b/kala-base/src/main/java/kala/collection/base/MapIterator.java index 66e4bcbd..b312f372 100644 --- a/kala-base/src/main/java/kala/collection/base/MapIterator.java +++ b/kala-base/src/main/java/kala/collection/base/MapIterator.java @@ -1,263 +1,263 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.function.CheckedBiConsumer; -import kala.tuple.Tuple; -import kala.tuple.Tuple2; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Iterator; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; - -@SuppressWarnings("unchecked") -public interface MapIterator extends Iterator> { - - static @NotNull MapIterator empty() { - return (MapIterator) MapIterators.EMPTY; - } - - static @NotNull MapIterator ofIterator(@NotNull Iterator> it) { - if (!it.hasNext()) { // implicit null check of it - return empty(); - } - if (it instanceof MapIterator) { - return (MapIterator) it; - } - - return new MapIterators.OfIterator<>(it); - } - - boolean hasNext(); - - K nextKey(); - - V getValue(); - - @Override - default Tuple2 next() { - return Tuple.of(nextKey(), getValue()); - } - - default boolean containsKey(K key) { - if (key == null) { - while (hasNext()) { - if (null == nextKey()) { - return true; - } - } - } else { - while (hasNext()) { - if (key.equals(nextKey())) { - return true; - } - } - } - return false; - } - - default boolean containsValue(Object value) { - if (value == null) { - while (hasNext()) { - nextKey(); - if (null == getValue()) { - return true; - } - } - } else { - while (hasNext()) { - nextKey(); - if (value.equals(getValue())) { - return true; - } - } - } - return false; - } - - default boolean anyMatch(@NotNull BiPredicate predicate) { - while (hasNext()) { - if (predicate.test(nextKey(), getValue())) { - return true; - } - } - return false; - } - - default boolean allMatch(@NotNull BiPredicate predicate) { - while (hasNext()) { - if (!predicate.test(nextKey(), getValue())) { - return false; - } - } - return true; - } - - default boolean noneMatch(@NotNull BiPredicate predicate) { - while (hasNext()) { - if (predicate.test(nextKey(), getValue())) { - return false; - } - } - return true; - } - - default @NotNull Iterator map(@NotNull BiFunction mapper) { - Objects.requireNonNull(mapper); - if (!hasNext()) { - return Iterators.empty(); - } - return new MapIterators.Mapped<>(this, mapper); - } - - default @NotNull MapIterator mapValues(@NotNull BiFunction mapper) { - Objects.requireNonNull(mapper); - if (!hasNext()) { - return MapIterator.empty(); - } - return new MapIterators.MapValues<>(this, mapper); - } - - default int hash() { - int hash = 0; - while (hasNext()) { - hash += Objects.hashCode(nextKey()) ^ Objects.hashCode(getValue()); - } - return hash; - } - - default @NotNull Iterator asKeysIterator() { - if (!hasNext()) { - return Iterators.empty(); - } - return new MapIterators.KeysIterator<>(this); - } - - default @NotNull Iterator asValuesIterator() { - if (!hasNext()) { - return Iterators.empty(); - } - return new MapIterators.ValuesIterator<>(this); - } - - default void forEach(@NotNull BiConsumer action) { - while (hasNext()) { - action.accept(nextKey(), getValue()); - } - } - - default void forEachChecked( - @NotNull CheckedBiConsumer action) throws Ex { - forEach(action); - } - - default void forEachUnchecked(@NotNull CheckedBiConsumer action) { - forEach(action); - } - - default @NotNull A joinTo(@NotNull A buffer) { - return joinTo(buffer, ", "); - } - - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { - return joinTo(buffer, separator, "", ""); - } - - @Contract(value = "_, _, _, _ -> param1", mutates = "param1") - default @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix - ) { - try { - buffer.append(prefix); - if (hasNext()) { - buffer.append(Objects.toString(nextKey())).append("=").append(Objects.toString(getValue())); - } - while (hasNext()) { - buffer.append(separator).append(Objects.toString(nextKey())).append("=").append(Objects.toString(getValue())); - } - buffer.append(postfix); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return buffer; - } - - default @NotNull A joinTo( - @NotNull A buffer, - @NotNull BiFunction transform) { - return joinTo(buffer, ", ", transform); - } - - default @NotNull A joinTo( - @NotNull A buffer, CharSequence separator, - @NotNull BiFunction transform) { - return joinTo(buffer, separator, "", "", transform); - } - - @Contract(value = "_, _, _, _, _ -> param1", mutates = "param1") - default @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix, - @NotNull BiFunction transform - ) { - try { - buffer.append(prefix); - if (hasNext()) { - buffer.append(transform.apply(nextKey(), getValue())); - } - while (hasNext()) { - buffer.append(separator).append(transform.apply(nextKey(), getValue())); - } - buffer.append(postfix); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return buffer; - } - - default @NotNull String joinToString() { - return joinTo(new StringBuilder()).toString(); - } - - default @NotNull String joinToString(CharSequence separator) { - return joinTo(new StringBuilder(), separator).toString(); - } - - default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { - return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); - } - - default @NotNull String joinToString(@NotNull BiFunction transform) { - return joinTo(new StringBuilder(), transform).toString(); - } - - default @NotNull String joinToString(CharSequence separator, @NotNull BiFunction transform) { - return joinTo(new StringBuilder(), separator, transform).toString(); - } - - default @NotNull String joinToString( - CharSequence separator, CharSequence prefix, CharSequence postfix, - @NotNull BiFunction transform) { - return joinTo(new StringBuilder(), separator, prefix, postfix, transform).toString(); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.function.CheckedBiConsumer; +import kala.tuple.Tuple; +import kala.tuple.Tuple2; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Iterator; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; + +@SuppressWarnings("unchecked") +public interface MapIterator extends Iterator> { + + static @NotNull MapIterator empty() { + return (MapIterator) MapIterators.EMPTY; + } + + static @NotNull MapIterator ofIterator(@NotNull Iterator> it) { + if (!it.hasNext()) { // implicit null check of it + return empty(); + } + if (it instanceof MapIterator) { + return (MapIterator) it; + } + + return new MapIterators.OfIterator<>(it); + } + + boolean hasNext(); + + K nextKey(); + + V getValue(); + + @Override + default Tuple2 next() { + return Tuple.of(nextKey(), getValue()); + } + + default boolean containsKey(K key) { + if (key == null) { + while (hasNext()) { + if (null == nextKey()) { + return true; + } + } + } else { + while (hasNext()) { + if (key.equals(nextKey())) { + return true; + } + } + } + return false; + } + + default boolean containsValue(Object value) { + if (value == null) { + while (hasNext()) { + nextKey(); + if (null == getValue()) { + return true; + } + } + } else { + while (hasNext()) { + nextKey(); + if (value.equals(getValue())) { + return true; + } + } + } + return false; + } + + default boolean anyMatch(@NotNull BiPredicate predicate) { + while (hasNext()) { + if (predicate.test(nextKey(), getValue())) { + return true; + } + } + return false; + } + + default boolean allMatch(@NotNull BiPredicate predicate) { + while (hasNext()) { + if (!predicate.test(nextKey(), getValue())) { + return false; + } + } + return true; + } + + default boolean noneMatch(@NotNull BiPredicate predicate) { + while (hasNext()) { + if (predicate.test(nextKey(), getValue())) { + return false; + } + } + return true; + } + + default @NotNull Iterator map(@NotNull BiFunction mapper) { + Objects.requireNonNull(mapper); + if (!hasNext()) { + return Iterators.empty(); + } + return new MapIterators.Mapped<>(this, mapper); + } + + default @NotNull MapIterator mapValues(@NotNull BiFunction mapper) { + Objects.requireNonNull(mapper); + if (!hasNext()) { + return MapIterator.empty(); + } + return new MapIterators.MapValues<>(this, mapper); + } + + default int hash() { + int hash = 0; + while (hasNext()) { + hash += Objects.hashCode(nextKey()) ^ Objects.hashCode(getValue()); + } + return hash; + } + + default @NotNull Iterator asKeysIterator() { + if (!hasNext()) { + return Iterators.empty(); + } + return new MapIterators.KeysIterator<>(this); + } + + default @NotNull Iterator asValuesIterator() { + if (!hasNext()) { + return Iterators.empty(); + } + return new MapIterators.ValuesIterator<>(this); + } + + default void forEach(@NotNull BiConsumer action) { + while (hasNext()) { + action.accept(nextKey(), getValue()); + } + } + + default void forEachChecked( + @NotNull CheckedBiConsumer action) throws Ex { + forEach(action); + } + + default void forEachUnchecked(@NotNull CheckedBiConsumer action) { + forEach(action); + } + + default @NotNull A joinTo(@NotNull A buffer) { + return joinTo(buffer, ", "); + } + + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { + return joinTo(buffer, separator, "", ""); + } + + @Contract(value = "_, _, _, _ -> param1", mutates = "param1") + default @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix + ) { + try { + buffer.append(prefix); + if (hasNext()) { + buffer.append(Objects.toString(nextKey())).append("=").append(Objects.toString(getValue())); + } + while (hasNext()) { + buffer.append(separator).append(Objects.toString(nextKey())).append("=").append(Objects.toString(getValue())); + } + buffer.append(postfix); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return buffer; + } + + default @NotNull A joinTo( + @NotNull A buffer, + @NotNull BiFunction transform) { + return joinTo(buffer, ", ", transform); + } + + default @NotNull A joinTo( + @NotNull A buffer, CharSequence separator, + @NotNull BiFunction transform) { + return joinTo(buffer, separator, "", "", transform); + } + + @Contract(value = "_, _, _, _, _ -> param1", mutates = "param1") + default @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix, + @NotNull BiFunction transform + ) { + try { + buffer.append(prefix); + if (hasNext()) { + buffer.append(transform.apply(nextKey(), getValue())); + } + while (hasNext()) { + buffer.append(separator).append(transform.apply(nextKey(), getValue())); + } + buffer.append(postfix); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return buffer; + } + + default @NotNull String joinToString() { + return joinTo(new StringBuilder()).toString(); + } + + default @NotNull String joinToString(CharSequence separator) { + return joinTo(new StringBuilder(), separator).toString(); + } + + default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { + return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); + } + + default @NotNull String joinToString(@NotNull BiFunction transform) { + return joinTo(new StringBuilder(), transform).toString(); + } + + default @NotNull String joinToString(CharSequence separator, @NotNull BiFunction transform) { + return joinTo(new StringBuilder(), separator, transform).toString(); + } + + default @NotNull String joinToString( + CharSequence separator, CharSequence prefix, CharSequence postfix, + @NotNull BiFunction transform) { + return joinTo(new StringBuilder(), separator, prefix, postfix, transform).toString(); + } +} diff --git a/kala-base/src/main/java/kala/collection/base/MapIterators.java b/kala-base/src/main/java/kala/collection/base/MapIterators.java index 63448439..ae03ba12 100644 --- a/kala-base/src/main/java/kala/collection/base/MapIterators.java +++ b/kala-base/src/main/java/kala/collection/base/MapIterators.java @@ -1,157 +1,157 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.function.BiFunction; - -public final class MapIterators { - private MapIterators() { - } - - public static final MapIterator EMPTY = new MapIterator() { - @Override - public Object nextKey() { - throw new NoSuchElementException(); - } - - @Override - public Object getValue() { - return null; - } - - @Override - public boolean hasNext() { - return false; - } - }; - - public static final class OfIterator extends AbstractMapIterator { - - private final Iterator> source; - - private V value; - - public OfIterator(Iterator> source) { - this.source = source; - } - - @Override - public boolean hasNext() { - return source.hasNext(); - } - - @Override - public K nextKey() { - Map.Entry n = source.next(); - this.value = n.getValue(); - return n.getKey(); - } - - @Override - public V getValue() { - return value; - } - } - - public static final class Mapped extends AbstractIterator { - private final @NotNull MapIterator source; - private final @NotNull BiFunction mapper; - - public Mapped(@NotNull MapIterator source, @NotNull BiFunction mapper) { - this.source = source; - this.mapper = mapper; - } - - @Override - public boolean hasNext() { - return source.hasNext(); - } - - @Override - public E next() { - return mapper.apply(source.nextKey(), source.getValue()); - } - } - - public static final class KeysIterator extends AbstractIterator { - private final MapIterator source; - - public KeysIterator(MapIterator source) { - this.source = source; - } - - @Override - public boolean hasNext() { - return source.hasNext(); - } - - @Override - public K next() { - return source.nextKey(); - } - } - - public static final class ValuesIterator extends AbstractIterator { - private final MapIterator source; - - public ValuesIterator(MapIterator source) { - this.source = source; - } - - @Override - public boolean hasNext() { - return source.hasNext(); - } - - @Override - public V next() { - source.nextKey(); - return source.getValue(); - } - } - - public static final class MapValues extends AbstractMapIterator { - private final @NotNull MapIterator source; - private final @NotNull BiFunction mapper; - - private K k; - - public MapValues(@NotNull MapIterator source, @NotNull BiFunction mapper) { - this.source = source; - this.mapper = mapper; - } - - @Override - public boolean hasNext() { - return source.hasNext(); - } - - @Override - public K nextKey() { - return k = source.nextKey(); - } - - @Override - public V getValue() { - return mapper.apply(k, source.getValue()); - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.function.BiFunction; + +public final class MapIterators { + private MapIterators() { + } + + public static final MapIterator EMPTY = new MapIterator() { + @Override + public Object nextKey() { + throw new NoSuchElementException(); + } + + @Override + public Object getValue() { + return null; + } + + @Override + public boolean hasNext() { + return false; + } + }; + + public static final class OfIterator extends AbstractMapIterator { + + private final Iterator> source; + + private V value; + + public OfIterator(Iterator> source) { + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public K nextKey() { + Map.Entry n = source.next(); + this.value = n.getValue(); + return n.getKey(); + } + + @Override + public V getValue() { + return value; + } + } + + public static final class Mapped extends AbstractIterator { + private final @NotNull MapIterator source; + private final @NotNull BiFunction mapper; + + public Mapped(@NotNull MapIterator source, @NotNull BiFunction mapper) { + this.source = source; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public E next() { + return mapper.apply(source.nextKey(), source.getValue()); + } + } + + public static final class KeysIterator extends AbstractIterator { + private final MapIterator source; + + public KeysIterator(MapIterator source) { + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public K next() { + return source.nextKey(); + } + } + + public static final class ValuesIterator extends AbstractIterator { + private final MapIterator source; + + public ValuesIterator(MapIterator source) { + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public V next() { + source.nextKey(); + return source.getValue(); + } + } + + public static final class MapValues extends AbstractMapIterator { + private final @NotNull MapIterator source; + private final @NotNull BiFunction mapper; + + private K k; + + public MapValues(@NotNull MapIterator source, @NotNull BiFunction mapper) { + this.source = source; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public K nextKey() { + return k = source.nextKey(); + } + + @Override + public V getValue() { + return mapper.apply(k, source.getValue()); + } + } +} diff --git a/kala-base/src/main/java/kala/collection/base/Mappable.java b/kala-base/src/main/java/kala/collection/base/Mappable.java index b56a5e7b..f7db0f9d 100644 --- a/kala-base/src/main/java/kala/collection/base/Mappable.java +++ b/kala-base/src/main/java/kala/collection/base/Mappable.java @@ -1,43 +1,43 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Function; - -/** - * A {@code Mappable} is a data structure that can be {@link #map(Function)} to another {@code Mappable}. - * - * @param the type of value - * @author Glavo - */ -public interface Mappable<@Covariant T> { - - /** - * Returns a container consisting of the results of applying the given - * function to the elements of this stream. - * - * @param The element type of the new container - * @param mapper a non-interfering stateless function to apply to each element - * @return the new container - */ - @Contract(pure = true) - @NotNull Mappable map(@NotNull Function mapper); -} - +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +/** + * A {@code Mappable} is a data structure that can be {@link #map(Function)} to another {@code Mappable}. + * + * @param the type of value + * @author Glavo + */ +public interface Mappable<@Covariant T> { + + /** + * Returns a container consisting of the results of applying the given + * function to the elements of this stream. + * + * @param The element type of the new container + * @param mapper a non-interfering stateless function to apply to each element + * @return the new container + */ + @Contract(pure = true) + @NotNull Mappable map(@NotNull Function mapper); +} + diff --git a/kala-base/src/main/java/kala/collection/base/Traversable.java b/kala-base/src/main/java/kala/collection/base/Traversable.java index 22721e6f..9d561ec0 100644 --- a/kala-base/src/main/java/kala/collection/base/Traversable.java +++ b/kala-base/src/main/java/kala/collection/base/Traversable.java @@ -1,1248 +1,1248 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base; - -import kala.annotations.Covariant; -import kala.annotations.DelegateBy; -import kala.collection.base.primitive.*; -import kala.collection.factory.CollectionBuilder; -import kala.collection.factory.primitive.*; -import kala.comparator.Comparators; -import kala.concurrent.Granularity; -import kala.concurrent.ConcurrentScope; -import kala.concurrent.LateInitCountDownLatch; -import kala.control.Option; -import kala.collection.factory.CollectionFactory; -import kala.function.*; -import kala.tuple.Tuple; -import kala.tuple.Tuple2; -import kala.value.primitive.IntVar; -import org.intellij.lang.annotations.Flow; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.stream.*; - -@FunctionalInterface -@SuppressWarnings("unchecked") -public interface Traversable<@Covariant T> extends Iterable, AnyTraversable { - - @SuppressWarnings("unchecked") - @Contract(value = "_ -> param1", pure = true) - static @NotNull Traversable narrow(Traversable traversable) { - return (Traversable) traversable; - } - - static @NotNull Traversable wrap(@NotNull Iterable iterable) { - Objects.requireNonNull(iterable); - - if (iterable instanceof Traversable) { - return narrow((Traversable) iterable); - } - - return ofSupplier(iterable::iterator); - } - - static @NotNull Traversable ofSupplier(@NotNull Supplier> supplier) { - Objects.requireNonNull(supplier); - return new Traversable<>() { - @Override - public @NotNull Iterator iterator() { - return Iterators.narrow(supplier.get()); - } - - @Override - public String toString() { - return joinToString(", ", "Traversable[", "]"); - } - }; - } - - default @NotNull Traversable asGeneric() { - return this; - } - - @NotNull Iterator iterator(); - - @Override - default Spliterator spliterator() { - return AnyTraversable.super.spliterator(); - } - - /// Returns a sequential [Stream] with this as its source. - /// - /// @return a sequential [Stream] over the elements in this `Traversable` - @Override - default @NotNull Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - /** - * Returns a possibly parallel {@code Stream} with this as its source. - * It is allowable for this method to return a sequential stream. - * - * @return a possibly parallel {@code Stream} over the elements in this - */ - @Override - default @NotNull Stream parallelStream() { - return StreamSupport.stream(spliterator(), true); - } - - default T elementAt(int index) { - final Iterator it = this.iterator(); - for (int i = 0; i < index; i++) { - if (it.hasNext()) { - it.next(); - } else { - throw new IndexOutOfBoundsException("index: " + index); - } - } - if (it.hasNext()) { - return it.next(); - } else { - throw new IndexOutOfBoundsException("index: " + index); - } - } - - default T getAny() { - return iterator().next(); - } - - default @Nullable T getAnyOrNull() { - return isNotEmpty() ? getAny() : null; - } - - default @NotNull Option getAnyOption() { - return isNotEmpty() ? Option.some(getAny()) : Option.none(); - } - - //region Element Retrieval Operations - - default @NotNull Option find(@NotNull Predicate predicate) { - for (T t : this) { - if (predicate.test(t)) { - return Option.some(t); - } - } - return Option.none(); - } - - //endregion - - //region Element Conditions - - default boolean contains(Object value) { - return Iterators.contains(iterator(), value); - } - - default boolean containsAll(Object @NotNull [] values) { - for (Object value : values) { - if (!contains(value)) { - return false; - } - } - return true; - } - - //@Override - default boolean containsAll(@NotNull Iterable values) { - for (Object value : values) { - if (!contains(value)) { - return false; - } - } - return true; - } - - default boolean sameElements(@NotNull Iterable other) { - return Iterators.sameElements(iterator(), other.iterator()); - } - - default boolean sameElements(@NotNull Iterable other, boolean identity) { - if (!identity) { - return sameElements(other); - } else { - return Iterators.sameElements(iterator(), other.iterator(), true); - } - } - - /** - * Tests whether any element of this {@code Traversable} match the {@code predicate}. - * - * @return {@code true} if either any element of this {@code Traversable} match the {@code predicate}, - * otherwise {@code false} - */ - default boolean anyMatch(@NotNull Predicate predicate) { - return Iterators.anyMatch(iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean anyMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { - return anyMatch(predicate); - } - - @ApiStatus.NonExtendable - default boolean anyMatchUnchecked(@NotNull CheckedPredicate predicate) { - return anyMatch(predicate); - } - - /** - * Tests whether all elements of this {@code Traversable} match the {@code predicate}. - * - * @return {@code true} if either all elements of this {@code Traversable} match the {@code predicate} or - * the {@code Traversable} is empty, otherwise {@code false} - */ - default boolean allMatch(@NotNull Predicate predicate) { - return Iterators.allMatch(iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean allMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { - return allMatch(predicate); - } - - @ApiStatus.NonExtendable - default boolean allMatchUnchecked(@NotNull CheckedPredicate predicate) { - return allMatch(predicate); - } - - /** - * Tests whether none elements of this {@code Traversable} match the {@code predicate}. - * - * @return {@code true} if either none elements of this {@code Traversable} match the {@code predicate} or - * the {@code Traversable} is empty, otherwise {@code false} - */ - default boolean noneMatch(@NotNull Predicate predicate) { - return Iterators.noneMatch(iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean noneMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { - return noneMatch(predicate); - } - - @ApiStatus.NonExtendable - default boolean noneMatchUnchecked(@NotNull CheckedPredicate predicate) { - return noneMatch(predicate); - } - - /** - * Equivalent to {@code this.zip(other).anyMatch(it -> predicate.test(it._1, it._2))} - */ - default boolean anyMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { - return Iterators.anyMatchWith(iterator(), other.iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean anyMatchWithChecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) throws Ex { - return anyMatchWith(other, predicate); - } - - @ApiStatus.NonExtendable - default boolean anyMatchWithUnchecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) { - return anyMatchWith(other, predicate); - } - - /** - * Equivalent to {@code this.zip(other).allMatch(it -> predicate.test(it._1, it._2))} - */ - default boolean allMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { - return Iterators.allMatchWith(iterator(), other.iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean allMatchWithChecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) throws Ex { - return allMatchWith(other, predicate); - } - - @ApiStatus.NonExtendable - default boolean allMatchWithUnchecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) { - return allMatchWith(other, predicate); - } - - /** - * Equivalent to {@code this.zip(other).noneMatch(it -> predicate.test(it._1, it._2))} - */ - default boolean noneMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { - return Iterators.noneMatchWith(iterator(), other.iterator(), predicate); - } - - @ApiStatus.NonExtendable - default boolean noneMatchWithChecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) throws Ex { - return noneMatchWith(other, predicate); - } - - @ApiStatus.NonExtendable - default boolean noneMatchWithUnchecked( - @NotNull Iterable other, - @NotNull CheckedBiPredicate predicate) { - return noneMatchWith(other, predicate); - } - - //endregion - - @DelegateBy("filterTo(Growable, Predicate)") - default R filter(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { - return filterTo(factory.newCollectionBuilder(), predicate).build(); - } - - @DelegateBy("filterNotTo(Growable, Predicate)") - default R filterNot(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { - return filterNotTo(factory.newCollectionBuilder(), predicate).build(); - } - - @DelegateBy("filterNotNullTo(Growable)") - default R filterNotNull(@NotNull CollectionFactory factory) { - return filterNotNullTo(factory.newCollectionBuilder()).build(); - } - - @DelegateBy("filterIsInstanceTo(Growable, Class)") - default R filterIsInstance(@NotNull CollectionFactory factory, Class clazz) { - return filterIsInstanceTo(factory.newCollectionBuilder(), clazz).build(); - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G filterTo(@NotNull G destination, @NotNull Predicate predicate) { - for (T e : this) { - if (predicate.test(e)) { - destination.plusAssign(e); - } - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G filterNotTo(@NotNull G destination, @NotNull Predicate predicate) { - for (T e : this) { - if (!predicate.test(e)) { - destination.plusAssign(e); - } - } - return destination; - } - - @Contract(value = "_ -> param1", mutates = "param1") - default > @NotNull G filterNotNullTo(@NotNull G destination) { - for (T e : this) { - if (e != null) { - destination.plusAssign(e); - } - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G filterIsInstanceTo(@NotNull G destination, @NotNull Class clazz) { - for (T value : this) { - if (clazz.isInstance(value)) { - destination.plusAssign((U) value); - } - } - return destination; - } - - @DelegateBy("mapTo(Growable, Function)") - default R map(@NotNull CollectionFactory factory, @NotNull Function mapper) { - return mapTo(factory.newCollectionBuilder(knownSize()), mapper).build(); - } - - default R mapToInt(@NotNull IntCollectionFactory factory, @NotNull ToIntFunction mapper) { - return IntCollectionFactory.buildBy(factory, consumer -> { - for (T e : this) { - consumer.accept(mapper.applyAsInt(e)); - } - }); - } - - default R mapToLong(@NotNull LongCollectionFactory factory, @NotNull ToLongFunction mapper) { - return LongCollectionFactory.buildBy(factory, consumer -> { - for (T e : this) { - consumer.accept(mapper.applyAsLong(e)); - } - }); - } - - default R mapToDouble(@NotNull DoubleCollectionFactory factory, @NotNull ToDoubleFunction mapper) { - return DoubleCollectionFactory.buildBy(factory, consumer -> { - for (T e : this) { - consumer.accept(mapper.applyAsDouble(e)); - } - }); - } - - default R mapToChar(@NotNull CharCollectionFactory factory, @NotNull ToCharFunction mapper) { - return CharCollectionFactory.buildBy(factory, consumer -> { - for (T e : this) { - consumer.accept(mapper.applyAsChar(e)); - } - }); - } - - default R mapToBoolean(@NotNull BooleanCollectionFactory factory, @NotNull ToBooleanFunction mapper) { - return BooleanCollectionFactory.buildBy(factory, consumer -> { - for (T e : this) { - consumer.accept(mapper.applyAsBoolean(e)); - } - }); - } - - @DelegateBy("mapNotNullTo(Growable, Function)") - default R mapNotNull(@NotNull CollectionFactory factory, @NotNull Function mapper) { - return mapNotNullTo(factory.newCollectionBuilder(knownSize()), mapper).build(); - } - - default @NotNull R mapMulti( - @NotNull CollectionFactory factory, - @NotNull BiConsumer> mapper) { - return mapMultiTo(factory.newCollectionBuilder(), mapper).build(); - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G mapTo(@NotNull G destination, @NotNull Function mapper) { - for (T e : this) { - destination.plusAssign(mapper.apply(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapToIntTo(@NotNull G destination, @NotNull ToIntFunction mapper) { - for (T e : this) { - destination.plusAssign(mapper.applyAsInt(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapToLongTo(@NotNull G destination, @NotNull ToLongFunction mapper) { - for (T e : this) { - destination.plusAssign(mapper.applyAsLong(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapToDoubleTo(@NotNull G destination, @NotNull ToDoubleFunction mapper) { - for (T e : this) { - destination.plusAssign(mapper.applyAsDouble(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapToCharTo(@NotNull G destination, @NotNull ToCharFunction mapper) { - for (T e : this) { - destination.plusAssign(mapper.applyAsChar(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapToBooleanTo(@NotNull G destination, @NotNull ToBooleanFunction mapper) { - for (T e : this) { - destination.plusAssign(mapper.applyAsBoolean(e)); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G mapNotNullTo( - @NotNull G destination, - @NotNull Function mapper) { - for (T e : this) { - U u = mapper.apply(e); - if (u != null) { - destination.plusAssign(u); - } - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull > G mapMultiTo( - @NotNull G destination, - @NotNull BiConsumer> mapper) { - - Consumer consumer = destination instanceof CollectionBuilder - ? ((CollectionBuilder) destination) - : destination::plusAssign; - - for (T value : this) { - mapper.accept(value, consumer); - } - return destination; - } - - @DelegateBy("flatMapTo(Growable, Function>)") - default @NotNull R flatMap( - @NotNull CollectionFactory factory, - @NotNull Function> mapper) { - return flatMapTo(factory.newCollectionBuilder(), mapper).build(); - } - - @DelegateBy("flatMapToIntTo(IntGrowable, Function)") - default @NotNull R flatMapToInt( - @NotNull IntCollectionFactory factory, - @NotNull Function mapper) { - return flatMapToIntTo(factory.newCollectionBuilder(), mapper).build(); - } - - @DelegateBy("flatMapToLongTo(LongGrowable, Function)") - default @NotNull R flatMapToLong( - @NotNull LongCollectionFactory factory, - @NotNull Function mapper) { - return flatMapToLongTo(factory.newCollectionBuilder(), mapper).build(); - } - - @DelegateBy("flatMapToDoubleTo(DoubleGrowable, Function)") - default @NotNull R flatMapToDouble( - @NotNull DoubleCollectionFactory factory, - @NotNull Function mapper) { - return flatMapToDoubleTo(factory.newCollectionBuilder(), mapper).build(); - } - - default > G flatMapTo( - @NotNull G destination, - @NotNull Function> mapper) { - for (T value : this) { - destination.plusAssign(mapper.apply(value)); - } - - return destination; - } - - default G flatMapToIntTo( - @NotNull G destination, - @NotNull Function mapper) { - for (T value : this) { - destination.plusAssign(mapper.apply(value)); - } - return destination; - } - - default G flatMapToLongTo( - @NotNull G destination, - @NotNull Function mapper) { - for (T value : this) { - destination.plusAssign(mapper.apply(value)); - } - return destination; - } - - default G flatMapToDoubleTo( - @NotNull G destination, - @NotNull Function mapper) { - for (T value : this) { - destination.plusAssign(mapper.apply(value)); - } - return destination; - } - - default Tuple2 partition(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { - @SuppressWarnings("rawtypes") - CollectionFactory uncheckedFactory = factory; - - Object builder1 = uncheckedFactory.newBuilder(); - Object builder2 = uncheckedFactory.newBuilder(); - - for (T e : this) { - Object builder = predicate.test(e) ? builder1 : builder2; - uncheckedFactory.addToBuilder(builder, e); - } - - return Tuple.of((R) uncheckedFactory.build(builder1), (R) uncheckedFactory.build(builder2)); - } - - @DelegateBy("distinctTo(Growable)") - default R distinct(@NotNull CollectionFactory factory) { - return distinctTo(factory.newCollectionBuilder()).build(); - } - - @DelegateBy("distinctByTo(Growable, Function)") - default R distinctBy(@NotNull CollectionFactory factory, Function mapper) { - return distinctByTo(factory.newCollectionBuilder(), mapper).build(); - } - - @DelegateBy("distinctByIntTo(Growable, ToIntFunction)") - default R distinctByInt(@NotNull CollectionFactory factory, ToIntFunction mapper) { - return distinctByIntTo(factory.newCollectionBuilder(), mapper).build(); - } - - default > @NotNull G distinctTo(G destination) { - HashSet iteratedValues = new HashSet<>(); - for (T value : this) { - if (iteratedValues.add(value)) { - destination.plusAssign(value); - } - } - return destination; - } - - default > @NotNull G distinctByTo(G destination, Function mapper) { - HashSet iteratedValues = new HashSet<>(); - for (T value : this) { - if (iteratedValues.add(mapper.apply(value))) { - destination.plusAssign(value); - } - } - return destination; - } - - default > @NotNull G distinctByIntTo(G destination, ToIntFunction mapper) { - HashSet iteratedValues = new HashSet<>(); // TODO - for (T value : this) { - if (iteratedValues.add(mapper.applyAsInt(value))) { - destination.plusAssign(value); - } - } - return destination; - } - - //region Aggregate Operations - - default int count(@NotNull Predicate predicate) { - return Iterators.count(iterator(), predicate); - } - - @DelegateBy("max(Comparator)") - default T max() { - return max(Comparators.naturalOrder()); - } - - default T max(Comparator comparator) { - if (isEmpty()) throw new NoSuchElementException(); - - return Iterators.max(iterator(), comparator); - } - - @DelegateBy("max()") - default @Nullable T maxOrNull() { - return isNotEmpty() ? max() : null; - } - - @DelegateBy("max(Comparator)") - default @Nullable T maxOrNull(@NotNull Comparator comparator) { - return isNotEmpty() ? max(comparator) : null; - } - - @DelegateBy("max()") - default @NotNull Option maxOption() { - return isNotEmpty() ? Option.some(max()) : Option.none(); - } - - @DelegateBy("max(Comparator)") - default @NotNull Option maxOption(Comparator comparator) { - return isNotEmpty() ? Option.some(max(comparator)) : Option.none(); - } - - @DelegateBy("min(Comparator)") - default T min() { - return min(Comparators.naturalOrder()); - } - - default T min(Comparator comparator) { - if (isEmpty()) throw new NoSuchElementException(); - - return Iterators.min(iterator(), comparator); - } - - @DelegateBy("min()") - default @Nullable T minOrNull() { - return isNotEmpty() ? min() : null; - } - - @DelegateBy("min(Comparator)") - default @Nullable T minOrNull(@NotNull Comparator comparator) { - return isNotEmpty() ? min(comparator) : null; - } - - @DelegateBy("min()") - default @NotNull Option minOption() { - return isNotEmpty() ? Option.some(min()) : Option.none(); - } - - @DelegateBy("min(Comparator)") - default @NotNull Option minOption(Comparator comparator) { - return isNotEmpty() ? Option.some(min(comparator)) : Option.none(); - } - - /** - * Folds this elements by apply {@code op}, starting with {@code zero}, unknown folding order. - * Because the implementation can specify the folding order freely, - * the {@code fold} function is usually more efficient than {@link #foldLeft} and {@link #foldRight}. - * - * @param zero the start value - * @param op the binary operator - * @return the folded value - */ - default T fold(T zero, @NotNull BiFunction op) { - Objects.requireNonNull(op); - return foldLeft(zero, op); - } - - /** - * Folds this elements by apply {@code op}, starting with {@code zero}, going left to right. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code op(...op(z, $1), $2, ..., $N)}. - * - * @param zero the start value - * @param op the binary operator - * @param the result type of the binary operator - * @return the folded value - */ - default U foldLeft(U zero, @NotNull BiFunction op) { - return Iterators.foldLeft(iterator(), zero, op); - } - - /** - * Folds this elements by apply {@code op}, starting with {@code zero}, going right to left. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code op($1, op($2, ... op($n, z)...))}. - * - * @param zero the start value - * @param op the binary operator - * @param the result type of the binary operator - * @return the folded value - */ - default U foldRight(U zero, @NotNull BiFunction op) { - return Iterators.foldRight(iterator(), zero, op); - } - - default T foldChecked( - T zero, @NotNull CheckedBiFunction op) throws Ex { - return fold(zero, op); - } - - default T foldUnchecked(T zero, @NotNull CheckedBiFunction op) { - return fold(zero, op); - } - - default U foldLeftChecked( - U zero, @NotNull CheckedBiFunction op) throws Ex { - return foldLeft(zero, op); - } - - default U foldLeftUnchecked(U zero, @NotNull CheckedBiFunction op) { - return foldLeft(zero, op); - } - - default U foldRightChecked( - U zero, @NotNull CheckedBiFunction op) throws Ex { - return foldRight(zero, op); - } - - default U foldRightUnchecked(U zero, @NotNull CheckedBiFunction op) { - return foldRight(zero, op); - } - - /** - * Reduces this elements by apply {@code op}. - * - * @param op the binary operator - * @return the reduced value - * @throws NoSuchElementException if this {@code Traversable} is empty - */ - default T reduce(@NotNull BiFunction op) { - return reduceLeft(op); - } - - default @Nullable T reduceOrNull(@NotNull BiFunction op) { - return reduceLeftOrNull(op); - } - - /** - * Reduces this elements by apply {@code op}. - * - * @param op the binary operator - * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Traversable} is empty - */ - default @NotNull Option reduceOption(@NotNull BiFunction op) { - return reduceLeftOption(op); - } - - /** - * Reduces this elements by apply {@code op}, going left to right. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code op( op( ... op($1, $2) ..., ${n-1}), $n)}. - * - * @param op the binary operator - * @return the reduced value - * @throws NoSuchElementException if this {@code Traversable} is empty - */ - default T reduceLeft(@NotNull BiFunction op) { - return Iterators.reduceLeft(iterator(), op); - } - - default @Nullable T reduceLeftOrNull(@NotNull BiFunction op) { - return this.isNotEmpty() ? reduceLeft(op) : null; - - } - - /** - * Reduces this elements by apply {@code op}, going left to right. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code Option.some(op( op( ... op($1, $2) ..., ${n-1}), $n))}. - * - * @param op the binary operator - * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Traversable} is empty - */ - default @NotNull Option reduceLeftOption(@NotNull BiFunction op) { - return this.isNotEmpty() ? Option.some(reduceLeft(op)) : Option.none(); - - } - - /** - * Reduces this elements by apply {@code op}, going right to left. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code op($1, op($2, ..., op(${n-1}, $n)...))}. - * - * @param op the binary operator - * @return the reduced value - * @throws NoSuchElementException if this {@code Traversable} is empty - */ - default T reduceRight(@NotNull BiFunction op) throws NoSuchElementException { - return Iterators.reduceRight(iterator(), op); - } - - default @Nullable T reduceRightOrNull(@NotNull BiFunction op) { - return this.isNotEmpty() ? reduceRight(op) : null; - } - - /** - * Reduces this elements by apply {@code op}, going right to left. - * - *

If this is a sequential container, use {@code $N} to refer to the Nth element, - * the return value of the function is {@code Option.some(op($1, op($2, ..., op(${n-1}, $n)...)))}. - * - * @param op the binary operator - * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Foldable} is empty - */ - default @NotNull Option reduceRightOption(@NotNull BiFunction op) { - return this.isNotEmpty() ? Option.some(reduceRight(op)) : Option.none(); - } - - default T reduceChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduce(op); - } - - default T reduceUnchecked(@NotNull CheckedBiFunction op) { - return reduce(op); - } - - default @Nullable T reduceOrNullChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceOrNull(op); - } - - default @Nullable T reduceOrNullUnchecked(@NotNull CheckedBiFunction op) { - return reduceOrNull(op); - } - - default @NotNull Option reduceOptionChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceOption(op); - } - - default @NotNull Option reduceOptionUnchecked(@NotNull CheckedBiFunction op) { - return reduceOption(op); - } - - default T reduceLeftChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceLeft(op); - } - - default T reduceLeftUnchecked(@NotNull CheckedBiFunction op) { - return reduceLeft(op); - } - - default @Nullable T reduceLeftOrNullChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceLeftOrNull(op); - } - - default @Nullable T reduceLeftOrNullUnchecked(@NotNull CheckedBiFunction op) { - return reduceLeftOrNull(op); - } - - default @NotNull Option reduceLeftOptionChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceLeftOption(op); - } - - default @NotNull Option reduceLeftOptionUnchecked(@NotNull CheckedBiFunction op) { - return reduceLeftOption(op); - } - - default T reduceRightChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceRight(op); - } - - default T reduceRightUnchecked(@NotNull CheckedBiFunction op) { - return reduceRight(op); - } - - default @Nullable T reduceRightOrNullChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceRightOrNull(op); - } - - default @Nullable T reduceRightOrNullUnchecked(@NotNull CheckedBiFunction op) { - return reduceRightOrNull(op); - } - - default @NotNull Option reduceRightOptionChecked( - @NotNull CheckedBiFunction op) throws Ex { - return reduceRightOption(op); - } - - default @NotNull Option reduceRightOptionUnchecked(@NotNull CheckedBiFunction op) { - return reduceRightOption(op); - } - - //endregion - - //region Copy Operations - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(Object @NotNull [] dest) { - return copyToArray(dest, 0, Integer.MAX_VALUE); - } - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(Object @NotNull [] dest, int destPos) { - return copyToArray(dest, destPos, Integer.MAX_VALUE); - } - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(Object @NotNull [] dest, int destPos, int limit) { - if (destPos < 0) { - throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); - } - - if (limit <= 0) { - return 0; - } - - final int dl = dest.length; //implicit null check of dest - if (destPos > dl) { - return 0; - } - - int end = Math.min(dl - destPos, limit) + destPos; - - Iterator it = this.iterator(); - - int idx = destPos; - while (it.hasNext() && idx < end) { - dest[idx++] = it.next(); - } - return idx - destPos; - } - - //endregion - - //region Conversion Operations - - @Override - @DelegateBy("toArray(IntFunction)") - default Object @NotNull [] toArray() { - return toArray(ObjectArrays.generator()); - } - - @DelegateBy("toArray(IntFunction)") - default U @NotNull [] toArray(@NotNull Class type) { - return toArray(GenericArrays.generator(type)); - } - - default U @NotNull [] toArray(@NotNull IntFunction generator) { - int s = knownSize(); - if (s == 0) { - return generator.apply(0); - } else if (s > 0) { - U[] arr = generator.apply(s); - this.copyToArray(arr); - return arr; - } else { - return Iterators.toArray((Iterator) iterator(), generator); - } - } - - /** - * @see Collection#toArray(Object[]) - */ - default U @NotNull [] toArray(U @NotNull [] array) { - final int size = this.size(); - final int arrayLength = array.length; - U[] res; - if (arrayLength > size) { - res = array; - } else { - res = (U[]) GenericArrays.create(array.getClass().getComponentType(), size); - } - - Iterator it = iterator(); - for (int i = 0; i < res.length; i++) { - if (it.hasNext()) { - res[i] = (U) it.next(); - } else { - if (arrayLength > size) { - res[i] = null; - } else if (arrayLength < i) { - return Arrays.copyOf(res, i); - } else { - System.arraycopy(res, 0, array, 0, i); - if (arrayLength > i) { - array[i] = null; - } - } - return array; - } - } - if (it.hasNext()) { - throw new ConcurrentModificationException(); - } - return res; - } - - //endregion - - //region Traverse Operations - - @Override - default void forEach(@NotNull Consumer action) { - Objects.requireNonNull(action); - for (T t : this) { - action.accept(t); - } - } - - @DelegateBy("forEach(Consumer)") - default void forEachChecked(@NotNull CheckedConsumer action) throws Ex { - forEach(action); - } - - @DelegateBy("forEach(Consumer)") - default void forEachUnchecked(@NotNull CheckedConsumer action) { - forEach(action); - } - - default void forEachBreakable(@NotNull Predicate action) { - Objects.requireNonNull(action); - for (T t : this) { - if (!action.test(t)) { - break; - } - } - } - - @DelegateBy("forEachBreakable(Predicate)") - default void forEachBreakableChecked( - @NotNull CheckedPredicate action) throws Ex { - forEachBreakable(action); - } - - @DelegateBy("forEachBreakable(Predicate)") - default void forEachBreakableUnchecked(@NotNull CheckedPredicate action) { - forEachBreakable(action); - } - - default void forEachParallel(@NotNull Consumer action) { - forEachParallel(action, ConcurrentScope.currentExecutor(), Granularity.DEFAULT); - } - - default void forEachParallel(@NotNull Consumer action, Granularity granularity) { - forEachParallel(action, ConcurrentScope.currentExecutor(), granularity); - } - - default void forEachParallel(@NotNull Consumer action, @NotNull Executor executor) { - forEachParallel(action, executor, Granularity.DEFAULT); - } - - default void forEachParallel( - @NotNull Consumer action, @NotNull Executor executor, @NotNull Granularity granularity) { - try { - forEachAsync(action, executor, granularity).get(); - } catch (InterruptedException | ExecutionException ignored) { - } - } - - default @NotNull Future forEachAsync(@NotNull Consumer action) { - return forEachAsync(action, ConcurrentScope.currentExecutor(), Granularity.DEFAULT); - } - - default @NotNull Future forEachAsync(@NotNull Consumer action, @NotNull Executor executor) { - return forEachAsync(action, executor, Granularity.DEFAULT); - } - - default @NotNull Future forEachAsync(@NotNull Consumer action, Granularity granularity) { - return forEachAsync(action, ConcurrentScope.currentExecutor(), granularity); - } - - default @NotNull Future forEachAsync( - @NotNull Consumer action, @NotNull Executor executor, @NotNull Granularity granularity) { - if (granularity != Granularity.ATOM && executor instanceof ForkJoinPool) { - return ((ForkJoinPool) executor).submit(() -> parallelStream().forEach(action), null); - } else { - LateInitCountDownLatch latch = new LateInitCountDownLatch(); - IntVar count = new IntVar(); - forEach(value -> { - count.increment(); - executor.execute(() -> { - try { - action.accept(value); - } catch (Throwable ignored) { - } finally { - latch.countDown(); - } - }); - }); - latch.init(count.value); - return latch.awaitFuture(); - } - } - - default void forEachWith(@NotNull Iterable other, @NotNull BiConsumer action) { - Iterators.forEachWith(this.iterator(), other.iterator(), action); - } - - @ApiStatus.NonExtendable - @DelegateBy("forEachWith(Iterable, BiConsumer)") - default void forEachWithChecked(@NotNull Iterable other, - @NotNull CheckedBiConsumer action) throws Ex { - forEachWith(other, action); - } - - @ApiStatus.NonExtendable - @DelegateBy("forEachWith(Iterable, BiConsumer)") - default void forEachWithUnchecked(@NotNull Iterable other, - @NotNull CheckedBiConsumer action) { - forEachWith(other, action); - } - - default void forEachCross(@NotNull Iterable other, @NotNull BiConsumer action) { - Objects.requireNonNull(other); - Objects.requireNonNull(action); - - for (T value1 : this) { - for (U value2 : other) { - action.accept(value1, value2); - } - } - } - - @ApiStatus.NonExtendable - @DelegateBy("forEachCross(Iterable, BiConsumer)") - default void forEachCrossChecked(@NotNull Iterable other, - @NotNull CheckedBiConsumer action) throws Ex { - forEachCross(other, action); - } - - @ApiStatus.NonExtendable - @DelegateBy("forEachCross(Iterable, BiConsumer)") - default void forEachCrossUnchecked(@NotNull Iterable other, - @NotNull CheckedBiConsumer action) { - forEachCross(other, action); - } - - //endregion - - //region String Representation - - @Contract(value = "_, _, _, _ -> param1", mutates = "param1") - default @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix - ) { - if (knownSize() == 0) { - try { - buffer.append(prefix).append(postfix); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return buffer; - } else { - return Iterators.joinTo(iterator(), buffer, separator, prefix, postfix); - } - } - - default @NotNull A joinTo(@NotNull A buffer, @NotNull Function transform) { - return joinTo(buffer, ", ", transform); - } - - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, @NotNull Function transform) { - return joinTo(buffer, separator, "", "", transform); - } - - @Contract(value = "_, _, _, _, _ -> param1", mutates = "param1") - default @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix, - @NotNull Function transform - ) { - if (knownSize() == 0) { - try { - buffer.append(prefix).append(postfix); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return buffer; - } else { - return Iterators.joinTo(iterator(), buffer, separator, prefix, postfix, transform); - } - } - - default @NotNull String joinToString(@NotNull Function transform) { - return joinTo(new StringBuilder(), transform).toString(); - } - - default @NotNull String joinToString(CharSequence separator, @NotNull Function transform) { - return joinTo(new StringBuilder(), separator, transform).toString(); - } - - default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix, @NotNull Function transform) { - return joinTo(new StringBuilder(), separator, prefix, postfix, transform).toString(); - } - - //endregion -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base; + +import kala.annotations.Covariant; +import kala.annotations.DelegateBy; +import kala.collection.base.primitive.*; +import kala.collection.factory.CollectionBuilder; +import kala.collection.factory.primitive.*; +import kala.comparator.Comparators; +import kala.concurrent.Granularity; +import kala.concurrent.ConcurrentScope; +import kala.concurrent.LateInitCountDownLatch; +import kala.control.Option; +import kala.collection.factory.CollectionFactory; +import kala.function.*; +import kala.tuple.Tuple; +import kala.tuple.Tuple2; +import kala.value.primitive.IntVar; +import org.intellij.lang.annotations.Flow; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; +import java.util.stream.*; + +@FunctionalInterface +@SuppressWarnings("unchecked") +public interface Traversable<@Covariant T> extends Iterable, AnyTraversable { + + @SuppressWarnings("unchecked") + @Contract(value = "_ -> param1", pure = true) + static @NotNull Traversable narrow(Traversable traversable) { + return (Traversable) traversable; + } + + static @NotNull Traversable wrap(@NotNull Iterable iterable) { + Objects.requireNonNull(iterable); + + if (iterable instanceof Traversable) { + return narrow((Traversable) iterable); + } + + return ofSupplier(iterable::iterator); + } + + static @NotNull Traversable ofSupplier(@NotNull Supplier> supplier) { + Objects.requireNonNull(supplier); + return new Traversable<>() { + @Override + public @NotNull Iterator iterator() { + return Iterators.narrow(supplier.get()); + } + + @Override + public String toString() { + return joinToString(", ", "Traversable[", "]"); + } + }; + } + + default @NotNull Traversable asGeneric() { + return this; + } + + @NotNull Iterator iterator(); + + @Override + default Spliterator spliterator() { + return AnyTraversable.super.spliterator(); + } + + /// Returns a sequential [Stream] with this as its source. + /// + /// @return a sequential [Stream] over the elements in this `Traversable` + @Override + default @NotNull Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + /** + * Returns a possibly parallel {@code Stream} with this as its source. + * It is allowable for this method to return a sequential stream. + * + * @return a possibly parallel {@code Stream} over the elements in this + */ + @Override + default @NotNull Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + default T elementAt(int index) { + final Iterator it = this.iterator(); + for (int i = 0; i < index; i++) { + if (it.hasNext()) { + it.next(); + } else { + throw new IndexOutOfBoundsException("index: " + index); + } + } + if (it.hasNext()) { + return it.next(); + } else { + throw new IndexOutOfBoundsException("index: " + index); + } + } + + default T getAny() { + return iterator().next(); + } + + default @Nullable T getAnyOrNull() { + return isNotEmpty() ? getAny() : null; + } + + default @NotNull Option getAnyOption() { + return isNotEmpty() ? Option.some(getAny()) : Option.none(); + } + + //region Element Retrieval Operations + + default @NotNull Option find(@NotNull Predicate predicate) { + for (T t : this) { + if (predicate.test(t)) { + return Option.some(t); + } + } + return Option.none(); + } + + //endregion + + //region Element Conditions + + default boolean contains(Object value) { + return Iterators.contains(iterator(), value); + } + + default boolean containsAll(Object @NotNull [] values) { + for (Object value : values) { + if (!contains(value)) { + return false; + } + } + return true; + } + + //@Override + default boolean containsAll(@NotNull Iterable values) { + for (Object value : values) { + if (!contains(value)) { + return false; + } + } + return true; + } + + default boolean sameElements(@NotNull Iterable other) { + return Iterators.sameElements(iterator(), other.iterator()); + } + + default boolean sameElements(@NotNull Iterable other, boolean identity) { + if (!identity) { + return sameElements(other); + } else { + return Iterators.sameElements(iterator(), other.iterator(), true); + } + } + + /** + * Tests whether any element of this {@code Traversable} match the {@code predicate}. + * + * @return {@code true} if either any element of this {@code Traversable} match the {@code predicate}, + * otherwise {@code false} + */ + default boolean anyMatch(@NotNull Predicate predicate) { + return Iterators.anyMatch(iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean anyMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { + return anyMatch(predicate); + } + + @ApiStatus.NonExtendable + default boolean anyMatchUnchecked(@NotNull CheckedPredicate predicate) { + return anyMatch(predicate); + } + + /** + * Tests whether all elements of this {@code Traversable} match the {@code predicate}. + * + * @return {@code true} if either all elements of this {@code Traversable} match the {@code predicate} or + * the {@code Traversable} is empty, otherwise {@code false} + */ + default boolean allMatch(@NotNull Predicate predicate) { + return Iterators.allMatch(iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean allMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { + return allMatch(predicate); + } + + @ApiStatus.NonExtendable + default boolean allMatchUnchecked(@NotNull CheckedPredicate predicate) { + return allMatch(predicate); + } + + /** + * Tests whether none elements of this {@code Traversable} match the {@code predicate}. + * + * @return {@code true} if either none elements of this {@code Traversable} match the {@code predicate} or + * the {@code Traversable} is empty, otherwise {@code false} + */ + default boolean noneMatch(@NotNull Predicate predicate) { + return Iterators.noneMatch(iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean noneMatchChecked(@NotNull CheckedPredicate predicate) throws Ex { + return noneMatch(predicate); + } + + @ApiStatus.NonExtendable + default boolean noneMatchUnchecked(@NotNull CheckedPredicate predicate) { + return noneMatch(predicate); + } + + /** + * Equivalent to {@code this.zip(other).anyMatch(it -> predicate.test(it._1, it._2))} + */ + default boolean anyMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { + return Iterators.anyMatchWith(iterator(), other.iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean anyMatchWithChecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) throws Ex { + return anyMatchWith(other, predicate); + } + + @ApiStatus.NonExtendable + default boolean anyMatchWithUnchecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) { + return anyMatchWith(other, predicate); + } + + /** + * Equivalent to {@code this.zip(other).allMatch(it -> predicate.test(it._1, it._2))} + */ + default boolean allMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { + return Iterators.allMatchWith(iterator(), other.iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean allMatchWithChecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) throws Ex { + return allMatchWith(other, predicate); + } + + @ApiStatus.NonExtendable + default boolean allMatchWithUnchecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) { + return allMatchWith(other, predicate); + } + + /** + * Equivalent to {@code this.zip(other).noneMatch(it -> predicate.test(it._1, it._2))} + */ + default boolean noneMatchWith(@NotNull Iterable other, @NotNull BiPredicate predicate) { + return Iterators.noneMatchWith(iterator(), other.iterator(), predicate); + } + + @ApiStatus.NonExtendable + default boolean noneMatchWithChecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) throws Ex { + return noneMatchWith(other, predicate); + } + + @ApiStatus.NonExtendable + default boolean noneMatchWithUnchecked( + @NotNull Iterable other, + @NotNull CheckedBiPredicate predicate) { + return noneMatchWith(other, predicate); + } + + //endregion + + @DelegateBy("filterTo(Growable, Predicate)") + default R filter(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { + return filterTo(factory.newCollectionBuilder(), predicate).build(); + } + + @DelegateBy("filterNotTo(Growable, Predicate)") + default R filterNot(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { + return filterNotTo(factory.newCollectionBuilder(), predicate).build(); + } + + @DelegateBy("filterNotNullTo(Growable)") + default R filterNotNull(@NotNull CollectionFactory factory) { + return filterNotNullTo(factory.newCollectionBuilder()).build(); + } + + @DelegateBy("filterIsInstanceTo(Growable, Class)") + default R filterIsInstance(@NotNull CollectionFactory factory, Class clazz) { + return filterIsInstanceTo(factory.newCollectionBuilder(), clazz).build(); + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G filterTo(@NotNull G destination, @NotNull Predicate predicate) { + for (T e : this) { + if (predicate.test(e)) { + destination.plusAssign(e); + } + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G filterNotTo(@NotNull G destination, @NotNull Predicate predicate) { + for (T e : this) { + if (!predicate.test(e)) { + destination.plusAssign(e); + } + } + return destination; + } + + @Contract(value = "_ -> param1", mutates = "param1") + default > @NotNull G filterNotNullTo(@NotNull G destination) { + for (T e : this) { + if (e != null) { + destination.plusAssign(e); + } + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G filterIsInstanceTo(@NotNull G destination, @NotNull Class clazz) { + for (T value : this) { + if (clazz.isInstance(value)) { + destination.plusAssign((U) value); + } + } + return destination; + } + + @DelegateBy("mapTo(Growable, Function)") + default R map(@NotNull CollectionFactory factory, @NotNull Function mapper) { + return mapTo(factory.newCollectionBuilder(knownSize()), mapper).build(); + } + + default R mapToInt(@NotNull IntCollectionFactory factory, @NotNull ToIntFunction mapper) { + return IntCollectionFactory.buildBy(factory, consumer -> { + for (T e : this) { + consumer.accept(mapper.applyAsInt(e)); + } + }); + } + + default R mapToLong(@NotNull LongCollectionFactory factory, @NotNull ToLongFunction mapper) { + return LongCollectionFactory.buildBy(factory, consumer -> { + for (T e : this) { + consumer.accept(mapper.applyAsLong(e)); + } + }); + } + + default R mapToDouble(@NotNull DoubleCollectionFactory factory, @NotNull ToDoubleFunction mapper) { + return DoubleCollectionFactory.buildBy(factory, consumer -> { + for (T e : this) { + consumer.accept(mapper.applyAsDouble(e)); + } + }); + } + + default R mapToChar(@NotNull CharCollectionFactory factory, @NotNull ToCharFunction mapper) { + return CharCollectionFactory.buildBy(factory, consumer -> { + for (T e : this) { + consumer.accept(mapper.applyAsChar(e)); + } + }); + } + + default R mapToBoolean(@NotNull BooleanCollectionFactory factory, @NotNull ToBooleanFunction mapper) { + return BooleanCollectionFactory.buildBy(factory, consumer -> { + for (T e : this) { + consumer.accept(mapper.applyAsBoolean(e)); + } + }); + } + + @DelegateBy("mapNotNullTo(Growable, Function)") + default R mapNotNull(@NotNull CollectionFactory factory, @NotNull Function mapper) { + return mapNotNullTo(factory.newCollectionBuilder(knownSize()), mapper).build(); + } + + default @NotNull R mapMulti( + @NotNull CollectionFactory factory, + @NotNull BiConsumer> mapper) { + return mapMultiTo(factory.newCollectionBuilder(), mapper).build(); + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G mapTo(@NotNull G destination, @NotNull Function mapper) { + for (T e : this) { + destination.plusAssign(mapper.apply(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapToIntTo(@NotNull G destination, @NotNull ToIntFunction mapper) { + for (T e : this) { + destination.plusAssign(mapper.applyAsInt(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapToLongTo(@NotNull G destination, @NotNull ToLongFunction mapper) { + for (T e : this) { + destination.plusAssign(mapper.applyAsLong(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapToDoubleTo(@NotNull G destination, @NotNull ToDoubleFunction mapper) { + for (T e : this) { + destination.plusAssign(mapper.applyAsDouble(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapToCharTo(@NotNull G destination, @NotNull ToCharFunction mapper) { + for (T e : this) { + destination.plusAssign(mapper.applyAsChar(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapToBooleanTo(@NotNull G destination, @NotNull ToBooleanFunction mapper) { + for (T e : this) { + destination.plusAssign(mapper.applyAsBoolean(e)); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G mapNotNullTo( + @NotNull G destination, + @NotNull Function mapper) { + for (T e : this) { + U u = mapper.apply(e); + if (u != null) { + destination.plusAssign(u); + } + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull > G mapMultiTo( + @NotNull G destination, + @NotNull BiConsumer> mapper) { + + Consumer consumer = destination instanceof CollectionBuilder + ? ((CollectionBuilder) destination) + : destination::plusAssign; + + for (T value : this) { + mapper.accept(value, consumer); + } + return destination; + } + + @DelegateBy("flatMapTo(Growable, Function>)") + default @NotNull R flatMap( + @NotNull CollectionFactory factory, + @NotNull Function> mapper) { + return flatMapTo(factory.newCollectionBuilder(), mapper).build(); + } + + @DelegateBy("flatMapToIntTo(IntGrowable, Function)") + default @NotNull R flatMapToInt( + @NotNull IntCollectionFactory factory, + @NotNull Function mapper) { + return flatMapToIntTo(factory.newCollectionBuilder(), mapper).build(); + } + + @DelegateBy("flatMapToLongTo(LongGrowable, Function)") + default @NotNull R flatMapToLong( + @NotNull LongCollectionFactory factory, + @NotNull Function mapper) { + return flatMapToLongTo(factory.newCollectionBuilder(), mapper).build(); + } + + @DelegateBy("flatMapToDoubleTo(DoubleGrowable, Function)") + default @NotNull R flatMapToDouble( + @NotNull DoubleCollectionFactory factory, + @NotNull Function mapper) { + return flatMapToDoubleTo(factory.newCollectionBuilder(), mapper).build(); + } + + default > G flatMapTo( + @NotNull G destination, + @NotNull Function> mapper) { + for (T value : this) { + destination.plusAssign(mapper.apply(value)); + } + + return destination; + } + + default G flatMapToIntTo( + @NotNull G destination, + @NotNull Function mapper) { + for (T value : this) { + destination.plusAssign(mapper.apply(value)); + } + return destination; + } + + default G flatMapToLongTo( + @NotNull G destination, + @NotNull Function mapper) { + for (T value : this) { + destination.plusAssign(mapper.apply(value)); + } + return destination; + } + + default G flatMapToDoubleTo( + @NotNull G destination, + @NotNull Function mapper) { + for (T value : this) { + destination.plusAssign(mapper.apply(value)); + } + return destination; + } + + default Tuple2 partition(@NotNull CollectionFactory factory, @NotNull Predicate predicate) { + @SuppressWarnings("rawtypes") + CollectionFactory uncheckedFactory = factory; + + Object builder1 = uncheckedFactory.newBuilder(); + Object builder2 = uncheckedFactory.newBuilder(); + + for (T e : this) { + Object builder = predicate.test(e) ? builder1 : builder2; + uncheckedFactory.addToBuilder(builder, e); + } + + return Tuple.of((R) uncheckedFactory.build(builder1), (R) uncheckedFactory.build(builder2)); + } + + @DelegateBy("distinctTo(Growable)") + default R distinct(@NotNull CollectionFactory factory) { + return distinctTo(factory.newCollectionBuilder()).build(); + } + + @DelegateBy("distinctByTo(Growable, Function)") + default R distinctBy(@NotNull CollectionFactory factory, Function mapper) { + return distinctByTo(factory.newCollectionBuilder(), mapper).build(); + } + + @DelegateBy("distinctByIntTo(Growable, ToIntFunction)") + default R distinctByInt(@NotNull CollectionFactory factory, ToIntFunction mapper) { + return distinctByIntTo(factory.newCollectionBuilder(), mapper).build(); + } + + default > @NotNull G distinctTo(G destination) { + HashSet iteratedValues = new HashSet<>(); + for (T value : this) { + if (iteratedValues.add(value)) { + destination.plusAssign(value); + } + } + return destination; + } + + default > @NotNull G distinctByTo(G destination, Function mapper) { + HashSet iteratedValues = new HashSet<>(); + for (T value : this) { + if (iteratedValues.add(mapper.apply(value))) { + destination.plusAssign(value); + } + } + return destination; + } + + default > @NotNull G distinctByIntTo(G destination, ToIntFunction mapper) { + HashSet iteratedValues = new HashSet<>(); // TODO + for (T value : this) { + if (iteratedValues.add(mapper.applyAsInt(value))) { + destination.plusAssign(value); + } + } + return destination; + } + + //region Aggregate Operations + + default int count(@NotNull Predicate predicate) { + return Iterators.count(iterator(), predicate); + } + + @DelegateBy("max(Comparator)") + default T max() { + return max(Comparators.naturalOrder()); + } + + default T max(Comparator comparator) { + if (isEmpty()) throw new NoSuchElementException(); + + return Iterators.max(iterator(), comparator); + } + + @DelegateBy("max()") + default @Nullable T maxOrNull() { + return isNotEmpty() ? max() : null; + } + + @DelegateBy("max(Comparator)") + default @Nullable T maxOrNull(@NotNull Comparator comparator) { + return isNotEmpty() ? max(comparator) : null; + } + + @DelegateBy("max()") + default @NotNull Option maxOption() { + return isNotEmpty() ? Option.some(max()) : Option.none(); + } + + @DelegateBy("max(Comparator)") + default @NotNull Option maxOption(Comparator comparator) { + return isNotEmpty() ? Option.some(max(comparator)) : Option.none(); + } + + @DelegateBy("min(Comparator)") + default T min() { + return min(Comparators.naturalOrder()); + } + + default T min(Comparator comparator) { + if (isEmpty()) throw new NoSuchElementException(); + + return Iterators.min(iterator(), comparator); + } + + @DelegateBy("min()") + default @Nullable T minOrNull() { + return isNotEmpty() ? min() : null; + } + + @DelegateBy("min(Comparator)") + default @Nullable T minOrNull(@NotNull Comparator comparator) { + return isNotEmpty() ? min(comparator) : null; + } + + @DelegateBy("min()") + default @NotNull Option minOption() { + return isNotEmpty() ? Option.some(min()) : Option.none(); + } + + @DelegateBy("min(Comparator)") + default @NotNull Option minOption(Comparator comparator) { + return isNotEmpty() ? Option.some(min(comparator)) : Option.none(); + } + + /** + * Folds this elements by apply {@code op}, starting with {@code zero}, unknown folding order. + * Because the implementation can specify the folding order freely, + * the {@code fold} function is usually more efficient than {@link #foldLeft} and {@link #foldRight}. + * + * @param zero the start value + * @param op the binary operator + * @return the folded value + */ + default T fold(T zero, @NotNull BiFunction op) { + Objects.requireNonNull(op); + return foldLeft(zero, op); + } + + /** + * Folds this elements by apply {@code op}, starting with {@code zero}, going left to right. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code op(...op(z, $1), $2, ..., $N)}. + * + * @param zero the start value + * @param op the binary operator + * @param the result type of the binary operator + * @return the folded value + */ + default U foldLeft(U zero, @NotNull BiFunction op) { + return Iterators.foldLeft(iterator(), zero, op); + } + + /** + * Folds this elements by apply {@code op}, starting with {@code zero}, going right to left. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code op($1, op($2, ... op($n, z)...))}. + * + * @param zero the start value + * @param op the binary operator + * @param the result type of the binary operator + * @return the folded value + */ + default U foldRight(U zero, @NotNull BiFunction op) { + return Iterators.foldRight(iterator(), zero, op); + } + + default T foldChecked( + T zero, @NotNull CheckedBiFunction op) throws Ex { + return fold(zero, op); + } + + default T foldUnchecked(T zero, @NotNull CheckedBiFunction op) { + return fold(zero, op); + } + + default U foldLeftChecked( + U zero, @NotNull CheckedBiFunction op) throws Ex { + return foldLeft(zero, op); + } + + default U foldLeftUnchecked(U zero, @NotNull CheckedBiFunction op) { + return foldLeft(zero, op); + } + + default U foldRightChecked( + U zero, @NotNull CheckedBiFunction op) throws Ex { + return foldRight(zero, op); + } + + default U foldRightUnchecked(U zero, @NotNull CheckedBiFunction op) { + return foldRight(zero, op); + } + + /** + * Reduces this elements by apply {@code op}. + * + * @param op the binary operator + * @return the reduced value + * @throws NoSuchElementException if this {@code Traversable} is empty + */ + default T reduce(@NotNull BiFunction op) { + return reduceLeft(op); + } + + default @Nullable T reduceOrNull(@NotNull BiFunction op) { + return reduceLeftOrNull(op); + } + + /** + * Reduces this elements by apply {@code op}. + * + * @param op the binary operator + * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Traversable} is empty + */ + default @NotNull Option reduceOption(@NotNull BiFunction op) { + return reduceLeftOption(op); + } + + /** + * Reduces this elements by apply {@code op}, going left to right. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code op( op( ... op($1, $2) ..., ${n-1}), $n)}. + * + * @param op the binary operator + * @return the reduced value + * @throws NoSuchElementException if this {@code Traversable} is empty + */ + default T reduceLeft(@NotNull BiFunction op) { + return Iterators.reduceLeft(iterator(), op); + } + + default @Nullable T reduceLeftOrNull(@NotNull BiFunction op) { + return this.isNotEmpty() ? reduceLeft(op) : null; + + } + + /** + * Reduces this elements by apply {@code op}, going left to right. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code Option.some(op( op( ... op($1, $2) ..., ${n-1}), $n))}. + * + * @param op the binary operator + * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Traversable} is empty + */ + default @NotNull Option reduceLeftOption(@NotNull BiFunction op) { + return this.isNotEmpty() ? Option.some(reduceLeft(op)) : Option.none(); + + } + + /** + * Reduces this elements by apply {@code op}, going right to left. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code op($1, op($2, ..., op(${n-1}, $n)...))}. + * + * @param op the binary operator + * @return the reduced value + * @throws NoSuchElementException if this {@code Traversable} is empty + */ + default T reduceRight(@NotNull BiFunction op) throws NoSuchElementException { + return Iterators.reduceRight(iterator(), op); + } + + default @Nullable T reduceRightOrNull(@NotNull BiFunction op) { + return this.isNotEmpty() ? reduceRight(op) : null; + } + + /** + * Reduces this elements by apply {@code op}, going right to left. + * + *

If this is a sequential container, use {@code $N} to refer to the Nth element, + * the return value of the function is {@code Option.some(op($1, op($2, ..., op(${n-1}, $n)...)))}. + * + * @param op the binary operator + * @return an {@code Option} contain the reduced value or a empty {@code Option} if the {@code Foldable} is empty + */ + default @NotNull Option reduceRightOption(@NotNull BiFunction op) { + return this.isNotEmpty() ? Option.some(reduceRight(op)) : Option.none(); + } + + default T reduceChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduce(op); + } + + default T reduceUnchecked(@NotNull CheckedBiFunction op) { + return reduce(op); + } + + default @Nullable T reduceOrNullChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceOrNull(op); + } + + default @Nullable T reduceOrNullUnchecked(@NotNull CheckedBiFunction op) { + return reduceOrNull(op); + } + + default @NotNull Option reduceOptionChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceOption(op); + } + + default @NotNull Option reduceOptionUnchecked(@NotNull CheckedBiFunction op) { + return reduceOption(op); + } + + default T reduceLeftChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceLeft(op); + } + + default T reduceLeftUnchecked(@NotNull CheckedBiFunction op) { + return reduceLeft(op); + } + + default @Nullable T reduceLeftOrNullChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceLeftOrNull(op); + } + + default @Nullable T reduceLeftOrNullUnchecked(@NotNull CheckedBiFunction op) { + return reduceLeftOrNull(op); + } + + default @NotNull Option reduceLeftOptionChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceLeftOption(op); + } + + default @NotNull Option reduceLeftOptionUnchecked(@NotNull CheckedBiFunction op) { + return reduceLeftOption(op); + } + + default T reduceRightChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceRight(op); + } + + default T reduceRightUnchecked(@NotNull CheckedBiFunction op) { + return reduceRight(op); + } + + default @Nullable T reduceRightOrNullChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceRightOrNull(op); + } + + default @Nullable T reduceRightOrNullUnchecked(@NotNull CheckedBiFunction op) { + return reduceRightOrNull(op); + } + + default @NotNull Option reduceRightOptionChecked( + @NotNull CheckedBiFunction op) throws Ex { + return reduceRightOption(op); + } + + default @NotNull Option reduceRightOptionUnchecked(@NotNull CheckedBiFunction op) { + return reduceRightOption(op); + } + + //endregion + + //region Copy Operations + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(Object @NotNull [] dest) { + return copyToArray(dest, 0, Integer.MAX_VALUE); + } + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(Object @NotNull [] dest, int destPos) { + return copyToArray(dest, destPos, Integer.MAX_VALUE); + } + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(Object @NotNull [] dest, int destPos, int limit) { + if (destPos < 0) { + throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); + } + + if (limit <= 0) { + return 0; + } + + final int dl = dest.length; //implicit null check of dest + if (destPos > dl) { + return 0; + } + + int end = Math.min(dl - destPos, limit) + destPos; + + Iterator it = this.iterator(); + + int idx = destPos; + while (it.hasNext() && idx < end) { + dest[idx++] = it.next(); + } + return idx - destPos; + } + + //endregion + + //region Conversion Operations + + @Override + @DelegateBy("toArray(IntFunction)") + default Object @NotNull [] toArray() { + return toArray(ObjectArrays.generator()); + } + + @DelegateBy("toArray(IntFunction)") + default U @NotNull [] toArray(@NotNull Class type) { + return toArray(GenericArrays.generator(type)); + } + + default U @NotNull [] toArray(@NotNull IntFunction generator) { + int s = knownSize(); + if (s == 0) { + return generator.apply(0); + } else if (s > 0) { + U[] arr = generator.apply(s); + this.copyToArray(arr); + return arr; + } else { + return Iterators.toArray((Iterator) iterator(), generator); + } + } + + /** + * @see Collection#toArray(Object[]) + */ + default U @NotNull [] toArray(U @NotNull [] array) { + final int size = this.size(); + final int arrayLength = array.length; + U[] res; + if (arrayLength > size) { + res = array; + } else { + res = (U[]) GenericArrays.create(array.getClass().getComponentType(), size); + } + + Iterator it = iterator(); + for (int i = 0; i < res.length; i++) { + if (it.hasNext()) { + res[i] = (U) it.next(); + } else { + if (arrayLength > size) { + res[i] = null; + } else if (arrayLength < i) { + return Arrays.copyOf(res, i); + } else { + System.arraycopy(res, 0, array, 0, i); + if (arrayLength > i) { + array[i] = null; + } + } + return array; + } + } + if (it.hasNext()) { + throw new ConcurrentModificationException(); + } + return res; + } + + //endregion + + //region Traverse Operations + + @Override + default void forEach(@NotNull Consumer action) { + Objects.requireNonNull(action); + for (T t : this) { + action.accept(t); + } + } + + @DelegateBy("forEach(Consumer)") + default void forEachChecked(@NotNull CheckedConsumer action) throws Ex { + forEach(action); + } + + @DelegateBy("forEach(Consumer)") + default void forEachUnchecked(@NotNull CheckedConsumer action) { + forEach(action); + } + + default void forEachBreakable(@NotNull Predicate action) { + Objects.requireNonNull(action); + for (T t : this) { + if (!action.test(t)) { + break; + } + } + } + + @DelegateBy("forEachBreakable(Predicate)") + default void forEachBreakableChecked( + @NotNull CheckedPredicate action) throws Ex { + forEachBreakable(action); + } + + @DelegateBy("forEachBreakable(Predicate)") + default void forEachBreakableUnchecked(@NotNull CheckedPredicate action) { + forEachBreakable(action); + } + + default void forEachParallel(@NotNull Consumer action) { + forEachParallel(action, ConcurrentScope.currentExecutor(), Granularity.DEFAULT); + } + + default void forEachParallel(@NotNull Consumer action, Granularity granularity) { + forEachParallel(action, ConcurrentScope.currentExecutor(), granularity); + } + + default void forEachParallel(@NotNull Consumer action, @NotNull Executor executor) { + forEachParallel(action, executor, Granularity.DEFAULT); + } + + default void forEachParallel( + @NotNull Consumer action, @NotNull Executor executor, @NotNull Granularity granularity) { + try { + forEachAsync(action, executor, granularity).get(); + } catch (InterruptedException | ExecutionException ignored) { + } + } + + default @NotNull Future forEachAsync(@NotNull Consumer action) { + return forEachAsync(action, ConcurrentScope.currentExecutor(), Granularity.DEFAULT); + } + + default @NotNull Future forEachAsync(@NotNull Consumer action, @NotNull Executor executor) { + return forEachAsync(action, executor, Granularity.DEFAULT); + } + + default @NotNull Future forEachAsync(@NotNull Consumer action, Granularity granularity) { + return forEachAsync(action, ConcurrentScope.currentExecutor(), granularity); + } + + default @NotNull Future forEachAsync( + @NotNull Consumer action, @NotNull Executor executor, @NotNull Granularity granularity) { + if (granularity != Granularity.ATOM && executor instanceof ForkJoinPool) { + return ((ForkJoinPool) executor).submit(() -> parallelStream().forEach(action), null); + } else { + LateInitCountDownLatch latch = new LateInitCountDownLatch(); + IntVar count = new IntVar(); + forEach(value -> { + count.increment(); + executor.execute(() -> { + try { + action.accept(value); + } catch (Throwable ignored) { + } finally { + latch.countDown(); + } + }); + }); + latch.init(count.value); + return latch.awaitFuture(); + } + } + + default void forEachWith(@NotNull Iterable other, @NotNull BiConsumer action) { + Iterators.forEachWith(this.iterator(), other.iterator(), action); + } + + @ApiStatus.NonExtendable + @DelegateBy("forEachWith(Iterable, BiConsumer)") + default void forEachWithChecked(@NotNull Iterable other, + @NotNull CheckedBiConsumer action) throws Ex { + forEachWith(other, action); + } + + @ApiStatus.NonExtendable + @DelegateBy("forEachWith(Iterable, BiConsumer)") + default void forEachWithUnchecked(@NotNull Iterable other, + @NotNull CheckedBiConsumer action) { + forEachWith(other, action); + } + + default void forEachCross(@NotNull Iterable other, @NotNull BiConsumer action) { + Objects.requireNonNull(other); + Objects.requireNonNull(action); + + for (T value1 : this) { + for (U value2 : other) { + action.accept(value1, value2); + } + } + } + + @ApiStatus.NonExtendable + @DelegateBy("forEachCross(Iterable, BiConsumer)") + default void forEachCrossChecked(@NotNull Iterable other, + @NotNull CheckedBiConsumer action) throws Ex { + forEachCross(other, action); + } + + @ApiStatus.NonExtendable + @DelegateBy("forEachCross(Iterable, BiConsumer)") + default void forEachCrossUnchecked(@NotNull Iterable other, + @NotNull CheckedBiConsumer action) { + forEachCross(other, action); + } + + //endregion + + //region String Representation + + @Contract(value = "_, _, _, _ -> param1", mutates = "param1") + default @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix + ) { + if (knownSize() == 0) { + try { + buffer.append(prefix).append(postfix); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return buffer; + } else { + return Iterators.joinTo(iterator(), buffer, separator, prefix, postfix); + } + } + + default @NotNull A joinTo(@NotNull A buffer, @NotNull Function transform) { + return joinTo(buffer, ", ", transform); + } + + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, @NotNull Function transform) { + return joinTo(buffer, separator, "", "", transform); + } + + @Contract(value = "_, _, _, _, _ -> param1", mutates = "param1") + default @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix, + @NotNull Function transform + ) { + if (knownSize() == 0) { + try { + buffer.append(prefix).append(postfix); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return buffer; + } else { + return Iterators.joinTo(iterator(), buffer, separator, prefix, postfix, transform); + } + } + + default @NotNull String joinToString(@NotNull Function transform) { + return joinTo(new StringBuilder(), transform).toString(); + } + + default @NotNull String joinToString(CharSequence separator, @NotNull Function transform) { + return joinTo(new StringBuilder(), separator, transform).toString(); + } + + default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix, @NotNull Function transform) { + return joinTo(new StringBuilder(), separator, prefix, postfix, transform).toString(); + } + + //endregion +} diff --git a/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveIterator.java b/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveIterator.java index 2fbc31ee..d92d4354 100644 --- a/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveIterator.java +++ b/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveIterator.java @@ -1,171 +1,168 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base.primitive; - -import kala.annotations.ReplaceWith; -import kala.collection.base.Iterators; -import kala.control.AnyOption; -import kala.control.primitive.CharOption; -import kala.tuple.Tuple2; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public interface PrimitiveIterator extends java.util.PrimitiveIterator { - - @Override - boolean hasNext(); - - @Override - @NotNull T next(); - - /** - * Equivalent to calling {@link #next()} and ignoring the return value. - *

- * Useful when you only need to count the number of Iterator elements and don't care about the value. - * The difference between this method and {@link #next()} is that boxing the return value can be avoided. - */ - void nextIgnoreResult(); - - //region Size Info - - default boolean isEmpty() { - return !hasNext(); - } - - @Contract(mutates = "this") - default int size() { - int i = 0; - while (hasNext()) { - nextIgnoreResult(); - ++i; - } - return i; - } - - default int knownSize() { - return hasNext() ? -1 : 0; - } - - //endregion - - //region Element Conditions - - @Contract(mutates = "this") - boolean contains(Object value); - - @Contract(mutates = "this") - default boolean containsAll(T @NotNull [] values) { - for (T value : values) { - if (!contains(value)) { - return false; - } - } - return true; - } - - @Contract(mutates = "this") - default boolean containsAll(@NotNull Iterable values) { - for (Object value : values) { - if (!contains(value)) { - return false; - } - } - return true; - } - - boolean sameElements(@NotNull Iterator other); - - //endregion - - //region Misc Operations - - @NotNull PrimitiveIterator drop(int n); - - @NotNull PrimitiveIterator take(int n); - - //endregion - - //region Aggregate Operations - - @Nullable T maxOrNull(); - - @NotNull AnyOption maxOption(); - - @Nullable T minOrNull(); - - @NotNull AnyOption minOption(); - - //endregion - - @Contract(mutates = "this") - @NotNull Object toArray(); - - //region Traverse Operations - - @Contract(mutates = "this") - void forEach(@NotNull T_CONSUMER action); - - @Override - @ReplaceWith("forEach(action)") - default void forEachRemaining(@NotNull T_CONSUMER action) { - forEach(action); - } - - //endregion - - //region String Representation - - @Contract(mutates = "this, param1") - default @NotNull A joinTo(@NotNull A buffer) { - return joinTo(buffer, ", "); - } - - @Contract(mutates = "this, param1") - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { - return joinTo(buffer, separator, "", ""); - } - - @Contract(value = "_, _, _, _ -> param1", mutates = "this, param1") - @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix - ); - - @Contract(mutates = "this") - default @NotNull String joinToString() { - return joinTo(new StringBuilder()).toString(); - } - - @Contract(mutates = "this") - default @NotNull String joinToString(CharSequence separator) { - return joinTo(new StringBuilder(), separator).toString(); - } - - @Contract(mutates = "this") - default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { - return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); - } - - //endregion - - default int hash() { - return Iterators.hash(this); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base.primitive; + +import kala.annotations.ReplaceWith; +import kala.collection.base.Iterators; +import kala.control.AnyOption; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Iterator; + +public interface PrimitiveIterator extends java.util.PrimitiveIterator { + + @Override + boolean hasNext(); + + @Override + @NotNull T next(); + + /** + * Equivalent to calling {@link #next()} and ignoring the return value. + *

+ * Useful when you only need to count the number of Iterator elements and don't care about the value. + * The difference between this method and {@link #next()} is that boxing the return value can be avoided. + */ + void nextIgnoreResult(); + + //region Size Info + + default boolean isEmpty() { + return !hasNext(); + } + + @Contract(mutates = "this") + default int size() { + int i = 0; + while (hasNext()) { + nextIgnoreResult(); + ++i; + } + return i; + } + + default int knownSize() { + return hasNext() ? -1 : 0; + } + + //endregion + + //region Element Conditions + + @Contract(mutates = "this") + boolean contains(Object value); + + @Contract(mutates = "this") + default boolean containsAll(T @NotNull [] values) { + for (T value : values) { + if (!contains(value)) { + return false; + } + } + return true; + } + + @Contract(mutates = "this") + default boolean containsAll(@NotNull Iterable values) { + for (Object value : values) { + if (!contains(value)) { + return false; + } + } + return true; + } + + boolean sameElements(@NotNull Iterator other); + + //endregion + + //region Misc Operations + + @NotNull PrimitiveIterator drop(int n); + + @NotNull PrimitiveIterator take(int n); + + //endregion + + //region Aggregate Operations + + @Nullable T maxOrNull(); + + @NotNull AnyOption maxOption(); + + @Nullable T minOrNull(); + + @NotNull AnyOption minOption(); + + //endregion + + @Contract(mutates = "this") + @NotNull Object toArray(); + + //region Traverse Operations + + @Contract(mutates = "this") + void forEach(@NotNull T_CONSUMER action); + + @Override + @ReplaceWith("forEach(action)") + default void forEachRemaining(@NotNull T_CONSUMER action) { + forEach(action); + } + + //endregion + + //region String Representation + + @Contract(mutates = "this, param1") + default @NotNull A joinTo(@NotNull A buffer) { + return joinTo(buffer, ", "); + } + + @Contract(mutates = "this, param1") + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator) { + return joinTo(buffer, separator, "", ""); + } + + @Contract(value = "_, _, _, _ -> param1", mutates = "this, param1") + @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix + ); + + @Contract(mutates = "this") + default @NotNull String joinToString() { + return joinTo(new StringBuilder()).toString(); + } + + @Contract(mutates = "this") + default @NotNull String joinToString(CharSequence separator) { + return joinTo(new StringBuilder(), separator).toString(); + } + + @Contract(mutates = "this") + default @NotNull String joinToString(CharSequence separator, CharSequence prefix, CharSequence postfix) { + return joinTo(new StringBuilder(), separator, prefix, postfix).toString(); + } + + //endregion + + default int hash() { + return Iterators.hash(this); + } +} diff --git a/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveTraversable.java b/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveTraversable.java index 71351e34..8ad331c8 100644 --- a/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveTraversable.java +++ b/kala-base/src/main/java/kala/collection/base/primitive/PrimitiveTraversable.java @@ -1,83 +1,83 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base.primitive; - -import kala.collection.base.AnyTraversable; -import kala.collection.base.Traversable; -import kala.control.AnyOption; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface PrimitiveTraversable extends AnyTraversable { - - default @NotNull Traversable asGeneric() { - return new AsGenericTraversable<>(this); - } - - @Override - @NotNull PrimitiveIterator iterator(); - - //region Size Info - - @Override - default int size() { - return iterator().size(); - } - - @Override - default int sizeCompare(int otherSize) { - if (otherSize < 0) { - return 1; - } - final int knownSize = knownSize(); - if (knownSize >= 0) { - return Integer.compare(knownSize, otherSize); - } - int i = 0; - PrimitiveIterator it = iterator(); - while (it.hasNext()) { - it.nextIgnoreResult(); - if (i == otherSize) { - return 1; - } - i++; - } - return i - otherSize; - } - - //endregion - - //region Aggregate Operations - - @Nullable T maxOrNull(); - - @NotNull AnyOption maxOption(); - - @Nullable T minOrNull(); - - @NotNull AnyOption minOption(); - - //endregion - - //region String Representation - - @Override - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, CharSequence prefix, CharSequence postfix) { - return iterator().joinTo(buffer, separator, prefix, postfix); - } - - //endregion -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base.primitive; + +import kala.collection.base.AnyTraversable; +import kala.collection.base.Traversable; +import kala.control.AnyOption; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface PrimitiveTraversable extends AnyTraversable { + + default @NotNull Traversable asGeneric() { + return new AsGenericTraversable<>(this); + } + + @Override + @NotNull PrimitiveIterator iterator(); + + //region Size Info + + @Override + default int size() { + return iterator().size(); + } + + @Override + default int sizeCompare(int otherSize) { + if (otherSize < 0) { + return 1; + } + final int knownSize = knownSize(); + if (knownSize >= 0) { + return Integer.compare(knownSize, otherSize); + } + int i = 0; + PrimitiveIterator it = iterator(); + while (it.hasNext()) { + it.nextIgnoreResult(); + if (i == otherSize) { + return 1; + } + i++; + } + return i - otherSize; + } + + //endregion + + //region Aggregate Operations + + @Nullable T maxOrNull(); + + @NotNull AnyOption maxOption(); + + @Nullable T minOrNull(); + + @NotNull AnyOption minOption(); + + //endregion + + //region String Representation + + @Override + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, CharSequence prefix, CharSequence postfix) { + return iterator().joinTo(buffer, separator, prefix, postfix); + } + + //endregion +} diff --git a/kala-base/src/main/java/kala/collection/factory/Factory.java b/kala-base/src/main/java/kala/collection/factory/Factory.java index 1f83e4d9..9494bfe5 100644 --- a/kala-base/src/main/java/kala/collection/factory/Factory.java +++ b/kala-base/src/main/java/kala/collection/factory/Factory.java @@ -1,46 +1,46 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.factory; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; -import java.util.function.Function; - -public interface Factory { - Builder newBuilder(); - - R build(Builder builder); - - default @NotNull Factory mapResult(@NotNull Function mapper) { - Objects.requireNonNull(mapper); - - final class MappedFactory implements Factory { - @Override - public Builder newBuilder() { - return Factory.this.newBuilder(); - } - - @Override - public U build(@NotNull Builder builder) { - return mapper.apply(Factory.this.build(builder)); - } - } - - return new MappedFactory(); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.factory; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.function.Function; + +public interface Factory { + Builder newBuilder(); + + R build(Builder builder); + + default @NotNull Factory mapResult(@NotNull Function mapper) { + Objects.requireNonNull(mapper); + + final class MappedFactory implements Factory { + @Override + public Builder newBuilder() { + return Factory.this.newBuilder(); + } + + @Override + public U build(@NotNull Builder builder) { + return mapper.apply(Factory.this.build(builder)); + } + } + + return new MappedFactory(); + } +} diff --git a/kala-base/src/main/java/kala/comparator/primitive/PrimitiveComparator.java b/kala-base/src/main/java/kala/comparator/primitive/PrimitiveComparator.java index 8a27eab9..3ded760e 100644 --- a/kala-base/src/main/java/kala/comparator/primitive/PrimitiveComparator.java +++ b/kala-base/src/main/java/kala/comparator/primitive/PrimitiveComparator.java @@ -1,31 +1,31 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.comparator.primitive; - -import org.jetbrains.annotations.NotNull; - -import java.util.Comparator; - -public sealed interface PrimitiveComparator> - extends Comparator permits BooleanComparator, IntComparator, LongComparator, ShortComparator, ByteComparator, CharComparator, DoubleComparator, FloatComparator { - - @NotNull C nullsFirst(); - - @NotNull C nullsLast(); - - @Override - @NotNull C reversed(); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.comparator.primitive; + +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; + +public sealed interface PrimitiveComparator> + extends Comparator permits BooleanComparator, IntComparator, LongComparator, ShortComparator, ByteComparator, CharComparator, DoubleComparator, FloatComparator { + + @NotNull C nullsFirst(); + + @NotNull C nullsLast(); + + @Override + @NotNull C reversed(); +} diff --git a/kala-base/src/main/java/kala/control/AnyOption.java b/kala-base/src/main/java/kala/control/AnyOption.java index a970ba9d..fb73b555 100644 --- a/kala-base/src/main/java/kala/control/AnyOption.java +++ b/kala-base/src/main/java/kala/control/AnyOption.java @@ -1,26 +1,26 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control; - -import kala.annotations.Covariant; -import kala.control.primitive.PrimitiveOption; - -import java.io.Serializable; - -public sealed interface AnyOption<@Covariant T> extends Serializable permits Option, PrimitiveOption { - int HASH_MAGIC = -818206074; - int NONE_HASH = 1937147281; -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control; + +import kala.annotations.Covariant; +import kala.control.primitive.PrimitiveOption; + +import java.io.Serializable; + +public sealed interface AnyOption<@Covariant T> extends Serializable permits Option, PrimitiveOption { + int HASH_MAGIC = -818206074; + int NONE_HASH = 1937147281; +} diff --git a/kala-base/src/main/java/kala/control/OptionContainer.java b/kala-base/src/main/java/kala/control/OptionContainer.java index 9284611d..2503d1e6 100644 --- a/kala-base/src/main/java/kala/control/OptionContainer.java +++ b/kala-base/src/main/java/kala/control/OptionContainer.java @@ -1,309 +1,309 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control; - -import kala.collection.base.Iterators; -import kala.collection.base.Traversable; -import kala.collection.base.Mappable; -import kala.annotations.Covariant; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.*; -import java.util.function.Consumer; -import java.util.stream.Collector; -import java.util.stream.Stream; - -/** - * A container object which may or may not contain a value. - * - * @param the type of value - * @author Glavo - */ -public interface OptionContainer<@Covariant T> extends Iterable, Mappable, Traversable { - - /** - * Returns {@code true} if the container contain a value, otherwise return {@code false}. - * - * @return {@code true} if the container contain a value, otherwise {@code false} - */ - boolean isDefined(); - - /** - * Returns {@code true} if the container is empty, otherwise return {@code false}. - * - * @return {@code true} if the container is empty, otherwise {@code false} - */ - @ApiStatus.NonExtendable - default boolean isEmpty() { - return !isDefined(); - } - - default @NotNull Stream stream() { - return isDefined() ? Stream.of(get()) : Stream.empty(); - } - - default @NotNull Stream parallelStream() { - return stream().parallel(); - } - - @Override - default @NotNull Iterator iterator() { - return isDefined() ? Iterators.of(get()) : Iterators.empty(); - } - - @Override - default int size() { - return isDefined() ? 1 : 0; - } - - /** - * Returns the value of the container. - * - * @return the value of the container - * @throws NoSuchElementException if the container is empty - */ - T get(); - - /** - * Returns the value of the container if it is not empty, otherwise return the {@code null}. - * - * @return the value of the container if the container {@link #isDefined()}, - * or the {@code null} if the container {@link #isEmpty()} - */ - default @Nullable T getOrNull() { - return isDefined() ? get() : null; - } - - /** - * Returns {@code Option.some(get())} if it is not empty, otherwise return the {@code Option.none()}. - * - * @return {@code Option.some(get())} if the container {@link #isDefined()}, - * or the {@code Option.none()} if the container {@link #isEmpty()} - */ - default @NotNull Option getOption() { - return isDefined() ? Option.some(get()) : Option.none(); - } - - /** - * Returns the value of the container if it is not empty, otherwise return the {@code defaultValue}. - * - * @param defaultValue the default value - * @return the value of the container if the container {@link #isDefined()}, - * or the {@code defaultValue} if the container {@link #isEmpty()} - */ - default T getOrDefault(T defaultValue) { - return isDefined() ? get() : defaultValue; - } - - default T getOrElse(@NotNull Supplier supplier) { - return isDefined() ? get() : supplier.get(); - } - - /** - * Returns the value of the container if it is not empty, otherwise throw the {@code exception}. - * - * @return the value of the container if the container {@link #isDefined()} - * @throws Ex if no value is present - */ - default T getOrThrowException(@NotNull Ex exception) throws Ex { - if (isEmpty()) { - Objects.requireNonNull(exception); - throw exception; - } - return get(); - } - - /** - * Returns the value of the container if it is not empty, otherwise throw {@code supplier.get()}. - * - * @return the value of the container if the container {@link #isDefined()} - * @throws Ex if no value is present - */ - default T getOrThrow(@NotNull Supplier supplier) throws Ex { - if (isEmpty()) { - Objects.requireNonNull(supplier); - throw supplier.get(); - } - return get(); - } - - default U get(@NotNull Function mapper) { - return mapper.apply(get()); - } - - default @Nullable U getOrNull(@NotNull Function mapper) { - return isDefined() ? mapper.apply(get()) : null; - } - - default @NotNull Option getOption(@NotNull Function mapper) { - return isDefined() ? Option.some(mapper.apply(get())) : Option.none(); - } - - default U getOrDefault(@NotNull Function mapper, U defaultValue) { - return isDefined() ? mapper.apply(get()) : defaultValue; - } - - default U getOrElse(@NotNull Function mapper, @NotNull Supplier supplier) { - return isDefined() ? mapper.apply(get()) : supplier.get(); - } - - default U getOrThrowException(@NotNull Function mapper, @NotNull Ex exception) throws Ex { - if (isEmpty()) { - Objects.requireNonNull(exception); - throw exception; - } - return mapper.apply(get()); - } - - default U getOrThrow(@NotNull Function mapper, @NotNull Supplier supplier) throws Ex { - if (isEmpty()) { - Objects.requireNonNull(supplier); - throw supplier.get(); - } - return mapper.apply(get()); - } - - default void ifDefined(@NotNull Consumer action) { - if (isDefined()) { - action.accept(get()); - } - } - - default void ifDefinedOrElse(@NotNull Consumer action, Runnable emptyAction) { - if (isDefined()) { - action.accept(get()); - } else { - emptyAction.run(); - } - } - - /** - * Returns {@code Option.some(get())} if it is not empty, otherwise return the {@code Option.none()}. - * - * @return {@code Option.some(get())} if the container {@link #isDefined()}, - * or the {@code Option.none()} if the container {@link #isEmpty()} - */ - default @NotNull Option toOption() { - return getOption(); - } - - @SuppressWarnings("unchecked") - default R collect(@NotNull Collector factory) { - final Collector f = ((Collector) factory); - Object builder = f.supplier().get(); - if (isDefined()) { - f.accumulator().accept(builder, get()); - } - return f.finisher().apply(builder); - } - - @Override - @NotNull OptionContainer map(@NotNull Function mapper); - - @Override - @Contract(pure = true) - default int count(@NotNull Predicate predicate) { - Objects.requireNonNull(predicate); - return anyMatch(predicate) ? 1 : 0; - } - - @Override - default U foldLeft(U zero, @NotNull BiFunction op) { - if (isEmpty()) { - return zero; - } - return op.apply(zero, get()); - } - - @Override - @Contract(pure = true) - default U foldRight(U zero, @NotNull BiFunction op) { - if (isEmpty()) { - return zero; - } - return op.apply(get(), zero); - } - - @Override - default T reduceLeft(@NotNull BiFunction op) { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return get(); - } - - @Override - default T reduceRight(@NotNull BiFunction op) { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return get(); - } - - @Override - @Contract(pure = true) - default @NotNull Option reduceLeftOption(@NotNull BiFunction op) { - return getOption(); - } - - @Override - @Contract(pure = true) - default @NotNull Option reduceRightOption(@NotNull BiFunction op) { - return getOption(); - } - - @Override - @Contract(pure = true) - default boolean anyMatch(@NotNull Predicate predicate) { - return isDefined() && predicate.test(get()); - } - - @Override - @Contract(pure = true) - default boolean allMatch(@NotNull Predicate predicate) { - return isEmpty() || predicate.test(get()); - } - - @Override - @Contract(pure = true) - default boolean noneMatch(@NotNull Predicate predicate) { - return isEmpty() || !predicate.test(get()); - } - - @Override - default boolean contains(Object value) { - return isDefined() && Objects.equals(value, get()); - } - - @Override - default @NotNull Option find(@NotNull Predicate predicate) { - return isDefined() && predicate.test(get()) // implicit null check of predicate - ? Option.some(get()) - : Option.none(); - } - - @Override - default void forEach(@NotNull Consumer action) { - Objects.requireNonNull(action); - if (isDefined()) { - action.accept(get()); - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control; + +import kala.collection.base.Iterators; +import kala.collection.base.Traversable; +import kala.collection.base.Mappable; +import kala.annotations.Covariant; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.*; +import java.util.function.Consumer; +import java.util.stream.Collector; +import java.util.stream.Stream; + +/** + * A container object which may or may not contain a value. + * + * @param the type of value + * @author Glavo + */ +public interface OptionContainer<@Covariant T> extends Iterable, Mappable, Traversable { + + /** + * Returns {@code true} if the container contain a value, otherwise return {@code false}. + * + * @return {@code true} if the container contain a value, otherwise {@code false} + */ + boolean isDefined(); + + /** + * Returns {@code true} if the container is empty, otherwise return {@code false}. + * + * @return {@code true} if the container is empty, otherwise {@code false} + */ + @ApiStatus.NonExtendable + default boolean isEmpty() { + return !isDefined(); + } + + default @NotNull Stream stream() { + return isDefined() ? Stream.of(get()) : Stream.empty(); + } + + default @NotNull Stream parallelStream() { + return stream().parallel(); + } + + @Override + default @NotNull Iterator iterator() { + return isDefined() ? Iterators.of(get()) : Iterators.empty(); + } + + @Override + default int size() { + return isDefined() ? 1 : 0; + } + + /** + * Returns the value of the container. + * + * @return the value of the container + * @throws NoSuchElementException if the container is empty + */ + T get(); + + /** + * Returns the value of the container if it is not empty, otherwise return the {@code null}. + * + * @return the value of the container if the container {@link #isDefined()}, + * or the {@code null} if the container {@link #isEmpty()} + */ + default @Nullable T getOrNull() { + return isDefined() ? get() : null; + } + + /** + * Returns {@code Option.some(get())} if it is not empty, otherwise return the {@code Option.none()}. + * + * @return {@code Option.some(get())} if the container {@link #isDefined()}, + * or the {@code Option.none()} if the container {@link #isEmpty()} + */ + default @NotNull Option getOption() { + return isDefined() ? Option.some(get()) : Option.none(); + } + + /** + * Returns the value of the container if it is not empty, otherwise return the {@code defaultValue}. + * + * @param defaultValue the default value + * @return the value of the container if the container {@link #isDefined()}, + * or the {@code defaultValue} if the container {@link #isEmpty()} + */ + default T getOrDefault(T defaultValue) { + return isDefined() ? get() : defaultValue; + } + + default T getOrElse(@NotNull Supplier supplier) { + return isDefined() ? get() : supplier.get(); + } + + /** + * Returns the value of the container if it is not empty, otherwise throw the {@code exception}. + * + * @return the value of the container if the container {@link #isDefined()} + * @throws Ex if no value is present + */ + default T getOrThrowException(@NotNull Ex exception) throws Ex { + if (isEmpty()) { + Objects.requireNonNull(exception); + throw exception; + } + return get(); + } + + /** + * Returns the value of the container if it is not empty, otherwise throw {@code supplier.get()}. + * + * @return the value of the container if the container {@link #isDefined()} + * @throws Ex if no value is present + */ + default T getOrThrow(@NotNull Supplier supplier) throws Ex { + if (isEmpty()) { + Objects.requireNonNull(supplier); + throw supplier.get(); + } + return get(); + } + + default U get(@NotNull Function mapper) { + return mapper.apply(get()); + } + + default @Nullable U getOrNull(@NotNull Function mapper) { + return isDefined() ? mapper.apply(get()) : null; + } + + default @NotNull Option getOption(@NotNull Function mapper) { + return isDefined() ? Option.some(mapper.apply(get())) : Option.none(); + } + + default U getOrDefault(@NotNull Function mapper, U defaultValue) { + return isDefined() ? mapper.apply(get()) : defaultValue; + } + + default U getOrElse(@NotNull Function mapper, @NotNull Supplier supplier) { + return isDefined() ? mapper.apply(get()) : supplier.get(); + } + + default U getOrThrowException(@NotNull Function mapper, @NotNull Ex exception) throws Ex { + if (isEmpty()) { + Objects.requireNonNull(exception); + throw exception; + } + return mapper.apply(get()); + } + + default U getOrThrow(@NotNull Function mapper, @NotNull Supplier supplier) throws Ex { + if (isEmpty()) { + Objects.requireNonNull(supplier); + throw supplier.get(); + } + return mapper.apply(get()); + } + + default void ifDefined(@NotNull Consumer action) { + if (isDefined()) { + action.accept(get()); + } + } + + default void ifDefinedOrElse(@NotNull Consumer action, Runnable emptyAction) { + if (isDefined()) { + action.accept(get()); + } else { + emptyAction.run(); + } + } + + /** + * Returns {@code Option.some(get())} if it is not empty, otherwise return the {@code Option.none()}. + * + * @return {@code Option.some(get())} if the container {@link #isDefined()}, + * or the {@code Option.none()} if the container {@link #isEmpty()} + */ + default @NotNull Option toOption() { + return getOption(); + } + + @SuppressWarnings("unchecked") + default R collect(@NotNull Collector factory) { + final Collector f = ((Collector) factory); + Object builder = f.supplier().get(); + if (isDefined()) { + f.accumulator().accept(builder, get()); + } + return f.finisher().apply(builder); + } + + @Override + @NotNull OptionContainer map(@NotNull Function mapper); + + @Override + @Contract(pure = true) + default int count(@NotNull Predicate predicate) { + Objects.requireNonNull(predicate); + return anyMatch(predicate) ? 1 : 0; + } + + @Override + default U foldLeft(U zero, @NotNull BiFunction op) { + if (isEmpty()) { + return zero; + } + return op.apply(zero, get()); + } + + @Override + @Contract(pure = true) + default U foldRight(U zero, @NotNull BiFunction op) { + if (isEmpty()) { + return zero; + } + return op.apply(get(), zero); + } + + @Override + default T reduceLeft(@NotNull BiFunction op) { + if (isEmpty()) { + throw new NoSuchElementException(); + } + return get(); + } + + @Override + default T reduceRight(@NotNull BiFunction op) { + if (isEmpty()) { + throw new NoSuchElementException(); + } + return get(); + } + + @Override + @Contract(pure = true) + default @NotNull Option reduceLeftOption(@NotNull BiFunction op) { + return getOption(); + } + + @Override + @Contract(pure = true) + default @NotNull Option reduceRightOption(@NotNull BiFunction op) { + return getOption(); + } + + @Override + @Contract(pure = true) + default boolean anyMatch(@NotNull Predicate predicate) { + return isDefined() && predicate.test(get()); + } + + @Override + @Contract(pure = true) + default boolean allMatch(@NotNull Predicate predicate) { + return isEmpty() || predicate.test(get()); + } + + @Override + @Contract(pure = true) + default boolean noneMatch(@NotNull Predicate predicate) { + return isEmpty() || !predicate.test(get()); + } + + @Override + default boolean contains(Object value) { + return isDefined() && Objects.equals(value, get()); + } + + @Override + default @NotNull Option find(@NotNull Predicate predicate) { + return isDefined() && predicate.test(get()) // implicit null check of predicate + ? Option.some(get()) + : Option.none(); + } + + @Override + default void forEach(@NotNull Consumer action) { + Objects.requireNonNull(action); + if (isDefined()) { + action.accept(get()); + } + } +} diff --git a/kala-base/src/main/java/kala/control/Try.java b/kala-base/src/main/java/kala/control/Try.java index 3273ebc7..fbaec471 100644 --- a/kala-base/src/main/java/kala/control/Try.java +++ b/kala-base/src/main/java/kala/control/Try.java @@ -1,527 +1,527 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control; - -import kala.annotations.ReplaceWith; -import kala.collection.base.Iterators; -import kala.collection.base.Traversable; -import kala.function.*; -import kala.annotations.Covariant; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.function.Consumer; -import java.util.function.Supplier; - -/** - * Represents a result value or the exception that caused it to fail. - * It provides a new way to handle exceptions, and provides some static methods to help users handle exceptions. - * - * @param - */ -@SuppressWarnings("unchecked") -public sealed interface Try<@Covariant T> extends AnyTry, Traversable, Serializable { - Try VOID = new Success<>(null); - - @Contract(value = "_ -> param1", pure = true) - static Try narrow(Try t) { - return (Try) t; - } - - /** - * Used to prompt the compiler that an exception may be thrown here. - * Usually used with {@link #sneakyThrow(Throwable)}. - *

- * Example: - *

{@code
-     * try {
-     *     list.forEach(value -> {
-     *        try {
-     *            // do something
-     *        } catch (IOException e) {
-     *            return sneakyThrow(e);
-     *        }
-     *     });
-     *
-     *     Try.maybeThrows();
-     * } catch (IOException e) {
-     *     // do something
-     * }}
- */ - static void maybeThrows() throws Ex { - // do nothing - } - - /** - * An alternative to the {@code throw} statement, used as an expression. - * - *
{@code
-     * var a = condition ? value : throwException(new IllegalArgumentException());
-     * }
- */ - @Contract("_ -> fail") - static R throwException(Ex exception) throws Ex { - throw exception; - } - - /** - * Throws the exception without telling the verifier. - *

- * It never returns, so you can use it as an expression of any type. - */ - @Contract("_ -> fail") - static R sneakyThrow(Throwable exception) { - sneakyThrow0(exception); - return null; // make compiler happy - } - - @Contract("_ -> fail") - private static void sneakyThrow0(Throwable exception) throws Ex { - throw (Ex) exception; - } - - static String getStackTraceAsString(@NotNull Throwable exception) { - Objects.requireNonNull(exception); - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(4096); - try (PrintStream stream = new PrintStream(buffer, false, StandardCharsets.UTF_8)) { - exception.printStackTrace(stream); - } - return buffer.toString(StandardCharsets.UTF_8); - } - - static String getStackTraceAsString(StackTraceElement @NotNull [] stackTrace) { - StringBuilder builder = new StringBuilder(4096); - String lineSeparator = System.lineSeparator(); - - for (StackTraceElement traceElement : stackTrace) { - builder.append("\tat ").append(traceElement).append(lineSeparator); - } - return builder.toString(); - } - - static String getStackTraceAsString(@NotNull Iterable stackTrace) { - StringBuilder builder = new StringBuilder(4096); - String lineSeparator = System.lineSeparator(); - - for (StackTraceElement traceElement : stackTrace) { - builder.append("\tat ").append(traceElement).append(lineSeparator); - } - return builder.toString(); - } - - @SuppressWarnings("removal") - static boolean isFatal(Throwable exception) { - return exception instanceof InterruptedException - || exception instanceof LinkageError - || exception instanceof ThreadDeath - || exception instanceof VirtualMachineError; - } - - static @NotNull Try success(T value) { - return new Success<>(value); - } - - static @NotNull Try failure(@NotNull Throwable exception) { - Objects.requireNonNull(exception); - return new Failure<>(exception); - } - - static @NotNull Try of(@NotNull CheckedSupplier supplier) { - Objects.requireNonNull(supplier); - try { - return success(supplier.getChecked()); - } catch (Throwable ex) { - return failure(ex); - } - } - - static @NotNull Try ofCallable(@NotNull Callable callable) { - Objects.requireNonNull(callable); - try { - return success(callable.call()); - } catch (Throwable ex) { - return failure(ex); - } - } - - static @NotNull Try runCatching(@NotNull CheckedRunnable runnable) { - Objects.requireNonNull(runnable); - try { - runnable.runChecked(); - return VOID; - } catch (Throwable ex) { - return failure(ex); - } - } - - static @NotNull Try runRunnable(@NotNull Runnable runnable) { - Objects.requireNonNull(runnable); - try { - runnable.run(); - return VOID; - } catch (Throwable ex) { - return failure(ex); - } - } - - static void runIgnoreException(@NotNull CheckedRunnable runnable) { - Objects.requireNonNull(runnable); - try { - runnable.runChecked(); - } catch (Throwable ignored) { - } - } - - static void runUnchecked(@NotNull CheckedRunnable runnable) { - runnable.run(); - } - - static @NotNull Try using( - R0 resource0, - @NotNull CheckedFunction action) { - Objects.requireNonNull(action); - try (R0 r0 = resource0) { - return success(action.applyChecked(resource0)); - } catch (Throwable ex) { - return failure(ex); - } - } - - static @NotNull Try using( - R0 resource0, R1 resource1, - @NotNull CheckedBiFunction action) { - Objects.requireNonNull(action); - try (R0 r0 = resource0; R1 r1 = resource1) { - return success(action.applyChecked(resource0, resource1)); - } catch (Throwable ex) { - return failure(ex); - } - } - - static @NotNull Try using( - R0 resource0, R1 resource1, R2 resource2, - @NotNull CheckedTriFunction action) { - Objects.requireNonNull(action); - try (R0 r0 = resource0; R1 r1 = resource1; R2 r2 = resource2) { - return success(action.applyChecked(resource0, resource1, resource2)); - } catch (Throwable ex) { - return failure(ex); - } - } - - /** - * Returns {@code true} if the {@code Try} is {@code Success}, otherwise return {@code false}. - * - * @return {@code true} if the {@code Try} is {@code Success}, otherwise {@code false} - */ - @Override - default boolean isSuccess() { - return this instanceof Try.Success; - } - - /** - * Returns {@code true} if the {@code Try} is {@code Failure}, otherwise return {@code false}. - * - * @return {@code true} if the {@code Try} is {@code Failure}, otherwise {@code false} - */ - @Override - default boolean isFailure() { - return this instanceof Try.Failure; - } - - @Override - @Deprecated - @ReplaceWith("get()") - default T getValue() { - return get(); - } - - default T get() { - if (this instanceof Try.Success(var value)) { - return value; - } - throw new NoSuchElementException("No value present"); - } - - @Override - default @Nullable T getOrNull() { - return this instanceof Success(var value) ? value : null; - } - - @Override - default @NotNull Option getOption() { - return this instanceof Success(var value) ? Option.some(value) : Option.none(); - } - - default T getOrDefault(T defaultValue) { - return this instanceof Success(var value) ? value : defaultValue; - } - - default T getOrElse(@NotNull Supplier supplier) { - return this instanceof Success(var value) ? value : supplier.get(); - } - - default T getOrThrow() throws Ex { - return switch (this) { - case Success(var value) -> value; - case Failure(var cause) -> throw (Ex) cause; - }; - } - - default T getOrThrow(@NotNull Supplier supplier) throws Ex { - if (this instanceof Try.Success(var value)) { - return value; - } - throw supplier.get(); - } - - default T getOrThrowException(Ex exception) throws Ex { - if (this instanceof Try.Success(var value)) { - return value; - } - throw exception; - } - - @Override - default @NotNull Throwable getCause() { - return switch (this) { - case Success __ -> throw new UnsupportedOperationException(); - case Failure(var cause) -> cause; - }; - } - - default @NotNull Try recover(@NotNull CheckedFunction op) { - Objects.requireNonNull(op); - - return switch (this) { - case Success success -> success; - case Failure(var cause) -> { - try { - yield success(op.applyChecked(cause)); - } catch (Throwable ex) { - yield failure(ex); - } - } - }; - } - - default @NotNull Try recover(@NotNull Class type, @NotNull CheckedFunction op) { - Objects.requireNonNull(op); - return switch (this) { - case Success __ -> this; - case Failure(var cause) -> { - if (!type.isInstance(cause)) { - yield this; - } - try { - yield success(op.applyChecked((X) cause)); - } catch (Throwable ex) { - yield failure(ex); - } - } - }; - } - - @NotNull - default Try recoverWith(@NotNull CheckedFunction, ?> op) { - Objects.requireNonNull(op); - return switch (this) { - case Success __ -> this; - case Failure(var cause) -> { - try { - yield narrow(op.applyChecked(cause)); - } catch (Throwable ex) { - yield failure(ex); - } - } - }; - } - - default @NotNull Try recoverWith( - @NotNull Class type, @NotNull CheckedFunction, ?> op) { - Objects.requireNonNull(op); - return switch (this) { - case Success __ -> this; - case Failure(var cause) -> { - if (!type.isInstance(cause)) { - yield this; - } - - try { - yield narrow(op.applyChecked((X) cause)); - } catch (Throwable ex) { - yield failure(ex); - } - } - }; - } - - /** - * If the {@code Try} is a {@code Failure}, throw the {@code throwable}, otherwise returns {@code this}. - * - * @param the type of the {@code throwable} - * @return {@code this} if the {@code Try} is a {@code Success} - * @throws Ex if the {@code Try} is a {@code Failure} - */ - @Override - default @NotNull Try rethrow() throws Ex { - return switch (this) { - case Success __ -> this; - case Failure(var cause) -> throw (Ex) cause; - }; - } - - /** - * If the {@code Try} is a {@code Failure} and the {@code throwable} is an instance of {@code type}, - * throw the {@code throwable}, otherwise returns {@code this}. - * - * @param the type of the {@code throwable} - * @return {@code this} if the {@code Try} is a {@code Success} - * or the {@code throwable} not an instance of {@code type} - * @throws Ex if the {@code Try} is a {@code Failure} and the {@code throwable}'s type is {@code type} - */ - @Override - default @NotNull Try rethrow(@NotNull Class type) throws Ex { - if (this instanceof Try.Failure(var cause) && type.isInstance(cause)) { - throw (Ex) cause; - } - - return this; - } - - @Override - default @NotNull Try rethrowFatal() { - if (this instanceof Try.Failure(var cause) && isFatal(cause)) { - sneakyThrow(cause); - } - return this; - } - - default @NotNull Either<@NotNull Throwable, T> toEither() { - return switch (this) { - case Success(var value) -> Either.right(value); - case Failure(var cause) -> Either.left(cause); - }; - } - - default @NotNull Result toResult() { - return switch (this) { - case Success(var value) -> Result.ok(value); - case Failure(var cause) -> Result.err(cause); - }; - } - - default @NotNull Try map(@NotNull CheckedFunction mapper) { - Objects.requireNonNull(mapper); - return switch (this) { - case Success(var value) -> { - try { - yield success(mapper.applyChecked(value)); - } catch (Throwable ex) { - yield failure(ex); - } - } - case Failure failure -> failure.cast(); - }; - } - - default @NotNull Try flatMap(@NotNull CheckedFunction, ?> mapper) { - Objects.requireNonNull(mapper); - - return switch (this) { - case Success(var value) -> { - try { - yield narrow(mapper.applyChecked(value)); - } catch (Throwable ex) { - yield failure(ex); - } - } - case Failure failure -> failure.cast(); - }; - } - - @Override - default @NotNull Iterator iterator() { - return switch (this) { - case Success(var value) -> Iterators.of(value); - case Failure failure -> Iterators.empty(); - }; - } - - @Override - default void forEach(@NotNull Consumer action) { - if (this instanceof Try.Success(var value)) { - action.accept(value); - } - } - - record Success(T value) implements Try { - - @Override - public int hashCode() { - return Objects.hashCode(value) + SUCCESS_HASH_MAGIC; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof AnyTry other) || other.isFailure()) return false; - - return Objects.equals(this.get(), other.getValue()); - } - - @Override - public String toString() { - return "Try.Success[" + value + "]"; - } - } - - record Failure(@NotNull Throwable cause) implements Try { - public Failure { - Objects.requireNonNull(cause); - } - - public Failure cast() { - return (Failure) this; - } - - @Override - public int hashCode() { - return cause.hashCode() + FAILURE_HASH_MAGIC; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof AnyTry other) || other.isSuccess()) return false; - - return Objects.equals(cause, other.getCause()); - } - - @Override - public String toString() { - return "Try.Failure[" + cause + "]"; - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control; + +import kala.annotations.ReplaceWith; +import kala.collection.base.Iterators; +import kala.collection.base.Traversable; +import kala.function.*; +import kala.annotations.Covariant; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * Represents a result value or the exception that caused it to fail. + * It provides a new way to handle exceptions, and provides some static methods to help users handle exceptions. + * + * @param + */ +@SuppressWarnings("unchecked") +public sealed interface Try<@Covariant T> extends AnyTry, Traversable, Serializable { + Try VOID = new Success<>(null); + + @Contract(value = "_ -> param1", pure = true) + static Try narrow(Try t) { + return (Try) t; + } + + /** + * Used to prompt the compiler that an exception may be thrown here. + * Usually used with {@link #sneakyThrow(Throwable)}. + *

+ * Example: + *

{@code
+     * try {
+     *     list.forEach(value -> {
+     *        try {
+     *            // do something
+     *        } catch (IOException e) {
+     *            return sneakyThrow(e);
+     *        }
+     *     });
+     *
+     *     Try.maybeThrows();
+     * } catch (IOException e) {
+     *     // do something
+     * }}
+ */ + static void maybeThrows() throws Ex { + // do nothing + } + + /** + * An alternative to the {@code throw} statement, used as an expression. + * + *
{@code
+     * var a = condition ? value : throwException(new IllegalArgumentException());
+     * }
+ */ + @Contract("_ -> fail") + static R throwException(Ex exception) throws Ex { + throw exception; + } + + /** + * Throws the exception without telling the verifier. + *

+ * It never returns, so you can use it as an expression of any type. + */ + @Contract("_ -> fail") + static R sneakyThrow(Throwable exception) { + sneakyThrow0(exception); + return null; // make compiler happy + } + + @Contract("_ -> fail") + private static void sneakyThrow0(Throwable exception) throws Ex { + throw (Ex) exception; + } + + static String getStackTraceAsString(@NotNull Throwable exception) { + Objects.requireNonNull(exception); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(4096); + try (PrintStream stream = new PrintStream(buffer, false, StandardCharsets.UTF_8)) { + exception.printStackTrace(stream); + } + return buffer.toString(StandardCharsets.UTF_8); + } + + static String getStackTraceAsString(StackTraceElement @NotNull [] stackTrace) { + StringBuilder builder = new StringBuilder(4096); + String lineSeparator = System.lineSeparator(); + + for (StackTraceElement traceElement : stackTrace) { + builder.append("\tat ").append(traceElement).append(lineSeparator); + } + return builder.toString(); + } + + static String getStackTraceAsString(@NotNull Iterable stackTrace) { + StringBuilder builder = new StringBuilder(4096); + String lineSeparator = System.lineSeparator(); + + for (StackTraceElement traceElement : stackTrace) { + builder.append("\tat ").append(traceElement).append(lineSeparator); + } + return builder.toString(); + } + + @SuppressWarnings("removal") + static boolean isFatal(Throwable exception) { + return exception instanceof InterruptedException + || exception instanceof LinkageError + || exception instanceof ThreadDeath + || exception instanceof VirtualMachineError; + } + + static @NotNull Try success(T value) { + return new Success<>(value); + } + + static @NotNull Try failure(@NotNull Throwable exception) { + Objects.requireNonNull(exception); + return new Failure<>(exception); + } + + static @NotNull Try of(@NotNull CheckedSupplier supplier) { + Objects.requireNonNull(supplier); + try { + return success(supplier.getChecked()); + } catch (Throwable ex) { + return failure(ex); + } + } + + static @NotNull Try ofCallable(@NotNull Callable callable) { + Objects.requireNonNull(callable); + try { + return success(callable.call()); + } catch (Throwable ex) { + return failure(ex); + } + } + + static @NotNull Try runCatching(@NotNull CheckedRunnable runnable) { + Objects.requireNonNull(runnable); + try { + runnable.runChecked(); + return VOID; + } catch (Throwable ex) { + return failure(ex); + } + } + + static @NotNull Try runRunnable(@NotNull Runnable runnable) { + Objects.requireNonNull(runnable); + try { + runnable.run(); + return VOID; + } catch (Throwable ex) { + return failure(ex); + } + } + + static void runIgnoreException(@NotNull CheckedRunnable runnable) { + Objects.requireNonNull(runnable); + try { + runnable.runChecked(); + } catch (Throwable ignored) { + } + } + + static void runUnchecked(@NotNull CheckedRunnable runnable) { + runnable.run(); + } + + static @NotNull Try using( + R0 resource0, + @NotNull CheckedFunction action) { + Objects.requireNonNull(action); + try (R0 r0 = resource0) { + return success(action.applyChecked(resource0)); + } catch (Throwable ex) { + return failure(ex); + } + } + + static @NotNull Try using( + R0 resource0, R1 resource1, + @NotNull CheckedBiFunction action) { + Objects.requireNonNull(action); + try (R0 r0 = resource0; R1 r1 = resource1) { + return success(action.applyChecked(resource0, resource1)); + } catch (Throwable ex) { + return failure(ex); + } + } + + static @NotNull Try using( + R0 resource0, R1 resource1, R2 resource2, + @NotNull CheckedTriFunction action) { + Objects.requireNonNull(action); + try (R0 r0 = resource0; R1 r1 = resource1; R2 r2 = resource2) { + return success(action.applyChecked(resource0, resource1, resource2)); + } catch (Throwable ex) { + return failure(ex); + } + } + + /** + * Returns {@code true} if the {@code Try} is {@code Success}, otherwise return {@code false}. + * + * @return {@code true} if the {@code Try} is {@code Success}, otherwise {@code false} + */ + @Override + default boolean isSuccess() { + return this instanceof Try.Success; + } + + /** + * Returns {@code true} if the {@code Try} is {@code Failure}, otherwise return {@code false}. + * + * @return {@code true} if the {@code Try} is {@code Failure}, otherwise {@code false} + */ + @Override + default boolean isFailure() { + return this instanceof Try.Failure; + } + + @Override + @Deprecated + @ReplaceWith("get()") + default T getValue() { + return get(); + } + + default T get() { + if (this instanceof Try.Success(var value)) { + return value; + } + throw new NoSuchElementException("No value present"); + } + + @Override + default @Nullable T getOrNull() { + return this instanceof Success(var value) ? value : null; + } + + @Override + default @NotNull Option getOption() { + return this instanceof Success(var value) ? Option.some(value) : Option.none(); + } + + default T getOrDefault(T defaultValue) { + return this instanceof Success(var value) ? value : defaultValue; + } + + default T getOrElse(@NotNull Supplier supplier) { + return this instanceof Success(var value) ? value : supplier.get(); + } + + default T getOrThrow() throws Ex { + return switch (this) { + case Success(var value) -> value; + case Failure(var cause) -> throw (Ex) cause; + }; + } + + default T getOrThrow(@NotNull Supplier supplier) throws Ex { + if (this instanceof Try.Success(var value)) { + return value; + } + throw supplier.get(); + } + + default T getOrThrowException(Ex exception) throws Ex { + if (this instanceof Try.Success(var value)) { + return value; + } + throw exception; + } + + @Override + default @NotNull Throwable getCause() { + return switch (this) { + case Success __ -> throw new UnsupportedOperationException(); + case Failure(var cause) -> cause; + }; + } + + default @NotNull Try recover(@NotNull CheckedFunction op) { + Objects.requireNonNull(op); + + return switch (this) { + case Success success -> success; + case Failure(var cause) -> { + try { + yield success(op.applyChecked(cause)); + } catch (Throwable ex) { + yield failure(ex); + } + } + }; + } + + default @NotNull Try recover(@NotNull Class type, @NotNull CheckedFunction op) { + Objects.requireNonNull(op); + return switch (this) { + case Success __ -> this; + case Failure(var cause) -> { + if (!type.isInstance(cause)) { + yield this; + } + try { + yield success(op.applyChecked((X) cause)); + } catch (Throwable ex) { + yield failure(ex); + } + } + }; + } + + @NotNull + default Try recoverWith(@NotNull CheckedFunction, ?> op) { + Objects.requireNonNull(op); + return switch (this) { + case Success __ -> this; + case Failure(var cause) -> { + try { + yield narrow(op.applyChecked(cause)); + } catch (Throwable ex) { + yield failure(ex); + } + } + }; + } + + default @NotNull Try recoverWith( + @NotNull Class type, @NotNull CheckedFunction, ?> op) { + Objects.requireNonNull(op); + return switch (this) { + case Success __ -> this; + case Failure(var cause) -> { + if (!type.isInstance(cause)) { + yield this; + } + + try { + yield narrow(op.applyChecked((X) cause)); + } catch (Throwable ex) { + yield failure(ex); + } + } + }; + } + + /** + * If the {@code Try} is a {@code Failure}, throw the {@code throwable}, otherwise returns {@code this}. + * + * @param the type of the {@code throwable} + * @return {@code this} if the {@code Try} is a {@code Success} + * @throws Ex if the {@code Try} is a {@code Failure} + */ + @Override + default @NotNull Try rethrow() throws Ex { + return switch (this) { + case Success __ -> this; + case Failure(var cause) -> throw (Ex) cause; + }; + } + + /** + * If the {@code Try} is a {@code Failure} and the {@code throwable} is an instance of {@code type}, + * throw the {@code throwable}, otherwise returns {@code this}. + * + * @param the type of the {@code throwable} + * @return {@code this} if the {@code Try} is a {@code Success} + * or the {@code throwable} not an instance of {@code type} + * @throws Ex if the {@code Try} is a {@code Failure} and the {@code throwable}'s type is {@code type} + */ + @Override + default @NotNull Try rethrow(@NotNull Class type) throws Ex { + if (this instanceof Try.Failure(var cause) && type.isInstance(cause)) { + throw (Ex) cause; + } + + return this; + } + + @Override + default @NotNull Try rethrowFatal() { + if (this instanceof Try.Failure(var cause) && isFatal(cause)) { + sneakyThrow(cause); + } + return this; + } + + default @NotNull Either<@NotNull Throwable, T> toEither() { + return switch (this) { + case Success(var value) -> Either.right(value); + case Failure(var cause) -> Either.left(cause); + }; + } + + default @NotNull Result toResult() { + return switch (this) { + case Success(var value) -> Result.ok(value); + case Failure(var cause) -> Result.err(cause); + }; + } + + default @NotNull Try map(@NotNull CheckedFunction mapper) { + Objects.requireNonNull(mapper); + return switch (this) { + case Success(var value) -> { + try { + yield success(mapper.applyChecked(value)); + } catch (Throwable ex) { + yield failure(ex); + } + } + case Failure failure -> failure.cast(); + }; + } + + default @NotNull Try flatMap(@NotNull CheckedFunction, ?> mapper) { + Objects.requireNonNull(mapper); + + return switch (this) { + case Success(var value) -> { + try { + yield narrow(mapper.applyChecked(value)); + } catch (Throwable ex) { + yield failure(ex); + } + } + case Failure failure -> failure.cast(); + }; + } + + @Override + default @NotNull Iterator iterator() { + return switch (this) { + case Success(var value) -> Iterators.of(value); + case Failure failure -> Iterators.empty(); + }; + } + + @Override + default void forEach(@NotNull Consumer action) { + if (this instanceof Try.Success(var value)) { + action.accept(value); + } + } + + record Success(T value) implements Try { + + @Override + public int hashCode() { + return Objects.hashCode(value) + SUCCESS_HASH_MAGIC; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AnyTry other) || other.isFailure()) return false; + + return Objects.equals(this.get(), other.getValue()); + } + + @Override + public String toString() { + return "Try.Success[" + value + "]"; + } + } + + record Failure(@NotNull Throwable cause) implements Try { + public Failure { + Objects.requireNonNull(cause); + } + + public Failure cast() { + return (Failure) this; + } + + @Override + public int hashCode() { + return cause.hashCode() + FAILURE_HASH_MAGIC; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AnyTry other) || other.isSuccess()) return false; + + return Objects.equals(cause, other.getCause()); + } + + @Override + public String toString() { + return "Try.Failure[" + cause + "]"; + } + } +} diff --git a/kala-base/src/main/java/kala/control/primitive/BooleanOption.java b/kala-base/src/main/java/kala/control/primitive/BooleanOption.java index e6a51973..cf509e99 100644 --- a/kala-base/src/main/java/kala/control/primitive/BooleanOption.java +++ b/kala-base/src/main/java/kala/control/primitive/BooleanOption.java @@ -1,161 +1,161 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control.primitive; - -import kala.annotations.ReplaceWith; -import kala.control.Option; -import kala.collection.base.primitive.BooleanIterator; -import kala.collection.base.primitive.BooleanTraversable; -import org.intellij.lang.annotations.Flow; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.Serial; -import java.util.NoSuchElementException; - -public final class BooleanOption implements PrimitiveOption, BooleanTraversable { - @Serial - private static final long serialVersionUID = 3226319253753655469L; - private static final int HASH_MAGIC = 773806848; - - public static final BooleanOption True = new BooleanOption(true); - public static final BooleanOption False = new BooleanOption(false); - public static final BooleanOption None = new BooleanOption(); - - private final boolean isDefined; - private final boolean value; - private final transient int hashCode; - private final transient String name; - - private BooleanOption() { - this.isDefined = false; - this.value = false; - this.name = "OptionBoolean.None"; - this.hashCode = NONE_HASH; - } - - private BooleanOption(boolean value) { - this.isDefined = true; - this.value = value; - this.name = value ? "OptionBoolean.True" : "OptionBoolean.False"; - this.hashCode = HASH_MAGIC + Boolean.hashCode(value); - } - - public static @NotNull BooleanOption some(boolean value) { - return value ? True : False; - } - - public static @NotNull BooleanOption none() { - return None; - } - - @Deprecated - @ReplaceWith("some(boolean)") - public static @NotNull BooleanOption of(boolean value) { - return value ? True : False; - } - - @Deprecated - @ReplaceWith("ofNullable(Boolean)") - public static @NotNull BooleanOption of(@Nullable Boolean value) { - return ofNullable(value); - } - - public static @NotNull BooleanOption ofNullable(@Nullable Boolean value) { - if (value == null) { - return None; - } - return value ? True : False; - } - - public static @NotNull BooleanOption fromOption(@NotNull Option option) { - if (option.isDefined()) { - return some(option.get()); - } else { - return None; - } - } - - public boolean isDefined() { - return isDefined; - } - - public boolean isEmpty() { - return !isDefined; - } - - /** - * Returns the {@code Option}'s value. - * - * @return the {@code Option}'s value - * @throws NoSuchElementException if the {@code Option} is empty - */ - @Flow(sourceIsContainer = true) - public boolean get() { - if (isDefined) { - return value; - } else { - throw new NoSuchElementException("OptionBoolean.None.get()"); - } - } - - public @Nullable Boolean getOrNull() { - return isDefined ? value : null; - } - - public @NotNull BooleanOption getOption() { - return this; - } - - @Override - public @NotNull BooleanIterator iterator() { - return isDefined ? BooleanIterator.of(value) : BooleanIterator.empty(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o instanceof Option other) { - if (this.isEmpty()) return other.isEmpty(); - if (other.isEmpty()) return false; - - Object v = other.get(); - return v instanceof Boolean && get() == (Boolean) v; - } - - return false; - } - - @Override - public int hashCode() { - return this.hashCode; - } - - @Override - public String toString() { - return name; - } - - @Serial - private Object readResolve() { - if (isDefined) { - return value ? True : False; - } else { - return None; - } - } -} - +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control.primitive; + +import kala.annotations.ReplaceWith; +import kala.control.Option; +import kala.collection.base.primitive.BooleanIterator; +import kala.collection.base.primitive.BooleanTraversable; +import org.intellij.lang.annotations.Flow; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.Serial; +import java.util.NoSuchElementException; + +public final class BooleanOption implements PrimitiveOption, BooleanTraversable { + @Serial + private static final long serialVersionUID = 3226319253753655469L; + private static final int HASH_MAGIC = 773806848; + + public static final BooleanOption True = new BooleanOption(true); + public static final BooleanOption False = new BooleanOption(false); + public static final BooleanOption None = new BooleanOption(); + + private final boolean isDefined; + private final boolean value; + private final transient int hashCode; + private final transient String name; + + private BooleanOption() { + this.isDefined = false; + this.value = false; + this.name = "OptionBoolean.None"; + this.hashCode = NONE_HASH; + } + + private BooleanOption(boolean value) { + this.isDefined = true; + this.value = value; + this.name = value ? "OptionBoolean.True" : "OptionBoolean.False"; + this.hashCode = HASH_MAGIC + Boolean.hashCode(value); + } + + public static @NotNull BooleanOption some(boolean value) { + return value ? True : False; + } + + public static @NotNull BooleanOption none() { + return None; + } + + @Deprecated + @ReplaceWith("some(boolean)") + public static @NotNull BooleanOption of(boolean value) { + return value ? True : False; + } + + @Deprecated + @ReplaceWith("ofNullable(Boolean)") + public static @NotNull BooleanOption of(@Nullable Boolean value) { + return ofNullable(value); + } + + public static @NotNull BooleanOption ofNullable(@Nullable Boolean value) { + if (value == null) { + return None; + } + return value ? True : False; + } + + public static @NotNull BooleanOption fromOption(@NotNull Option option) { + if (option.isDefined()) { + return some(option.get()); + } else { + return None; + } + } + + public boolean isDefined() { + return isDefined; + } + + public boolean isEmpty() { + return !isDefined; + } + + /** + * Returns the {@code Option}'s value. + * + * @return the {@code Option}'s value + * @throws NoSuchElementException if the {@code Option} is empty + */ + @Flow(sourceIsContainer = true) + public boolean get() { + if (isDefined) { + return value; + } else { + throw new NoSuchElementException("OptionBoolean.None.get()"); + } + } + + public @Nullable Boolean getOrNull() { + return isDefined ? value : null; + } + + public @NotNull BooleanOption getOption() { + return this; + } + + @Override + public @NotNull BooleanIterator iterator() { + return isDefined ? BooleanIterator.of(value) : BooleanIterator.empty(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof Option other) { + if (this.isEmpty()) return other.isEmpty(); + if (other.isEmpty()) return false; + + Object v = other.get(); + return v instanceof Boolean && get() == (Boolean) v; + } + + return false; + } + + @Override + public int hashCode() { + return this.hashCode; + } + + @Override + public String toString() { + return name; + } + + @Serial + private Object readResolve() { + if (isDefined) { + return value ? True : False; + } else { + return None; + } + } +} + diff --git a/kala-base/src/main/java/kala/function/IndexedConsumer.java b/kala-base/src/main/java/kala/function/IndexedConsumer.java index ed5f7a1e..73085f19 100644 --- a/kala-base/src/main/java/kala/function/IndexedConsumer.java +++ b/kala-base/src/main/java/kala/function/IndexedConsumer.java @@ -1,36 +1,36 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.function; - -/** - * Represents an operation that accepts an index and an object-valued argument, and returns no result. - * - *

This is a functional interface whose functional method is {@link #accept(int, Object)}. - * - * @param the type of the input to the operation - * @author Glavo - */ -@FunctionalInterface -public interface IndexedConsumer { - - /** - * Performs this operation on the given argument. - * - * @param index the index of {@code t} in the container - * @param t the input argument - */ - void accept(int index, T t); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.function; + +/** + * Represents an operation that accepts an index and an object-valued argument, and returns no result. + * + *

This is a functional interface whose functional method is {@link #accept(int, Object)}. + * + * @param the type of the input to the operation + * @author Glavo + */ +@FunctionalInterface +public interface IndexedConsumer { + + /** + * Performs this operation on the given argument. + * + * @param index the index of {@code t} in the container + * @param t the input argument + */ + void accept(int index, T t); +} diff --git a/kala-base/src/main/java/kala/function/IndexedFunction.java b/kala-base/src/main/java/kala/function/IndexedFunction.java index 277f2cb9..42ce9531 100644 --- a/kala-base/src/main/java/kala/function/IndexedFunction.java +++ b/kala-base/src/main/java/kala/function/IndexedFunction.java @@ -1,38 +1,38 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.function; - -/** - * Represents a function that accepts an index and an object-valued argument, and produces a result. - * - *

This is a functional interface whose functional method is {@link #apply(int, Object)}. - * - * @param the type of the input to the function - * @param the type of the result of the function - * @author Glavo - */ -@FunctionalInterface -public interface IndexedFunction { - - /** - * Applies this function to the given argument. - * - * @param index the index of {@code t} in the container - * @param t the function argument - * @return the function result - */ - R apply(int index, T t); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.function; + +/** + * Represents a function that accepts an index and an object-valued argument, and produces a result. + * + *

This is a functional interface whose functional method is {@link #apply(int, Object)}. + * + * @param the type of the input to the function + * @param the type of the result of the function + * @author Glavo + */ +@FunctionalInterface +public interface IndexedFunction { + + /** + * Applies this function to the given argument. + * + * @param index the index of {@code t} in the container + * @param t the function argument + * @return the function result + */ + R apply(int index, T t); +} diff --git a/kala-base/src/main/java/kala/function/IntIntBiFunction.java b/kala-base/src/main/java/kala/function/IntIntBiFunction.java index fa68c759..825cbbb8 100644 --- a/kala-base/src/main/java/kala/function/IntIntBiFunction.java +++ b/kala-base/src/main/java/kala/function/IntIntBiFunction.java @@ -1,21 +1,21 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.function; - -@FunctionalInterface -public interface IntIntBiFunction { - R apply(int i1, int i2); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.function; + +@FunctionalInterface +public interface IntIntBiFunction { + R apply(int i1, int i2); +} diff --git a/kala-base/src/main/java/kala/function/LargeIndexedConsumer.java b/kala-base/src/main/java/kala/function/LargeIndexedConsumer.java index 15125495..860037b7 100644 --- a/kala-base/src/main/java/kala/function/LargeIndexedConsumer.java +++ b/kala-base/src/main/java/kala/function/LargeIndexedConsumer.java @@ -1,36 +1,36 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.function; - -/** - * Represents an operation that accepts an index and an object-valued argument, and returns no result. - * - *

This is a functional interface whose functional method is {@link #accept(long, Object)}. - * - * @param the type of the input to the operation - * @author Glavo - */ -@FunctionalInterface -public interface LargeIndexedConsumer { - - /** - * Performs this operation on the given argument. - * - * @param index the index of {@code t} in the container - * @param t the input argument - */ - void accept(long index, T t); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.function; + +/** + * Represents an operation that accepts an index and an object-valued argument, and returns no result. + * + *

This is a functional interface whose functional method is {@link #accept(long, Object)}. + * + * @param the type of the input to the operation + * @author Glavo + */ +@FunctionalInterface +public interface LargeIndexedConsumer { + + /** + * Performs this operation on the given argument. + * + * @param index the index of {@code t} in the container + * @param t the input argument + */ + void accept(long index, T t); +} diff --git a/kala-base/src/main/java/kala/function/LargeIndexedFunction.java b/kala-base/src/main/java/kala/function/LargeIndexedFunction.java index 3bec5f39..5b26171a 100644 --- a/kala-base/src/main/java/kala/function/LargeIndexedFunction.java +++ b/kala-base/src/main/java/kala/function/LargeIndexedFunction.java @@ -1,38 +1,38 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.function; - -/** - * Represents a function that accepts an index and an object-valued argument, and produces a result. - * - *

This is a functional interface whose functional method is {@link #apply(long, Object)}. - * - * @param the type of the input to the function - * @param the type of the result of the function - * @author Glavo - */ -@FunctionalInterface -public interface LargeIndexedFunction { - - /** - * Applies this function to the given argument. - * - * @param index the index of {@code t} in the container - * @param t the function argument - * @return the function result - */ - R apply(long index, T t); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.function; + +/** + * Represents a function that accepts an index and an object-valued argument, and produces a result. + * + *

This is a functional interface whose functional method is {@link #apply(long, Object)}. + * + * @param the type of the input to the function + * @param the type of the result of the function + * @author Glavo + */ +@FunctionalInterface +public interface LargeIndexedFunction { + + /** + * Applies this function to the given argument. + * + * @param index the index of {@code t} in the container + * @param t the function argument + * @return the function result + */ + R apply(long index, T t); +} diff --git a/kala-base/src/main/java/kala/function/package-info.java b/kala-base/src/main/java/kala/function/package-info.java index 35143c26..98d2129a 100644 --- a/kala-base/src/main/java/kala/function/package-info.java +++ b/kala-base/src/main/java/kala/function/package-info.java @@ -1,23 +1,23 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Provide functional interfaces not included in the {@link java.util.function}. - * - * @author Glavo - * @see java.util.function - */ +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provide functional interfaces not included in the {@link java.util.function}. + * + * @author Glavo + * @see java.util.function + */ package kala.function; \ No newline at end of file diff --git a/kala-base/src/main/java/kala/io/StdOut.java b/kala-base/src/main/java/kala/io/StdOut.java index 2d60f2d7..2de92cab 100644 --- a/kala-base/src/main/java/kala/io/StdOut.java +++ b/kala-base/src/main/java/kala/io/StdOut.java @@ -1,557 +1,557 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.io; - -import kala.annotations.StaticClass; -import org.jetbrains.annotations.NotNull; - -import java.io.PrintStream; -import java.util.Locale; - -/** - * Provide methods to simply output to the console. - */ -@StaticClass -public final class StdOut { - public static void print(Object x) { - if (x == null) { - System.out.print("null"); - } else if (x.getClass().isArray()) { - switch (x) { - case Object[] objects -> print(objects); - case char[] chars -> print(chars); - case boolean[] booleans -> print(booleans); - case byte[] bytes -> print(bytes); - case short[] shorts -> print(shorts); - case int[] ints -> print(ints); - case long[] longs -> print(longs); - case float[] floats -> print(floats); - case double[] doubles -> print(doubles); - default -> throw new AssertionError("Unknown array type: " + x.getClass()); - } - } else { - System.out.print(x); - } - } - - public static void print(String x) { - System.out.print(x); - } - - public static void print(char x) { - System.out.print(x); - } - - public static void print(boolean x) { - System.out.print(x); - } - - public static void print(byte x) { - System.out.print(x); - } - - public static void print(short x) { - System.out.print(x); - } - - public static void print(int x) { - System.out.print(x); - } - - public static void print(long x) { - System.out.print(x); - } - - public static void print(float x) { - System.out.print(x); - } - - public static void print(double x) { - System.out.print(x); - } - - public static void print(Object[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(char[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(boolean[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(byte[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(short[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(int[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(long[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(float[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void print(double[] array) { - if (array == null) { - System.out.print("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.print(']'); - } - } - - public static void println() { - System.out.println(); - } - - public static void println(Object x) { - if (x == null) { - System.out.println("null"); - } else if (x.getClass().isArray()) { - switch (x) { - case Object[] objects -> println(objects); - case char[] chars -> println(chars); - case boolean[] booleans -> println(booleans); - case byte[] bytes -> println(bytes); - case short[] shorts -> println(shorts); - case int[] ints -> println(ints); - case long[] longs -> println(longs); - case float[] floats -> println(floats); - case double[] doubles -> println(doubles); - default -> throw new AssertionError("Unknown array type: " + x.getClass()); - } - } else { - System.out.println(x); - } - } - - public static void println(String x) { - System.out.println(x); - } - - public static void println(char x) { - System.out.println(x); - } - - public static void println(boolean x) { - System.out.println(x); - } - - public static void println(byte x) { - System.out.println(x); - } - - public static void println(short x) { - System.out.println(x); - } - - public static void println(int x) { - System.out.println(x); - } - - public static void println(long x) { - System.out.println(x); - } - - public static void println(float x) { - System.out.println(x); - } - - public static void println(double x) { - System.out.println(x); - } - - public static void println(Object[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(char[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(boolean[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(byte[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(short[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(int[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(long[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(float[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void println(double[] array) { - if (array == null) { - System.out.println("null"); - return; - } - - final int size = array.length; - final PrintStream out = System.out; - - synchronized (out) { - out.print('['); - if (size > 0) { - out.print(array[0]); - for (int i = 1; i < size; i++) { - out.print(", "); - out.print(array[i]); - } - } - out.println(']'); - } - } - - public static void printf(@NotNull String format, Object... args) { - System.out.printf(format, args); - } - - public static void printf(Locale locale, @NotNull String format, Object... args) { - System.out.printf(locale, format, args); - } - - public static void flushStdout() { - System.out.flush(); - } - - private StdOut() { - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.io; + +import kala.annotations.StaticClass; +import org.jetbrains.annotations.NotNull; + +import java.io.PrintStream; +import java.util.Locale; + +/** + * Provide methods to simply output to the console. + */ +@StaticClass +public final class StdOut { + public static void print(Object x) { + if (x == null) { + System.out.print("null"); + } else if (x.getClass().isArray()) { + switch (x) { + case Object[] objects -> print(objects); + case char[] chars -> print(chars); + case boolean[] booleans -> print(booleans); + case byte[] bytes -> print(bytes); + case short[] shorts -> print(shorts); + case int[] ints -> print(ints); + case long[] longs -> print(longs); + case float[] floats -> print(floats); + case double[] doubles -> print(doubles); + default -> throw new AssertionError("Unknown array type: " + x.getClass()); + } + } else { + System.out.print(x); + } + } + + public static void print(String x) { + System.out.print(x); + } + + public static void print(char x) { + System.out.print(x); + } + + public static void print(boolean x) { + System.out.print(x); + } + + public static void print(byte x) { + System.out.print(x); + } + + public static void print(short x) { + System.out.print(x); + } + + public static void print(int x) { + System.out.print(x); + } + + public static void print(long x) { + System.out.print(x); + } + + public static void print(float x) { + System.out.print(x); + } + + public static void print(double x) { + System.out.print(x); + } + + public static void print(Object[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(char[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(boolean[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(byte[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(short[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(int[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(long[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(float[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void print(double[] array) { + if (array == null) { + System.out.print("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.print(']'); + } + } + + public static void println() { + System.out.println(); + } + + public static void println(Object x) { + if (x == null) { + System.out.println("null"); + } else if (x.getClass().isArray()) { + switch (x) { + case Object[] objects -> println(objects); + case char[] chars -> println(chars); + case boolean[] booleans -> println(booleans); + case byte[] bytes -> println(bytes); + case short[] shorts -> println(shorts); + case int[] ints -> println(ints); + case long[] longs -> println(longs); + case float[] floats -> println(floats); + case double[] doubles -> println(doubles); + default -> throw new AssertionError("Unknown array type: " + x.getClass()); + } + } else { + System.out.println(x); + } + } + + public static void println(String x) { + System.out.println(x); + } + + public static void println(char x) { + System.out.println(x); + } + + public static void println(boolean x) { + System.out.println(x); + } + + public static void println(byte x) { + System.out.println(x); + } + + public static void println(short x) { + System.out.println(x); + } + + public static void println(int x) { + System.out.println(x); + } + + public static void println(long x) { + System.out.println(x); + } + + public static void println(float x) { + System.out.println(x); + } + + public static void println(double x) { + System.out.println(x); + } + + public static void println(Object[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(char[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(boolean[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(byte[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(short[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(int[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(long[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(float[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void println(double[] array) { + if (array == null) { + System.out.println("null"); + return; + } + + final int size = array.length; + final PrintStream out = System.out; + + synchronized (out) { + out.print('['); + if (size > 0) { + out.print(array[0]); + for (int i = 1; i < size; i++) { + out.print(", "); + out.print(array[i]); + } + } + out.println(']'); + } + } + + public static void printf(@NotNull String format, Object... args) { + System.out.printf(format, args); + } + + public static void printf(Locale locale, @NotNull String format, Object... args) { + System.out.printf(locale, format, args); + } + + public static void flushStdout() { + System.out.flush(); + } + + private StdOut() { + } +} diff --git a/kala-base/src/main/java/kala/tuple/EmptyTuple.java b/kala-base/src/main/java/kala/tuple/EmptyTuple.java index 0ca98f4d..e936611c 100644 --- a/kala-base/src/main/java/kala/tuple/EmptyTuple.java +++ b/kala-base/src/main/java/kala/tuple/EmptyTuple.java @@ -1,42 +1,42 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import org.jetbrains.annotations.NotNull; - -import java.util.function.IntFunction; - -public sealed interface EmptyTuple extends Tuple permits Unit { - @Override - default int arity() { - return 0; - } - - @Override - default U elementAt(int index) { - throw new IndexOutOfBoundsException("EmptyTuple.elementAt()"); - } - - @Override - default U @NotNull [] toArray(@NotNull IntFunction generator) { - return generator.apply(0); - } - - @Override - default @NotNull Tuple1 cons(H head) { - return new Tuple1<>(head); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.IntFunction; + +public sealed interface EmptyTuple extends Tuple permits Unit { + @Override + default int arity() { + return 0; + } + + @Override + default U elementAt(int index) { + throw new IndexOutOfBoundsException("EmptyTuple.elementAt()"); + } + + @Override + default U @NotNull [] toArray(@NotNull IntFunction generator) { + return generator.apply(0); + } + + @Override + default @NotNull Tuple1 cons(H head) { + return new Tuple1<>(head); + } +} diff --git a/kala-base/src/main/java/kala/tuple/HList.java b/kala-base/src/main/java/kala/tuple/HList.java index c4dfe19a..b28ccd1a 100644 --- a/kala-base/src/main/java/kala/tuple/HList.java +++ b/kala-base/src/main/java/kala/tuple/HList.java @@ -1,53 +1,53 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.NotNull; - -/** - * The base class of heterogeneous lists. - * When the number of elements is 9 or less, use TupleN, otherwise use TupleXXL to store values in an array. - * Elements are compactly stored in any case. - * - *

{@code TupleN} is equivalent to - * {@code TList>>>}. - * The latter type notation can type-safely reference a tuple of unlimited length. - * - * @param the type of the head element - * @param - * @author Glavo - */ -public sealed interface HList<@Covariant H, @Covariant T extends Tuple> extends NonEmptyTuple - permits Tuple1, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tuple9, TupleXXL { - /** - * Returns the head of this heterogeneous list. - * - * @return the head of this heterogeneous list - */ - H head(); - - /** - * Returns the tail of this heterogeneous list. - * - * @return the tail of this heterogeneous list - */ - @NotNull - T tail(); - - @Override - @NotNull HList> cons(HH head); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.NotNull; + +/** + * The base class of heterogeneous lists. + * When the number of elements is 9 or less, use TupleN, otherwise use TupleXXL to store values in an array. + * Elements are compactly stored in any case. + * + *

{@code TupleN} is equivalent to + * {@code TList>>>}. + * The latter type notation can type-safely reference a tuple of unlimited length. + * + * @param the type of the head element + * @param + * @author Glavo + */ +public sealed interface HList<@Covariant H, @Covariant T extends Tuple> extends NonEmptyTuple + permits Tuple1, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tuple9, TupleXXL { + /** + * Returns the head of this heterogeneous list. + * + * @return the head of this heterogeneous list + */ + H head(); + + /** + * Returns the tail of this heterogeneous list. + * + * @return the tail of this heterogeneous list + */ + @NotNull + T tail(); + + @Override + @NotNull HList> cons(HH head); +} diff --git a/kala-base/src/main/java/kala/tuple/NonEmptyTuple.java b/kala-base/src/main/java/kala/tuple/NonEmptyTuple.java index 6c94aa7d..c4d3a9ac 100644 --- a/kala-base/src/main/java/kala/tuple/NonEmptyTuple.java +++ b/kala-base/src/main/java/kala/tuple/NonEmptyTuple.java @@ -1,24 +1,24 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import org.jetbrains.annotations.NotNull; - -public sealed interface NonEmptyTuple extends Tuple permits HList { - Object head(); - - @NotNull Tuple tail(); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import org.jetbrains.annotations.NotNull; + +public sealed interface NonEmptyTuple extends Tuple permits HList { + Object head(); + + @NotNull Tuple tail(); +} diff --git a/kala-base/src/main/java/kala/tuple/Tuple.java b/kala-base/src/main/java/kala/tuple/Tuple.java index 63958760..b84cf7d8 100644 --- a/kala-base/src/main/java/kala/tuple/Tuple.java +++ b/kala-base/src/main/java/kala/tuple/Tuple.java @@ -1,1330 +1,1330 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Comparator; -import java.util.function.IntFunction; - -import kala.collection.base.GenericArrays; -import org.intellij.lang.annotations.Flow; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -/** - * The base class of all tuples. - * - * @author Glavo - * @see HList - */ -public sealed interface Tuple extends AnyTuple, Serializable permits EmptyTuple, NonEmptyTuple { - /** - * Returns the number of elements of this {@code Tuple}. - * - * @return the number of elements of this {@code Tuple} - */ - @Contract(pure = true) - int arity(); - - /** - * Returns the element at the specified position in this {@code Tuple}. - * - * @return the element at the specified position in this {@code Tuple} - * @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >= - * arity()}) - */ - @Contract(pure = true) - @Flow(sourceIsContainer = true) - U elementAt(int index); - - /** - * Return a new tuple by prepending the head to `this` tuple. - * - * @return a new tuple by prepending the head to `this` tuple - */ - @Contract(pure = true) - @NotNull HList cons(H head); - - /** - * Returns an array containing all the elements in this tuple. - * - * @return an array containing all the elements in this tuple - */ - @Contract(value = "-> new", pure = true) - default Object @NotNull [] toArray() { - return toArray(Object[]::new); - } - - default U @NotNull [] toArray(@NotNull Class type) { - return toArray(GenericArrays.generator(type)); - } - - /** - * Returns an array containing all the elements in this tuple, using the provided {@code - * generator} function to allocate the returned array. - * - * @return an array containing all the elements in this tuple - * @throws ArrayStoreException if any element of this tuple cannot be stored in the generated - * array because the runtime type does not match - */ - @Contract(pure = true) - U @NotNull [] toArray(@NotNull IntFunction generator); - - static @NotNull Unit empty() { - return Unit.INSTANCE; - } - - static @NotNull Unit of() { - return Unit.INSTANCE; - } - - /** - * Creates a tuple of 1 element. - * - * @param type of the 1st element - * @param t1 the 1st element - * @return a tuple of 1 element - */ - @Contract("_ -> new") - static @NotNull Tuple1 of(T1 t1) { - return new Tuple1<>(t1); - } - - /** - * Creates a tuple of 2 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param t1 the 1st element - * @param t2 the 2nd element - * @return a tuple of 2 elements - */ - @Contract("_, _ -> new") - static @NotNull Tuple2 of(T1 t1, T2 t2) { - return new Tuple2<>(t1, t2); - } - - /** - * Creates a tuple of 3 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @return a tuple of 3 elements - */ - @Contract("_, _, _ -> new") - static @NotNull Tuple3 of(T1 t1, T2 t2, T3 t3) { - return new Tuple3<>(t1, t2, t3); - } - - /** - * Creates a tuple of 4 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @return a tuple of 4 elements - */ - @Contract("_, _, _, _ -> new") - static @NotNull Tuple4 of(T1 t1, T2 t2, T3 t3, T4 t4) { - return new Tuple4<>(t1, t2, t3, t4); - } - - /** - * Creates a tuple of 5 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @param t5 the 5th element - * @return a tuple of 5 elements - */ - @Contract("_, _, _, _, _ -> new") - static @NotNull Tuple5 of( - T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { - return new Tuple5<>(t1, t2, t3, t4, t5); - } - - /** - * Creates a tuple of 6 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @param t5 the 5th element - * @param t6 the 6th element - * @return a tuple of 6 elements - */ - @Contract("_, _, _, _, _, _ -> new") - static @NotNull Tuple6 of( - T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { - return new Tuple6<>(t1, t2, t3, t4, t5, t6); - } - - /** - * Creates a tuple of 7 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param type of the 7th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @param t5 the 5th element - * @param t6 the 6th element - * @param t7 the 7th element - * @return a tuple of 7 elements - */ - @Contract("_, _, _, _, _, _, _ -> new") - static @NotNull Tuple7 of( - T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { - return new Tuple7<>(t1, t2, t3, t4, t5, t6, t7); - } - - /** - * Creates a tuple of 8 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param type of the 7th element - * @param type of the 8th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @param t5 the 5th element - * @param t6 the 6th element - * @param t7 the 7th element - * @param t8 the 8th element - * @return a tuple of 8 elements - */ - @Contract("_, _, _, _, _, _, _, _ -> new") - static @NotNull Tuple8 of( - T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { - return new Tuple8<>(t1, t2, t3, t4, t5, t6, t7, t8); - } - - /** - * Creates a tuple of 9 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param type of the 7th element - * @param type of the 8th element - * @param type of the 9th element - * @param t1 the 1st element - * @param t2 the 2nd element - * @param t3 the 3rd element - * @param t4 the 4th element - * @param t5 the 5th element - * @param t6 the 6th element - * @param t7 the 7th element - * @param t8 the 8th element - * @param t9 the 9th element - * @return a tuple of 9 elements - */ - @Contract("_, _, _, _, _, _, _, _, _ -> new") - static - @NotNull Tuple9 of( - T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { - return new Tuple9<>(t1, t2, t3, t4, t5, t6, t7, t8, t9); - } - - @SuppressWarnings("unchecked") - @Contract("_ -> new") - static @NotNull T of(Object... values) { - return switch (values.length) { - case 0 -> (T) Unit.INSTANCE; - case 1 -> (T) new Tuple1<>(values[0]); - case 2 -> (T) new Tuple2<>(values[0], values[1]); - case 3 -> (T) new Tuple3<>(values[0], values[1], values[2]); - case 4 -> (T) new Tuple4<>(values[0], values[1], values[2], values[3]); - case 5 -> (T) new Tuple5<>(values[0], values[1], values[2], values[3], values[4]); - case 6 -> (T) - new Tuple6<>( - values[0], values[1], values[2], values[3], values[4], values[5]); - case 7 -> (T) - new Tuple7<>( - values[0], values[1], values[2], values[3], values[4], values[5], - values[6]); - case 8 -> (T) - new Tuple8<>( - values[0], values[1], values[2], values[3], values[4], values[5], - values[6], values[7]); - case 9 -> (T) - new Tuple9<>( - values[0], values[1], values[2], values[3], values[4], values[5], - values[6], values[7], values[8]); - default -> (T) new TupleXXL(values.clone()); - }; - } - - /** - * Return the 1st element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 1st element of the {@code tuple} - */ - static T component1(@NotNull HList tuple) { - return tuple.elementAt(0); - } - - /** - * Return the 2nd element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 2nd element of the {@code tuple} - */ - static T component2(@NotNull HList> tuple) { - return tuple.elementAt(1); - } - - /** - * Return the 3rd element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 3rd element of the {@code tuple} - */ - static T component3( - @NotNull HList>> tuple) { - return tuple.elementAt(2); - } - - /** - * Return the 4th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 4th element of the {@code tuple} - */ - static T component4( - @NotNull - HList>>> tuple) { - return tuple.elementAt(3); - } - - /** - * Return the 5th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 5th element of the {@code tuple} - */ - static T component5( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>> - tuple) { - return tuple.elementAt(4); - } - - /** - * Return the 6th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 6th element of the {@code tuple} - */ - static T component6( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>> - tuple) { - return tuple.elementAt(5); - } - - /** - * Return the 7th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 7th element of the {@code tuple} - */ - static T component7( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>> - tuple) { - return tuple.elementAt(6); - } - - /** - * Return the 8th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 8th element of the {@code tuple} - */ - static T component8( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>> - tuple) { - return tuple.elementAt(7); - } - - /** - * Return the 9th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 9th element of the {@code tuple} - */ - static T component9( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>> - tuple) { - return tuple.elementAt(8); - } - - /** - * Return the 10th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 10th element of the {@code tuple} - */ - static T component10( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>> - tuple) { - return tuple.elementAt(9); - } - - /** - * Return the 11th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 11th element of the {@code tuple} - */ - static T component11( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>> - tuple) { - return tuple.elementAt(10); - } - - /** - * Return the 12th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 12th element of the {@code tuple} - */ - static T component12( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>> - tuple) { - return tuple.elementAt(11); - } - - /** - * Return the 13th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 13th element of the {@code tuple} - */ - static T component13( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(12); - } - - /** - * Return the 14th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 14th element of the {@code tuple} - */ - static T component14( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(13); - } - - /** - * Return the 15th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 15th element of the {@code tuple} - */ - static T component15( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(14); - } - - /** - * Return the 16th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 16th element of the {@code tuple} - */ - static T component16( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(15); - } - - /** - * Return the 17th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 17th element of the {@code tuple} - */ - static T component17( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(16); - } - - /** - * Return the 18th element of the {@code tuple}. - * - * @param type of the element - * @param tuple a {@code Tuple} - * @return the 18th element of the {@code tuple} - */ - static T component18( - @NotNull - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - ?, - ? extends - HList< - T, - ?>>>>>>>>>>>>>>>>>> - tuple) { - return tuple.elementAt(17); - } - - static @NotNull Comparator comparator() { - return (Comparator & Serializable) (u1, u2) -> 0; - } - - static @NotNull Comparator> comparator(@NotNull Comparator c1) { - return (Comparator> & Serializable) (t1, t2) -> c1.compare(t1.component1(), t2.component1()); - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - return c2.compare(t1.component2(), t2.component2()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - return c3.compare(t1.component3(), t2.component3()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - return c4.compare(t1.component4(), t2.component4()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4, - @NotNull Comparator c5 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - final int compare4 = c4.compare(t1.component4(), t2.component4()); - if (compare4 != 0) { - return compare4; - } - return c5.compare(t1.component5(), t2.component5()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4, - @NotNull Comparator c5, - @NotNull Comparator c6 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - final int compare4 = c4.compare(t1.component4(), t2.component4()); - if (compare4 != 0) { - return compare4; - } - final int compare5 = c5.compare(t1.component5(), t2.component5()); - if (compare5 != 0) { - return compare5; - } - return c6.compare(t1.component6(), t2.component6()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4, - @NotNull Comparator c5, - @NotNull Comparator c6, - @NotNull Comparator c7 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - final int compare4 = c4.compare(t1.component4(), t2.component4()); - if (compare4 != 0) { - return compare4; - } - final int compare5 = c5.compare(t1.component5(), t2.component5()); - if (compare5 != 0) { - return compare5; - } - final int compare6 = c6.compare(t1.component6(), t2.component6()); - if (compare6 != 0) { - return compare6; - } - return c7.compare(t1.component7(), t2.component7()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4, - @NotNull Comparator c5, - @NotNull Comparator c6, - @NotNull Comparator c7, - @NotNull Comparator c8 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - final int compare4 = c4.compare(t1.component4(), t2.component4()); - if (compare4 != 0) { - return compare4; - } - final int compare5 = c5.compare(t1.component5(), t2.component5()); - if (compare5 != 0) { - return compare5; - } - final int compare6 = c6.compare(t1.component6(), t2.component6()); - if (compare6 != 0) { - return compare6; - } - final int compare7 = c7.compare(t1.component7(), t2.component7()); - if (compare7 != 0) { - return compare7; - } - return c8.compare(t1.component8(), t2.component8()); - }; - } - - static @NotNull Comparator> comparator( - @NotNull Comparator c1, - @NotNull Comparator c2, - @NotNull Comparator c3, - @NotNull Comparator c4, - @NotNull Comparator c5, - @NotNull Comparator c6, - @NotNull Comparator c7, - @NotNull Comparator c8, - @NotNull Comparator c9 - ) { - return (Comparator> & Serializable) (t1, t2) -> { - final int compare1 = c1.compare(t1.component1(), t2.component1()); - if (compare1 != 0) { - return compare1; - } - final int compare2 = c2.compare(t1.component2(), t2.component2()); - if (compare2 != 0) { - return compare2; - } - final int compare3 = c3.compare(t1.component3(), t2.component3()); - if (compare3 != 0) { - return compare3; - } - final int compare4 = c4.compare(t1.component4(), t2.component4()); - if (compare4 != 0) { - return compare4; - } - final int compare5 = c5.compare(t1.component5(), t2.component5()); - if (compare5 != 0) { - return compare5; - } - final int compare6 = c6.compare(t1.component6(), t2.component6()); - if (compare6 != 0) { - return compare6; - } - final int compare7 = c7.compare(t1.component7(), t2.component7()); - if (compare7 != 0) { - return compare7; - } - final int compare8 = c8.compare(t1.component8(), t2.component8()); - if (compare8 != 0) { - return compare8; - } - return c9.compare(t1.component9(), t2.component9()); - }; - } - - @SuppressWarnings("unchecked") - static @NotNull Comparator comparator(@NotNull Comparator... comparators) { - final int n = comparators.length; - return switch (n) { - case 0 -> (Comparator) comparator(); - case 1 -> (Comparator) comparator(comparators[0]); - case 2 -> (Comparator) comparator(comparators[0], comparators[1]); - case 3 -> (Comparator) comparator(comparators[0], comparators[1], comparators[2]); - case 4 -> (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3]); - case 5 -> - (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4]); - case 6 -> - (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5]); - case 7 -> - (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6]); - case 8 -> - (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6], comparators[7]); - case 9 -> - (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6], comparators[7], comparators[8]); - default -> { - final class ComparatorN implements Comparator, Serializable { - @Serial - private static final long serialVersionUID = 0L; - private final @NotNull Comparator[] comparators; - - private ComparatorN(@NotNull Comparator[] comparators) { - this.comparators = comparators; - } - - @Override - public int compare(Tuple o1, Tuple o2) { - final Comparator[] comparators = this.comparators; - final int n = comparators.length; - if (o1.arity() != n || o2.arity() != n) { - throw new ClassCastException(); - } - for (int i = 0; i < n; i++) { - @SuppressWarnings("unchecked") final Comparator c = (Comparator) comparators[i]; - final int res = c.compare(o1.elementAt(i), o2.elementAt(i)); - if (res != 0) { - return res; - } - } - return 0; - } - - @Override - public boolean equals(Object obj) { - return this == obj || obj instanceof ComparatorN cn && Arrays.equals(this.comparators, cn.comparators); - } - } - yield (Comparator) new ComparatorN(comparators.clone()); - } - }; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Comparator; +import java.util.function.IntFunction; + +import kala.collection.base.GenericArrays; +import org.intellij.lang.annotations.Flow; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +/** + * The base class of all tuples. + * + * @author Glavo + * @see HList + */ +public sealed interface Tuple extends AnyTuple, Serializable permits EmptyTuple, NonEmptyTuple { + /** + * Returns the number of elements of this {@code Tuple}. + * + * @return the number of elements of this {@code Tuple} + */ + @Contract(pure = true) + int arity(); + + /** + * Returns the element at the specified position in this {@code Tuple}. + * + * @return the element at the specified position in this {@code Tuple} + * @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >= + * arity()}) + */ + @Contract(pure = true) + @Flow(sourceIsContainer = true) + U elementAt(int index); + + /** + * Return a new tuple by prepending the head to `this` tuple. + * + * @return a new tuple by prepending the head to `this` tuple + */ + @Contract(pure = true) + @NotNull HList cons(H head); + + /** + * Returns an array containing all the elements in this tuple. + * + * @return an array containing all the elements in this tuple + */ + @Contract(value = "-> new", pure = true) + default Object @NotNull [] toArray() { + return toArray(Object[]::new); + } + + default U @NotNull [] toArray(@NotNull Class type) { + return toArray(GenericArrays.generator(type)); + } + + /** + * Returns an array containing all the elements in this tuple, using the provided {@code + * generator} function to allocate the returned array. + * + * @return an array containing all the elements in this tuple + * @throws ArrayStoreException if any element of this tuple cannot be stored in the generated + * array because the runtime type does not match + */ + @Contract(pure = true) + U @NotNull [] toArray(@NotNull IntFunction generator); + + static @NotNull Unit empty() { + return Unit.INSTANCE; + } + + static @NotNull Unit of() { + return Unit.INSTANCE; + } + + /** + * Creates a tuple of 1 element. + * + * @param type of the 1st element + * @param t1 the 1st element + * @return a tuple of 1 element + */ + @Contract("_ -> new") + static @NotNull Tuple1 of(T1 t1) { + return new Tuple1<>(t1); + } + + /** + * Creates a tuple of 2 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param t1 the 1st element + * @param t2 the 2nd element + * @return a tuple of 2 elements + */ + @Contract("_, _ -> new") + static @NotNull Tuple2 of(T1 t1, T2 t2) { + return new Tuple2<>(t1, t2); + } + + /** + * Creates a tuple of 3 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @return a tuple of 3 elements + */ + @Contract("_, _, _ -> new") + static @NotNull Tuple3 of(T1 t1, T2 t2, T3 t3) { + return new Tuple3<>(t1, t2, t3); + } + + /** + * Creates a tuple of 4 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @return a tuple of 4 elements + */ + @Contract("_, _, _, _ -> new") + static @NotNull Tuple4 of(T1 t1, T2 t2, T3 t3, T4 t4) { + return new Tuple4<>(t1, t2, t3, t4); + } + + /** + * Creates a tuple of 5 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @param t5 the 5th element + * @return a tuple of 5 elements + */ + @Contract("_, _, _, _, _ -> new") + static @NotNull Tuple5 of( + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + return new Tuple5<>(t1, t2, t3, t4, t5); + } + + /** + * Creates a tuple of 6 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @param t5 the 5th element + * @param t6 the 6th element + * @return a tuple of 6 elements + */ + @Contract("_, _, _, _, _, _ -> new") + static @NotNull Tuple6 of( + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { + return new Tuple6<>(t1, t2, t3, t4, t5, t6); + } + + /** + * Creates a tuple of 7 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param type of the 7th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @param t5 the 5th element + * @param t6 the 6th element + * @param t7 the 7th element + * @return a tuple of 7 elements + */ + @Contract("_, _, _, _, _, _, _ -> new") + static @NotNull Tuple7 of( + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { + return new Tuple7<>(t1, t2, t3, t4, t5, t6, t7); + } + + /** + * Creates a tuple of 8 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param type of the 7th element + * @param type of the 8th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @param t5 the 5th element + * @param t6 the 6th element + * @param t7 the 7th element + * @param t8 the 8th element + * @return a tuple of 8 elements + */ + @Contract("_, _, _, _, _, _, _, _ -> new") + static @NotNull Tuple8 of( + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { + return new Tuple8<>(t1, t2, t3, t4, t5, t6, t7, t8); + } + + /** + * Creates a tuple of 9 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param type of the 7th element + * @param type of the 8th element + * @param type of the 9th element + * @param t1 the 1st element + * @param t2 the 2nd element + * @param t3 the 3rd element + * @param t4 the 4th element + * @param t5 the 5th element + * @param t6 the 6th element + * @param t7 the 7th element + * @param t8 the 8th element + * @param t9 the 9th element + * @return a tuple of 9 elements + */ + @Contract("_, _, _, _, _, _, _, _, _ -> new") + static + @NotNull Tuple9 of( + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { + return new Tuple9<>(t1, t2, t3, t4, t5, t6, t7, t8, t9); + } + + @SuppressWarnings("unchecked") + @Contract("_ -> new") + static @NotNull T of(Object... values) { + return switch (values.length) { + case 0 -> (T) Unit.INSTANCE; + case 1 -> (T) new Tuple1<>(values[0]); + case 2 -> (T) new Tuple2<>(values[0], values[1]); + case 3 -> (T) new Tuple3<>(values[0], values[1], values[2]); + case 4 -> (T) new Tuple4<>(values[0], values[1], values[2], values[3]); + case 5 -> (T) new Tuple5<>(values[0], values[1], values[2], values[3], values[4]); + case 6 -> (T) + new Tuple6<>( + values[0], values[1], values[2], values[3], values[4], values[5]); + case 7 -> (T) + new Tuple7<>( + values[0], values[1], values[2], values[3], values[4], values[5], + values[6]); + case 8 -> (T) + new Tuple8<>( + values[0], values[1], values[2], values[3], values[4], values[5], + values[6], values[7]); + case 9 -> (T) + new Tuple9<>( + values[0], values[1], values[2], values[3], values[4], values[5], + values[6], values[7], values[8]); + default -> (T) new TupleXXL(values.clone()); + }; + } + + /** + * Return the 1st element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 1st element of the {@code tuple} + */ + static T component1(@NotNull HList tuple) { + return tuple.elementAt(0); + } + + /** + * Return the 2nd element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 2nd element of the {@code tuple} + */ + static T component2(@NotNull HList> tuple) { + return tuple.elementAt(1); + } + + /** + * Return the 3rd element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 3rd element of the {@code tuple} + */ + static T component3( + @NotNull HList>> tuple) { + return tuple.elementAt(2); + } + + /** + * Return the 4th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 4th element of the {@code tuple} + */ + static T component4( + @NotNull + HList>>> tuple) { + return tuple.elementAt(3); + } + + /** + * Return the 5th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 5th element of the {@code tuple} + */ + static T component5( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>> + tuple) { + return tuple.elementAt(4); + } + + /** + * Return the 6th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 6th element of the {@code tuple} + */ + static T component6( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>> + tuple) { + return tuple.elementAt(5); + } + + /** + * Return the 7th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 7th element of the {@code tuple} + */ + static T component7( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>> + tuple) { + return tuple.elementAt(6); + } + + /** + * Return the 8th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 8th element of the {@code tuple} + */ + static T component8( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>> + tuple) { + return tuple.elementAt(7); + } + + /** + * Return the 9th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 9th element of the {@code tuple} + */ + static T component9( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>> + tuple) { + return tuple.elementAt(8); + } + + /** + * Return the 10th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 10th element of the {@code tuple} + */ + static T component10( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>> + tuple) { + return tuple.elementAt(9); + } + + /** + * Return the 11th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 11th element of the {@code tuple} + */ + static T component11( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>> + tuple) { + return tuple.elementAt(10); + } + + /** + * Return the 12th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 12th element of the {@code tuple} + */ + static T component12( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>> + tuple) { + return tuple.elementAt(11); + } + + /** + * Return the 13th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 13th element of the {@code tuple} + */ + static T component13( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(12); + } + + /** + * Return the 14th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 14th element of the {@code tuple} + */ + static T component14( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(13); + } + + /** + * Return the 15th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 15th element of the {@code tuple} + */ + static T component15( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(14); + } + + /** + * Return the 16th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 16th element of the {@code tuple} + */ + static T component16( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(15); + } + + /** + * Return the 17th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 17th element of the {@code tuple} + */ + static T component17( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(16); + } + + /** + * Return the 18th element of the {@code tuple}. + * + * @param type of the element + * @param tuple a {@code Tuple} + * @return the 18th element of the {@code tuple} + */ + static T component18( + @NotNull + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + ?, + ? extends + HList< + T, + ?>>>>>>>>>>>>>>>>>> + tuple) { + return tuple.elementAt(17); + } + + static @NotNull Comparator comparator() { + return (Comparator & Serializable) (u1, u2) -> 0; + } + + static @NotNull Comparator> comparator(@NotNull Comparator c1) { + return (Comparator> & Serializable) (t1, t2) -> c1.compare(t1.component1(), t2.component1()); + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + return c2.compare(t1.component2(), t2.component2()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + return c3.compare(t1.component3(), t2.component3()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + return c4.compare(t1.component4(), t2.component4()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4, + @NotNull Comparator c5 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + final int compare4 = c4.compare(t1.component4(), t2.component4()); + if (compare4 != 0) { + return compare4; + } + return c5.compare(t1.component5(), t2.component5()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4, + @NotNull Comparator c5, + @NotNull Comparator c6 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + final int compare4 = c4.compare(t1.component4(), t2.component4()); + if (compare4 != 0) { + return compare4; + } + final int compare5 = c5.compare(t1.component5(), t2.component5()); + if (compare5 != 0) { + return compare5; + } + return c6.compare(t1.component6(), t2.component6()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4, + @NotNull Comparator c5, + @NotNull Comparator c6, + @NotNull Comparator c7 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + final int compare4 = c4.compare(t1.component4(), t2.component4()); + if (compare4 != 0) { + return compare4; + } + final int compare5 = c5.compare(t1.component5(), t2.component5()); + if (compare5 != 0) { + return compare5; + } + final int compare6 = c6.compare(t1.component6(), t2.component6()); + if (compare6 != 0) { + return compare6; + } + return c7.compare(t1.component7(), t2.component7()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4, + @NotNull Comparator c5, + @NotNull Comparator c6, + @NotNull Comparator c7, + @NotNull Comparator c8 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + final int compare4 = c4.compare(t1.component4(), t2.component4()); + if (compare4 != 0) { + return compare4; + } + final int compare5 = c5.compare(t1.component5(), t2.component5()); + if (compare5 != 0) { + return compare5; + } + final int compare6 = c6.compare(t1.component6(), t2.component6()); + if (compare6 != 0) { + return compare6; + } + final int compare7 = c7.compare(t1.component7(), t2.component7()); + if (compare7 != 0) { + return compare7; + } + return c8.compare(t1.component8(), t2.component8()); + }; + } + + static @NotNull Comparator> comparator( + @NotNull Comparator c1, + @NotNull Comparator c2, + @NotNull Comparator c3, + @NotNull Comparator c4, + @NotNull Comparator c5, + @NotNull Comparator c6, + @NotNull Comparator c7, + @NotNull Comparator c8, + @NotNull Comparator c9 + ) { + return (Comparator> & Serializable) (t1, t2) -> { + final int compare1 = c1.compare(t1.component1(), t2.component1()); + if (compare1 != 0) { + return compare1; + } + final int compare2 = c2.compare(t1.component2(), t2.component2()); + if (compare2 != 0) { + return compare2; + } + final int compare3 = c3.compare(t1.component3(), t2.component3()); + if (compare3 != 0) { + return compare3; + } + final int compare4 = c4.compare(t1.component4(), t2.component4()); + if (compare4 != 0) { + return compare4; + } + final int compare5 = c5.compare(t1.component5(), t2.component5()); + if (compare5 != 0) { + return compare5; + } + final int compare6 = c6.compare(t1.component6(), t2.component6()); + if (compare6 != 0) { + return compare6; + } + final int compare7 = c7.compare(t1.component7(), t2.component7()); + if (compare7 != 0) { + return compare7; + } + final int compare8 = c8.compare(t1.component8(), t2.component8()); + if (compare8 != 0) { + return compare8; + } + return c9.compare(t1.component9(), t2.component9()); + }; + } + + @SuppressWarnings("unchecked") + static @NotNull Comparator comparator(@NotNull Comparator... comparators) { + final int n = comparators.length; + return switch (n) { + case 0 -> (Comparator) comparator(); + case 1 -> (Comparator) comparator(comparators[0]); + case 2 -> (Comparator) comparator(comparators[0], comparators[1]); + case 3 -> (Comparator) comparator(comparators[0], comparators[1], comparators[2]); + case 4 -> (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3]); + case 5 -> + (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4]); + case 6 -> + (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5]); + case 7 -> + (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6]); + case 8 -> + (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6], comparators[7]); + case 9 -> + (Comparator) comparator(comparators[0], comparators[1], comparators[2], comparators[3], comparators[4], comparators[5], comparators[6], comparators[7], comparators[8]); + default -> { + final class ComparatorN implements Comparator, Serializable { + @Serial + private static final long serialVersionUID = 0L; + private final @NotNull Comparator[] comparators; + + private ComparatorN(@NotNull Comparator[] comparators) { + this.comparators = comparators; + } + + @Override + public int compare(Tuple o1, Tuple o2) { + final Comparator[] comparators = this.comparators; + final int n = comparators.length; + if (o1.arity() != n || o2.arity() != n) { + throw new ClassCastException(); + } + for (int i = 0; i < n; i++) { + @SuppressWarnings("unchecked") final Comparator c = (Comparator) comparators[i]; + final int res = c.compare(o1.elementAt(i), o2.elementAt(i)); + if (res != 0) { + return res; + } + } + return 0; + } + + @Override + public boolean equals(Object obj) { + return this == obj || obj instanceof ComparatorN cn && Arrays.equals(this.comparators, cn.comparators); + } + } + yield (Comparator) new ComparatorN(comparators.clone()); + } + }; + } +} diff --git a/kala-base/src/main/java/kala/tuple/Tuple2.java b/kala-base/src/main/java/kala/tuple/Tuple2.java index 7dec6467..4139758b 100644 --- a/kala-base/src/main/java/kala/tuple/Tuple2.java +++ b/kala-base/src/main/java/kala/tuple/Tuple2.java @@ -1,144 +1,144 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Map; -import java.util.Objects; -import java.util.function.IntFunction; - -/** - * A tuple of 2 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @author Glavo - */ -public record Tuple2<@Covariant T1, @Covariant T2>(T1 component1, T2 component2) implements HList>, Serializable, Map.Entry { - @Serial - private static final long serialVersionUID = 0L; - - @Contract(value = "_ -> param1", pure = true) - @SuppressWarnings("unchecked") - public static Tuple2 narrow( - HList> tuple) { - return (Tuple2) tuple; - } - - @Override - public int arity() { - return 2; - } - - @Override - @SuppressWarnings("unchecked") - public U elementAt(int index) { - return switch (index) { - case 0 -> (U) component1; - case 1 -> (U) component2; - default -> throw new IndexOutOfBoundsException("Index out of range: " + index); - }; - } - - @Override - @SuppressWarnings("unchecked") - public U @NotNull [] toArray(@NotNull IntFunction generator) { - U[] arr = generator.apply(arity()); - arr[0] = (U) this.component1; - arr[1] = (U) this.component2; - return arr; - } - - @Override - public T1 head() { - return component1; - } - - @Override - public @NotNull Tuple1 tail() { - return Tuple.of(component2); - } - - @Contract("_ -> new") - @Override - public @NotNull Tuple3 cons(H head) { - return new Tuple3<>(head, component1, component2); - } - - @Override - public T1 getKey() { - return component1; - } - - @Override - public T2 getValue() { - return component2; - } - - /** - * Used to override {@link Map # setValue}. - * Tuples are immutable, calling this method will always fail. - * - * @throws UnsupportedOperationException when calling this method - */ - @Override - @Deprecated - @Contract("_ -> fail") - public T2 setValue(T2 value) throws UnsupportedOperationException { - throw new UnsupportedOperationException("Tuple2.setValue"); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o instanceof Tuple2 other) { - return Objects.equals(this.component1, other.component1) && Objects.equals(this.component2, other.component2); - } - - if (o instanceof Map.Entry other) { - return Objects.equals(this.component1, other.getKey()) && Objects.equals(this.component2, other.getValue()); - } - - if (o instanceof AnyTuple other) { - return other.arity() == 2 - && Objects.equals(this.component1, other.elementAt(0)) - && Objects.equals(this.component2, other.elementAt(1)); - } - - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(component1) ^ Objects.hashCode(component2); - } - - @Override - public String toString() { - return "(" + component1 + ", " + component2 + ")" ; - } - - @Serial - private Object writeReplace() { - return new SerializedTuple(toArray()); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; +import java.util.function.IntFunction; + +/** + * A tuple of 2 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @author Glavo + */ +public record Tuple2<@Covariant T1, @Covariant T2>(T1 component1, T2 component2) implements HList>, Serializable, Map.Entry { + @Serial + private static final long serialVersionUID = 0L; + + @Contract(value = "_ -> param1", pure = true) + @SuppressWarnings("unchecked") + public static Tuple2 narrow( + HList> tuple) { + return (Tuple2) tuple; + } + + @Override + public int arity() { + return 2; + } + + @Override + @SuppressWarnings("unchecked") + public U elementAt(int index) { + return switch (index) { + case 0 -> (U) component1; + case 1 -> (U) component2; + default -> throw new IndexOutOfBoundsException("Index out of range: " + index); + }; + } + + @Override + @SuppressWarnings("unchecked") + public U @NotNull [] toArray(@NotNull IntFunction generator) { + U[] arr = generator.apply(arity()); + arr[0] = (U) this.component1; + arr[1] = (U) this.component2; + return arr; + } + + @Override + public T1 head() { + return component1; + } + + @Override + public @NotNull Tuple1 tail() { + return Tuple.of(component2); + } + + @Contract("_ -> new") + @Override + public @NotNull Tuple3 cons(H head) { + return new Tuple3<>(head, component1, component2); + } + + @Override + public T1 getKey() { + return component1; + } + + @Override + public T2 getValue() { + return component2; + } + + /** + * Used to override {@link Map # setValue}. + * Tuples are immutable, calling this method will always fail. + * + * @throws UnsupportedOperationException when calling this method + */ + @Override + @Deprecated + @Contract("_ -> fail") + public T2 setValue(T2 value) throws UnsupportedOperationException { + throw new UnsupportedOperationException("Tuple2.setValue"); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Tuple2 other) { + return Objects.equals(this.component1, other.component1) && Objects.equals(this.component2, other.component2); + } + + if (o instanceof Map.Entry other) { + return Objects.equals(this.component1, other.getKey()) && Objects.equals(this.component2, other.getValue()); + } + + if (o instanceof AnyTuple other) { + return other.arity() == 2 + && Objects.equals(this.component1, other.elementAt(0)) + && Objects.equals(this.component2, other.elementAt(1)); + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(component1) ^ Objects.hashCode(component2); + } + + @Override + public String toString() { + return "(" + component1 + ", " + component2 + ")" ; + } + + @Serial + private Object writeReplace() { + return new SerializedTuple(toArray()); + } +} diff --git a/kala-base/src/main/java/kala/tuple/Tuple8.java b/kala-base/src/main/java/kala/tuple/Tuple8.java index 92d41c94..7ee11c33 100644 --- a/kala-base/src/main/java/kala/tuple/Tuple8.java +++ b/kala-base/src/main/java/kala/tuple/Tuple8.java @@ -1,159 +1,159 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Objects; -import java.util.function.IntFunction; - -/** - * A tuple of 8 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param type of the 7th element - * @param type of the 8th element - * @author Glavo - */ -public record Tuple8<@Covariant T1, @Covariant T2, @Covariant T3, @Covariant T4, @Covariant T5, @Covariant T6, @Covariant T7, @Covariant T8>( - T1 component1, T2 component2, T3 component3, - T4 component4, T5 component5, T6 component6, - T7 component7, T8 component8 -) implements HList>, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - @SuppressWarnings("unchecked") - public static Tuple8 narrow( - HList>>>>>>> tuple) { - return (Tuple8) tuple; - } - - @Override - public int arity() { - return 8; - } - - @Override - @SuppressWarnings("unchecked") - public U elementAt(int index) { - return switch (index) { - case 0 -> (U) component1; - case 1 -> (U) component2; - case 2 -> (U) component3; - case 3 -> (U) component4; - case 4 -> (U) component5; - case 5 -> (U) component6; - case 6 -> (U) component7; - case 7 -> (U) component8; - default -> throw new IndexOutOfBoundsException("Index out of range: " + index); - }; - } - - @Override - @SuppressWarnings("unchecked") - public U @NotNull [] toArray(@NotNull IntFunction generator) { - U[] arr = generator.apply(arity()); - arr[0] = (U) this.component1; - arr[1] = (U) this.component2; - arr[2] = (U) this.component3; - arr[3] = (U) this.component4; - arr[4] = (U) this.component5; - arr[5] = (U) this.component6; - arr[6] = (U) this.component7; - arr[7] = (U) this.component8; - return arr; - } - - @Override - public T1 head() { - return component1; - } - - @Override - public @NotNull Tuple7 tail() { - return Tuple.of(component2, component3, component4, component5, component6, component7, component8); - } - - @Override - @Contract("_ -> new") - public @NotNull Tuple9 cons(H head) { - return new Tuple9<>(head, component1, component2, component3, component4, component5, component6, component7, component8); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o instanceof Tuple8 other) { - return Objects.equals(this.component1, other.component1) - && Objects.equals(this.component2, other.component2) - && Objects.equals(this.component3, other.component3) - && Objects.equals(this.component4, other.component4) - && Objects.equals(this.component5, other.component5) - && Objects.equals(this.component6, other.component6) - && Objects.equals(this.component7, other.component7) - && Objects.equals(this.component8, other.component8); - } - - if (o instanceof AnyTuple other) { - return other.arity() == 8 - && Objects.equals(this.component1, other.elementAt(0)) - && Objects.equals(this.component2, other.elementAt(1)) - && Objects.equals(this.component3, other.elementAt(2)) - && Objects.equals(this.component4, other.elementAt(3)) - && Objects.equals(this.component5, other.elementAt(4)) - && Objects.equals(this.component6, other.elementAt(5)) - && Objects.equals(this.component7, other.elementAt(6)) - && Objects.equals(this.component8, other.elementAt(7)); - } - - return false; - } - - @Override - public int hashCode() { - int hash = 0; - hash = 31 * hash + Objects.hashCode(component1); - hash = 31 * hash + Objects.hashCode(component2); - hash = 31 * hash + Objects.hashCode(component3); - hash = 31 * hash + Objects.hashCode(component4); - hash = 31 * hash + Objects.hashCode(component5); - hash = 31 * hash + Objects.hashCode(component6); - hash = 31 * hash + Objects.hashCode(component7); - hash = 31 * hash + Objects.hashCode(component8); - return hash; - } - - @Override - public String toString() { - return "(" + component1 + ", " + component2 + ", " + component3 + ", " + component4 + ", " + component5 + ", " + component6 + ", " + component7 + ", " + component8 + ")" ; - } - - @Serial - private Object writeReplace() { - return new SerializedTuple(toArray()); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Objects; +import java.util.function.IntFunction; + +/** + * A tuple of 8 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param type of the 7th element + * @param type of the 8th element + * @author Glavo + */ +public record Tuple8<@Covariant T1, @Covariant T2, @Covariant T3, @Covariant T4, @Covariant T5, @Covariant T6, @Covariant T7, @Covariant T8>( + T1 component1, T2 component2, T3 component3, + T4 component4, T5 component5, T6 component6, + T7 component7, T8 component8 +) implements HList>, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + @SuppressWarnings("unchecked") + public static Tuple8 narrow( + HList>>>>>>> tuple) { + return (Tuple8) tuple; + } + + @Override + public int arity() { + return 8; + } + + @Override + @SuppressWarnings("unchecked") + public U elementAt(int index) { + return switch (index) { + case 0 -> (U) component1; + case 1 -> (U) component2; + case 2 -> (U) component3; + case 3 -> (U) component4; + case 4 -> (U) component5; + case 5 -> (U) component6; + case 6 -> (U) component7; + case 7 -> (U) component8; + default -> throw new IndexOutOfBoundsException("Index out of range: " + index); + }; + } + + @Override + @SuppressWarnings("unchecked") + public U @NotNull [] toArray(@NotNull IntFunction generator) { + U[] arr = generator.apply(arity()); + arr[0] = (U) this.component1; + arr[1] = (U) this.component2; + arr[2] = (U) this.component3; + arr[3] = (U) this.component4; + arr[4] = (U) this.component5; + arr[5] = (U) this.component6; + arr[6] = (U) this.component7; + arr[7] = (U) this.component8; + return arr; + } + + @Override + public T1 head() { + return component1; + } + + @Override + public @NotNull Tuple7 tail() { + return Tuple.of(component2, component3, component4, component5, component6, component7, component8); + } + + @Override + @Contract("_ -> new") + public @NotNull Tuple9 cons(H head) { + return new Tuple9<>(head, component1, component2, component3, component4, component5, component6, component7, component8); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Tuple8 other) { + return Objects.equals(this.component1, other.component1) + && Objects.equals(this.component2, other.component2) + && Objects.equals(this.component3, other.component3) + && Objects.equals(this.component4, other.component4) + && Objects.equals(this.component5, other.component5) + && Objects.equals(this.component6, other.component6) + && Objects.equals(this.component7, other.component7) + && Objects.equals(this.component8, other.component8); + } + + if (o instanceof AnyTuple other) { + return other.arity() == 8 + && Objects.equals(this.component1, other.elementAt(0)) + && Objects.equals(this.component2, other.elementAt(1)) + && Objects.equals(this.component3, other.elementAt(2)) + && Objects.equals(this.component4, other.elementAt(3)) + && Objects.equals(this.component5, other.elementAt(4)) + && Objects.equals(this.component6, other.elementAt(5)) + && Objects.equals(this.component7, other.elementAt(6)) + && Objects.equals(this.component8, other.elementAt(7)); + } + + return false; + } + + @Override + public int hashCode() { + int hash = 0; + hash = 31 * hash + Objects.hashCode(component1); + hash = 31 * hash + Objects.hashCode(component2); + hash = 31 * hash + Objects.hashCode(component3); + hash = 31 * hash + Objects.hashCode(component4); + hash = 31 * hash + Objects.hashCode(component5); + hash = 31 * hash + Objects.hashCode(component6); + hash = 31 * hash + Objects.hashCode(component7); + hash = 31 * hash + Objects.hashCode(component8); + return hash; + } + + @Override + public String toString() { + return "(" + component1 + ", " + component2 + ", " + component3 + ", " + component4 + ", " + component5 + ", " + component6 + ", " + component7 + ", " + component8 + ")" ; + } + + @Serial + private Object writeReplace() { + return new SerializedTuple(toArray()); + } +} diff --git a/kala-base/src/main/java/kala/tuple/Tuple9.java b/kala-base/src/main/java/kala/tuple/Tuple9.java index 98ab7602..eb2c4688 100644 --- a/kala-base/src/main/java/kala/tuple/Tuple9.java +++ b/kala-base/src/main/java/kala/tuple/Tuple9.java @@ -1,177 +1,177 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import kala.annotations.Covariant; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Objects; -import java.util.function.IntFunction; - -/** - * A tuple of 9 elements. - * - * @param type of the 1st element - * @param type of the 2nd element - * @param type of the 3rd element - * @param type of the 4th element - * @param type of the 5th element - * @param type of the 6th element - * @param type of the 7th element - * @param type of the 8th element - * @param type of the 9th element - * @author Glavo - */ -public record Tuple9<@Covariant T1, @Covariant T2, @Covariant T3, @Covariant T4, @Covariant T5, @Covariant T6, @Covariant T7, @Covariant T8, @Covariant T9>( - T1 component1, T2 component2, T3 component3, - T4 component4, T5 component5, T6 component6, - T7 component7, T8 component8, T9 component9 -) implements HList>, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - @SuppressWarnings("unchecked") - public static Tuple9 narrow( - HList>>>>>>>> tuple) { - return (Tuple9) tuple; - } - - @Override - public int arity() { - return 9; - } - - @Override - @SuppressWarnings("unchecked") - public U elementAt(int index) { - return switch (index) { - case 0 -> (U) component1; - case 1 -> (U) component2; - case 2 -> (U) component3; - case 3 -> (U) component4; - case 4 -> (U) component5; - case 5 -> (U) component6; - case 6 -> (U) component7; - case 7 -> (U) component8; - case 8 -> (U) component9; - default -> throw new IndexOutOfBoundsException("Index out of range: " + index); - }; - } - - @Override - @SuppressWarnings("unchecked") - public U @NotNull [] toArray(@NotNull IntFunction generator) { - U[] arr = generator.apply(arity()); - arr[0] = (U) this.component1; - arr[1] = (U) this.component2; - arr[2] = (U) this.component3; - arr[3] = (U) this.component4; - arr[4] = (U) this.component5; - arr[5] = (U) this.component6; - arr[6] = (U) this.component7; - arr[7] = (U) this.component8; - arr[8] = (U) this.component9; - return arr; - } - - @Override - public T1 head() { - return component1; - } - - @Override - public @NotNull Tuple8 tail() { - return Tuple.of(component2, component3, component4, component5, component6, component7, component8, component9); - } - - @Override - @Contract("_ -> new") - @SuppressWarnings({"unchecked", "rawtypes"}) - public @NotNull HList> cons(H head) { - Object[] arr = new Object[10]; - arr[0] = head; - arr[1] = component1; - arr[2] = component2; - arr[3] = component3; - arr[4] = component4; - arr[5] = component5; - arr[6] = component6; - arr[7] = component7; - arr[8] = component8; - arr[9] = component9; - return (HList) new TupleXXL(arr); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o instanceof Tuple9 other) { - return Objects.equals(this.component1, other.component1) - && Objects.equals(this.component2, other.component2) - && Objects.equals(this.component3, other.component3) - && Objects.equals(this.component4, other.component4) - && Objects.equals(this.component5, other.component5) - && Objects.equals(this.component6, other.component6) - && Objects.equals(this.component7, other.component7) - && Objects.equals(this.component8, other.component8) - && Objects.equals(this.component9, other.component9); - } - - if (o instanceof AnyTuple other) { - return other.arity() == 9 - && Objects.equals(this.component1, other.elementAt(0)) - && Objects.equals(this.component2, other.elementAt(1)) - && Objects.equals(this.component3, other.elementAt(2)) - && Objects.equals(this.component4, other.elementAt(3)) - && Objects.equals(this.component5, other.elementAt(4)) - && Objects.equals(this.component6, other.elementAt(5)) - && Objects.equals(this.component7, other.elementAt(6)) - && Objects.equals(this.component8, other.elementAt(7)) - && Objects.equals(this.component9, other.elementAt(8)); - } - - return false; - } - - @Override - public int hashCode() { - int hash = 0; - hash = 31 * hash + Objects.hashCode(component1); - hash = 31 * hash + Objects.hashCode(component2); - hash = 31 * hash + Objects.hashCode(component3); - hash = 31 * hash + Objects.hashCode(component4); - hash = 31 * hash + Objects.hashCode(component5); - hash = 31 * hash + Objects.hashCode(component6); - hash = 31 * hash + Objects.hashCode(component7); - hash = 31 * hash + Objects.hashCode(component8); - hash = 31 * hash + Objects.hashCode(component9); - return hash; - } - - @Override - public String toString() { - return "(" + component1 + ", " + component2 + ", " + component3 + ", " + component4 + ", " + component5 + ", " + component6 + ", " + component7 + ", " + component8 + ", " + component9 + ")" ; - } - - @Serial - private Object writeReplace() { - return new SerializedTuple(toArray()); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import kala.annotations.Covariant; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Objects; +import java.util.function.IntFunction; + +/** + * A tuple of 9 elements. + * + * @param type of the 1st element + * @param type of the 2nd element + * @param type of the 3rd element + * @param type of the 4th element + * @param type of the 5th element + * @param type of the 6th element + * @param type of the 7th element + * @param type of the 8th element + * @param type of the 9th element + * @author Glavo + */ +public record Tuple9<@Covariant T1, @Covariant T2, @Covariant T3, @Covariant T4, @Covariant T5, @Covariant T6, @Covariant T7, @Covariant T8, @Covariant T9>( + T1 component1, T2 component2, T3 component3, + T4 component4, T5 component5, T6 component6, + T7 component7, T8 component8, T9 component9 +) implements HList>, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + @SuppressWarnings("unchecked") + public static Tuple9 narrow( + HList>>>>>>>> tuple) { + return (Tuple9) tuple; + } + + @Override + public int arity() { + return 9; + } + + @Override + @SuppressWarnings("unchecked") + public U elementAt(int index) { + return switch (index) { + case 0 -> (U) component1; + case 1 -> (U) component2; + case 2 -> (U) component3; + case 3 -> (U) component4; + case 4 -> (U) component5; + case 5 -> (U) component6; + case 6 -> (U) component7; + case 7 -> (U) component8; + case 8 -> (U) component9; + default -> throw new IndexOutOfBoundsException("Index out of range: " + index); + }; + } + + @Override + @SuppressWarnings("unchecked") + public U @NotNull [] toArray(@NotNull IntFunction generator) { + U[] arr = generator.apply(arity()); + arr[0] = (U) this.component1; + arr[1] = (U) this.component2; + arr[2] = (U) this.component3; + arr[3] = (U) this.component4; + arr[4] = (U) this.component5; + arr[5] = (U) this.component6; + arr[6] = (U) this.component7; + arr[7] = (U) this.component8; + arr[8] = (U) this.component9; + return arr; + } + + @Override + public T1 head() { + return component1; + } + + @Override + public @NotNull Tuple8 tail() { + return Tuple.of(component2, component3, component4, component5, component6, component7, component8, component9); + } + + @Override + @Contract("_ -> new") + @SuppressWarnings({"unchecked", "rawtypes"}) + public @NotNull HList> cons(H head) { + Object[] arr = new Object[10]; + arr[0] = head; + arr[1] = component1; + arr[2] = component2; + arr[3] = component3; + arr[4] = component4; + arr[5] = component5; + arr[6] = component6; + arr[7] = component7; + arr[8] = component8; + arr[9] = component9; + return (HList) new TupleXXL(arr); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Tuple9 other) { + return Objects.equals(this.component1, other.component1) + && Objects.equals(this.component2, other.component2) + && Objects.equals(this.component3, other.component3) + && Objects.equals(this.component4, other.component4) + && Objects.equals(this.component5, other.component5) + && Objects.equals(this.component6, other.component6) + && Objects.equals(this.component7, other.component7) + && Objects.equals(this.component8, other.component8) + && Objects.equals(this.component9, other.component9); + } + + if (o instanceof AnyTuple other) { + return other.arity() == 9 + && Objects.equals(this.component1, other.elementAt(0)) + && Objects.equals(this.component2, other.elementAt(1)) + && Objects.equals(this.component3, other.elementAt(2)) + && Objects.equals(this.component4, other.elementAt(3)) + && Objects.equals(this.component5, other.elementAt(4)) + && Objects.equals(this.component6, other.elementAt(5)) + && Objects.equals(this.component7, other.elementAt(6)) + && Objects.equals(this.component8, other.elementAt(7)) + && Objects.equals(this.component9, other.elementAt(8)); + } + + return false; + } + + @Override + public int hashCode() { + int hash = 0; + hash = 31 * hash + Objects.hashCode(component1); + hash = 31 * hash + Objects.hashCode(component2); + hash = 31 * hash + Objects.hashCode(component3); + hash = 31 * hash + Objects.hashCode(component4); + hash = 31 * hash + Objects.hashCode(component5); + hash = 31 * hash + Objects.hashCode(component6); + hash = 31 * hash + Objects.hashCode(component7); + hash = 31 * hash + Objects.hashCode(component8); + hash = 31 * hash + Objects.hashCode(component9); + return hash; + } + + @Override + public String toString() { + return "(" + component1 + ", " + component2 + ", " + component3 + ", " + component4 + ", " + component5 + ", " + component6 + ", " + component7 + ", " + component8 + ", " + component9 + ")" ; + } + + @Serial + private Object writeReplace() { + return new SerializedTuple(toArray()); + } +} diff --git a/kala-base/src/main/java/kala/tuple/TupleXXL.java b/kala-base/src/main/java/kala/tuple/TupleXXL.java index 9cc6e874..8f5b5c3e 100644 --- a/kala-base/src/main/java/kala/tuple/TupleXXL.java +++ b/kala-base/src/main/java/kala/tuple/TupleXXL.java @@ -1,143 +1,143 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple; - -import org.jetbrains.annotations.NotNull; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Objects; -import java.util.function.IntFunction; - -/** - * A tuple of more than 9 elements. - * - * @author Glavo - */ -@SuppressWarnings("unchecked") -final class TupleXXL implements HList>, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - private final Object @NotNull [] values; - - TupleXXL(Object @NotNull [] values) { - this.values = values; - } - - @Override - public int arity() { - return values.length; - } - - @Override - public U elementAt(int index) { - try { - return (U) values[index]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new IndexOutOfBoundsException("Index out of range: " + index); - } - } - - @Override - @SuppressWarnings("rawtypes") - public @NotNull HList cons(H head) { - int arity = arity(); - Object[] arr = new Object[arity + 1]; - arr[0] = head; - System.arraycopy(values, 0, arr, 1, arity); - return (HList) new TupleXXL(arr); - } - - @Override - public Object @NotNull [] toArray() { - return values.clone(); - } - - @SuppressWarnings("SuspiciousSystemArraycopy") - @Override - public U @NotNull [] toArray(@NotNull IntFunction generator) { - U[] arr = generator.apply(arity()); - System.arraycopy(values, 0, arr, 0, arity()); - return arr; - } - - @Override - public Object head() { - return values[0]; - } - - @Override - public @NotNull HList tail() { - int arity = arity(); - if (arity == 10) { - return new Tuple9<>( - values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9] - ); - } - return new TupleXXL(Arrays.copyOfRange(values, 1, arity)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o instanceof TupleXXL other) { - return Arrays.equals(this.values, other.values); - } - - if (o instanceof AnyTuple other) { - if (this.arity() != other.arity()) return false; - for (int i = 0; i < values.length; i++) { - if (!Objects.equals(values[i], other.elementAt(i))) return false; - } - return true; - } - - return false; - } - - @Override - public int hashCode() { - int hash = 0; - for (Object value : values) { - hash = hash * 31 + Objects.hashCode(value); - } - return hash; - } - - @Override - public String toString() { - final Object[] values = this.values; - final int arity = values.length; - - StringBuilder builder = new StringBuilder(6 * arity); - builder.append('(').append(values[0]); - - for (int i = 1; i < arity; i++) { - builder.append(", ").append(values[i]); - } - builder.append(')'); - - return builder.toString(); - } - - @Serial - private Object writeReplace() { - return new SerializedTuple(values); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Objects; +import java.util.function.IntFunction; + +/** + * A tuple of more than 9 elements. + * + * @author Glavo + */ +@SuppressWarnings("unchecked") +final class TupleXXL implements HList>, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + private final Object @NotNull [] values; + + TupleXXL(Object @NotNull [] values) { + this.values = values; + } + + @Override + public int arity() { + return values.length; + } + + @Override + public U elementAt(int index) { + try { + return (U) values[index]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new IndexOutOfBoundsException("Index out of range: " + index); + } + } + + @Override + @SuppressWarnings("rawtypes") + public @NotNull HList cons(H head) { + int arity = arity(); + Object[] arr = new Object[arity + 1]; + arr[0] = head; + System.arraycopy(values, 0, arr, 1, arity); + return (HList) new TupleXXL(arr); + } + + @Override + public Object @NotNull [] toArray() { + return values.clone(); + } + + @SuppressWarnings("SuspiciousSystemArraycopy") + @Override + public U @NotNull [] toArray(@NotNull IntFunction generator) { + U[] arr = generator.apply(arity()); + System.arraycopy(values, 0, arr, 0, arity()); + return arr; + } + + @Override + public Object head() { + return values[0]; + } + + @Override + public @NotNull HList tail() { + int arity = arity(); + if (arity == 10) { + return new Tuple9<>( + values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9] + ); + } + return new TupleXXL(Arrays.copyOfRange(values, 1, arity)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof TupleXXL other) { + return Arrays.equals(this.values, other.values); + } + + if (o instanceof AnyTuple other) { + if (this.arity() != other.arity()) return false; + for (int i = 0; i < values.length; i++) { + if (!Objects.equals(values[i], other.elementAt(i))) return false; + } + return true; + } + + return false; + } + + @Override + public int hashCode() { + int hash = 0; + for (Object value : values) { + hash = hash * 31 + Objects.hashCode(value); + } + return hash; + } + + @Override + public String toString() { + final Object[] values = this.values; + final int arity = values.length; + + StringBuilder builder = new StringBuilder(6 * arity); + builder.append('(').append(values[0]); + + for (int i = 1; i < arity; i++) { + builder.append(", ").append(values[i]); + } + builder.append(')'); + + return builder.toString(); + } + + @Serial + private Object writeReplace() { + return new SerializedTuple(values); + } +} diff --git a/kala-base/src/main/java/kala/tuple/primitive/PrimitiveTuple.java b/kala-base/src/main/java/kala/tuple/primitive/PrimitiveTuple.java index b6052b5a..93fccdaa 100644 --- a/kala-base/src/main/java/kala/tuple/primitive/PrimitiveTuple.java +++ b/kala-base/src/main/java/kala/tuple/primitive/PrimitiveTuple.java @@ -1,21 +1,21 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.tuple.primitive; - -import kala.tuple.AnyTuple; - -public interface PrimitiveTuple extends AnyTuple { -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.tuple.primitive; + +import kala.tuple.AnyTuple; + +public interface PrimitiveTuple extends AnyTuple { +} diff --git a/kala-base/src/main/java/kala/value/CheckedVar.java b/kala-base/src/main/java/kala/value/CheckedVar.java index adf7f6d4..ca881e61 100644 --- a/kala-base/src/main/java/kala/value/CheckedVar.java +++ b/kala-base/src/main/java/kala/value/CheckedVar.java @@ -1,57 +1,57 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.value; - -import java.io.Serial; -import java.io.Serializable; - -public final class CheckedVar extends AbstractMutableValue implements Cloneable, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - private final Class type; - private T value; - - public CheckedVar(Class type) { - this.type = type; - } - - public CheckedVar(Class type, T value) { - this.type = type; - this.value = type.cast(value); - } - - @Override - public T get() { - return value; - } - - @Override - public void set(T value) throws ClassCastException { - this.value = type.cast(value); - } - - @Override - @SuppressWarnings("MethodDoesntCallSuperMethod") - public CheckedVar clone() { - return new CheckedVar<>(type, value); - } - - @Override - public String toString() { - return "CheckedVar[" + value + "]"; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.value; + +import java.io.Serial; +import java.io.Serializable; + +public final class CheckedVar extends AbstractMutableValue implements Cloneable, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + private final Class type; + private T value; + + public CheckedVar(Class type) { + this.type = type; + } + + public CheckedVar(Class type, T value) { + this.type = type; + this.value = type.cast(value); + } + + @Override + public T get() { + return value; + } + + @Override + public void set(T value) throws ClassCastException { + this.value = type.cast(value); + } + + @Override + @SuppressWarnings("MethodDoesntCallSuperMethod") + public CheckedVar clone() { + return new CheckedVar<>(type, value); + } + + @Override + public String toString() { + return "CheckedVar[" + value + "]"; + } +} diff --git a/kala-base/src/main/java/kala/value/LazyValue.java b/kala-base/src/main/java/kala/value/LazyValue.java index 83db12ce..f537d0bf 100644 --- a/kala-base/src/main/java/kala/value/LazyValue.java +++ b/kala-base/src/main/java/kala/value/LazyValue.java @@ -1,135 +1,135 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.value; - -import kala.annotations.Covariant; -import kala.collection.base.AbstractIterator; -import kala.function.Memoized; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.io.Serial; -import java.io.Serializable; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.function.Function; -import java.util.function.Supplier; - -public final class LazyValue<@Covariant T> extends AbstractValue implements Memoized, Serializable { - @Serial - private static final long serialVersionUID = 7403692951772568981L; - - private transient volatile Supplier supplier; - private transient T value; - - private LazyValue(Supplier supplier) { - this.supplier = supplier; - } - - private LazyValue(T value) { - this.value = value; - } - - @Contract(value = "_ -> param1", pure = true) - @SuppressWarnings("unchecked") - public static LazyValue narrow(LazyValue value) { - return (LazyValue) value; - } - - @Contract("_ -> new") - public static @NotNull LazyValue of(@NotNull Supplier supplier) { - Objects.requireNonNull(supplier); - return new LazyValue<>(supplier); - } - - @Contract("_ -> new") - public static @NotNull LazyValue ofValue(T value) { - return new LazyValue<>(value); - } - - public T get() { - Supplier s = supplier; - if (s != null) { - synchronized (this) { - s = supplier; - if (s != null) { - value = s.get(); - supplier = null; - } - } - } - return value; - } - - public boolean isReady() { - return supplier == null; - } - - @Override - @Contract("_ -> new") - public @NotNull LazyValue map(@NotNull Function mapper) { - Objects.requireNonNull(mapper); - return LazyValue.of(() -> mapper.apply(get())); - } - - @Override - public @NotNull Iterator iterator() { - return new AbstractIterator() { - private boolean hasNext = true; - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public T next() { - if (!hasNext) { - throw new NoSuchElementException(); - } - hasNext = false; - return get(); - } - }; - } - - @Override - public String toString() { - if (supplier == null) { - return "LazyValue[" + value + "]"; - } else { - return "LazyValue[]"; - } - } - - //region Serialization Operations - - @Serial - @SuppressWarnings("unchecked") - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - value = (T) in.readObject(); - supplier = null; - } - - @Serial - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.writeObject(get()); - } - - //endregion -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.value; + +import kala.annotations.Covariant; +import kala.collection.base.AbstractIterator; +import kala.function.Memoized; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.Serial; +import java.io.Serializable; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Supplier; + +public final class LazyValue<@Covariant T> extends AbstractValue implements Memoized, Serializable { + @Serial + private static final long serialVersionUID = 7403692951772568981L; + + private transient volatile Supplier supplier; + private transient T value; + + private LazyValue(Supplier supplier) { + this.supplier = supplier; + } + + private LazyValue(T value) { + this.value = value; + } + + @Contract(value = "_ -> param1", pure = true) + @SuppressWarnings("unchecked") + public static LazyValue narrow(LazyValue value) { + return (LazyValue) value; + } + + @Contract("_ -> new") + public static @NotNull LazyValue of(@NotNull Supplier supplier) { + Objects.requireNonNull(supplier); + return new LazyValue<>(supplier); + } + + @Contract("_ -> new") + public static @NotNull LazyValue ofValue(T value) { + return new LazyValue<>(value); + } + + public T get() { + Supplier s = supplier; + if (s != null) { + synchronized (this) { + s = supplier; + if (s != null) { + value = s.get(); + supplier = null; + } + } + } + return value; + } + + public boolean isReady() { + return supplier == null; + } + + @Override + @Contract("_ -> new") + public @NotNull LazyValue map(@NotNull Function mapper) { + Objects.requireNonNull(mapper); + return LazyValue.of(() -> mapper.apply(get())); + } + + @Override + public @NotNull Iterator iterator() { + return new AbstractIterator() { + private boolean hasNext = true; + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public T next() { + if (!hasNext) { + throw new NoSuchElementException(); + } + hasNext = false; + return get(); + } + }; + } + + @Override + public String toString() { + if (supplier == null) { + return "LazyValue[" + value + "]"; + } else { + return "LazyValue[]"; + } + } + + //region Serialization Operations + + @Serial + @SuppressWarnings("unchecked") + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + value = (T) in.readObject(); + supplier = null; + } + + @Serial + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.writeObject(get()); + } + + //endregion +} diff --git a/kala-base/src/main/java/kala/value/TransientVar.java b/kala-base/src/main/java/kala/value/TransientVar.java index c01de0b2..3c7de047 100644 --- a/kala-base/src/main/java/kala/value/TransientVar.java +++ b/kala-base/src/main/java/kala/value/TransientVar.java @@ -1,48 +1,48 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.value; - -import java.io.Serial; -import java.io.Serializable; - -public final class TransientVar implements MutableValue, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - public transient T value; - - public TransientVar() { - } - - public TransientVar(T value) { - this.value = value; - } - - @Override - public T get() { - return value; - } - - @Override - public void set(T value) { - this.value = value; - } - - @Override - public String toString() { - return "TransientVar[" + value + "]"; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.value; + +import java.io.Serial; +import java.io.Serializable; + +public final class TransientVar implements MutableValue, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + public transient T value; + + public TransientVar() { + } + + public TransientVar(T value) { + this.value = value; + } + + @Override + public T get() { + return value; + } + + @Override + public void set(T value) { + this.value = value; + } + + @Override + public String toString() { + return "TransientVar[" + value + "]"; + } +} diff --git a/kala-base/src/main/java/kala/value/Var.java b/kala-base/src/main/java/kala/value/Var.java index d15cd46f..fbfae7e0 100644 --- a/kala-base/src/main/java/kala/value/Var.java +++ b/kala-base/src/main/java/kala/value/Var.java @@ -1,55 +1,55 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.value; - -import java.io.Serial; -import java.io.Serializable; - -/// A simple mutable value has a mutable object reference. -public final class Var extends AbstractMutableValue implements Cloneable, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - public T value; - - public Var() { - } - - public Var(T value) { - this.value = value; - } - - @Override - public T get() { - return value; - } - - @Override - public void set(T value) { - this.value = value; - } - - @Override - @SuppressWarnings("MethodDoesntCallSuperMethod") - public Var clone() { - return new Var<>(value); - } - - @Override - public String toString() { - return "Var[" + value + "]"; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.value; + +import java.io.Serial; +import java.io.Serializable; + +/// A simple mutable value has a mutable object reference. +public final class Var extends AbstractMutableValue implements Cloneable, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + public T value; + + public Var() { + } + + public Var(T value) { + this.value = value; + } + + @Override + public T get() { + return value; + } + + @Override + public void set(T value) { + this.value = value; + } + + @Override + @SuppressWarnings("MethodDoesntCallSuperMethod") + public Var clone() { + return new Var<>(value); + } + + @Override + public String toString() { + return "Var[" + value + "]"; + } +} diff --git a/kala-base/src/main/java/kala/value/VolatileVar.java b/kala-base/src/main/java/kala/value/VolatileVar.java index 011cefa8..0f4a7cf4 100644 --- a/kala-base/src/main/java/kala/value/VolatileVar.java +++ b/kala-base/src/main/java/kala/value/VolatileVar.java @@ -1,48 +1,48 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.value; - -import java.io.Serial; -import java.io.Serializable; - -public final class VolatileVar extends AbstractMutableValue implements Serializable { - @Serial - private static final long serialVersionUID = 0L; - - public volatile T value; - - public VolatileVar() { - } - - public VolatileVar(T value) { - this.value = value; - } - - @Override - public T get() { - return value; - } - - @Override - public void set(T value) { - this.value = value; - } - - @Override - public String toString() { - return "VolatileVar[" + value + "]"; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.value; + +import java.io.Serial; +import java.io.Serializable; + +public final class VolatileVar extends AbstractMutableValue implements Serializable { + @Serial + private static final long serialVersionUID = 0L; + + public volatile T value; + + public VolatileVar() { + } + + public VolatileVar(T value) { + this.value = value; + } + + @Override + public T get() { + return value; + } + + @Override + public void set(T value) { + this.value = value; + } + + @Override + public String toString() { + return "VolatileVar[" + value + "]"; + } +} diff --git a/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveIterator.java.ftl b/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveIterator.java.ftl index 5f56ba2b..b9ae790c 100644 --- a/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveIterator.java.ftl +++ b/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveIterator.java.ftl @@ -1,884 +1,884 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base.primitive; - -import kala.annotations.ReplaceWith; -import kala.collection.base.GenericArrays; -import kala.collection.base.Growable; -import kala.collection.base.Iterators; -import kala.control.primitive.${Type}Option; -import kala.function.*; -import kala.internal.*; -import kala.tuple.Tuple; -import kala.tuple.Tuple2; -import kala.collection.base.AbstractIterator; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.function.*; - -public interface ${Type}Iterator extends PrimitiveIterator<${WrapperType}, ${Type}Consumer><#if IsSpecialized>, java.util.PrimitiveIterator.Of${Type} { - - static @NotNull ${Type}Iterator empty() { - return ${Type}Iterators.EMPTY; - } - - static @NotNull ${Type}Iterator of() { - return empty(); - } - - static @NotNull ${Type}Iterator of(${PrimitiveType} value) { - return new ${Type}Iterator() { - private boolean hasNext = true; - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public ${PrimitiveType} next${Type}() { - if (hasNext) { - hasNext = false; - return value; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public String toString() { - if (hasNext) { - return "${Type}Iterator[" + value + "]"; - } else { - return "${Type}Iterator[]"; - } - } - }; - } - - static @NotNull ${Type}Iterator of(${PrimitiveType}... values) { - return ${Type}Arrays.iterator(values); - } -<#if Type == 'Char'> - - static @NotNull CharIterator of(@NotNull String str) { - return str.isEmpty() ? ${Type}Iterators.EMPTY : new ${Type}Iterators.OfString(str); - } - - - static @NotNull ${Type}Iterator ofIterator(@NotNull Iterator it) { - Objects.requireNonNull(it); - if (it instanceof ${Type}Iterator) { - return (${Type}Iterator) it; - } - return new ${Type}Iterator() { - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public ${PrimitiveType} next${Type}() { - return it.next(); - } - - @Override - public String toString() { - return it.toString(); - } - }; - } - -<#if IsSpecialized> - static @NotNull ${Type}Iterator ofIterator(@NotNull ${PrimitiveIteratorType} it) { - Objects.requireNonNull(it); - if (it instanceof ${Type}Iterator) { - return (${Type}Iterator) it; - } - return new ${Type}Iterator() { - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public ${PrimitiveType} next${Type}() { - return it.next${Type}(); - } - - @Override - public String toString() { - return it.toString(); - } - }; - } - - - static @NotNull ${Type}Iterator concat(@NotNull ${Type}Iterator it1, @NotNull ${Type}Iterator it2) { - if (!it1.hasNext()) { //implicit null check of it1 - return Objects.requireNonNull(it2); - } - if (!it2.hasNext()) {//implicit null check of it1 - return it1; - } - return new ${Type}Iterators.Concat(it1, it2); - } - - static @NotNull ${Type}Iterator concat(@NotNull ${Type}Iterator... its) { - return switch (its.length) { // implicit null check of its - case 0 -> ${Type}Iterator.empty(); - case 1 -> Objects.requireNonNull(its[0]); - case 2 -> concat(its[0], its[1]); - default -> new ${Type}Iterators.ConcatAll(GenericArrays.iterator(its)); - }; - } - - static @NotNull ${Type}Iterator concat(@NotNull Iterable its) { - return concat(its.iterator()); // implicit null check of its - } - - static @NotNull ${Type}Iterator concat(@NotNull Iterator its) { - if (!its.hasNext()) { // implicit null check of its - return ${Type}Iterator.empty(); - } - return new ${Type}Iterators.ConcatAll(its); - } - - /** - * Returns the next {@code ${PrimitiveType}} element in the iteration. - * - * @return the next {@code ${PrimitiveType}} element in the iteration - * @throws NoSuchElementException if the iteration has no more elements - */ - ${PrimitiveType} next${Type}(); - - @Override - default void nextIgnoreResult() { - next${Type}(); - } - - @Override - @Deprecated - @ReplaceWith("next${Type}()") - default @NotNull ${WrapperType} next() { - return next${Type}(); - } - - default @NotNull ${Type}Option find(@NotNull ${Type}Predicate predicate) { - while (hasNext()) { - ${PrimitiveType} value = next${Type}(); - if (predicate.test(value)) { - return ${Type}Option.some(value); - } - } - return ${Type}Option.None; - } - - //region Element Conditions - - default boolean contains(${PrimitiveType} value) { - while (hasNext()) { - if (${PrimitiveEquals("value", "next${Type}()")}) { - return true; - } - } - return false; - } - - default boolean contains(Object value) { - if (!(value instanceof ${WrapperType})) { - return false; - } - - ${PrimitiveType} v = (${WrapperType}) value; - - while (hasNext()) { - if (${PrimitiveEquals("v", "next${Type}()")}) { - return true; - } - } - return false; - } - -<#if Type == "Boolean"> - default boolean containsAll(boolean @NotNull [] values) { - if (!hasNext()) { - return values.length == 0; - } - boolean containsTrue = false; - boolean containsFalse = false; - - while (hasNext()) { - boolean v = nextBoolean(); - if (v) { - containsTrue = true; - } else { - containsFalse = true; - } - if (containsTrue && containsFalse) { - return true; - } - } - - if (containsTrue && containsFalse) { - throw new AssertionError(); - } else if (containsTrue) { - for (boolean value : values) { - if (!value) { - return false; - } - } - } else if (containsFalse) { - for (boolean value : values) { - if (value) { - return false; - } - } - } else { - throw new AssertionError(); - } - return true; - } - - @Override - default boolean containsAll(Boolean @NotNull [] values) { - if (values.length == 0) { - return true; - } - if (!hasNext()) { - return false; - } - - boolean containsTrue = false; - boolean containsFalse = false; - - while (hasNext()) { - boolean v = nextBoolean(); - if (v) { - containsTrue = true; - } else { - containsFalse = true; - } - if (containsTrue && containsFalse) { - break; - } - } - - if (containsTrue && containsFalse) { - for (Boolean value : values) { - if (value == null) { - return false; - } - } - } else if (containsTrue) { - for (Boolean value : values) { - if (value == null || !value) { - return false; - } - } - } else if (containsFalse) { - for (Boolean value : values) { - if (value == null || value) { - return false; - } - } - } else { - throw new AssertionError(); - } - return true; - } - - @Override - default boolean containsAll(@NotNull Iterable values) { - Iterator it = values.iterator(); - if (!it.hasNext()) { - return true; - } - if (!hasNext()) { - return false; - } - - boolean containsTrue = false; - boolean containsFalse = false; - - while (hasNext()) { - boolean v = nextBoolean(); - if (v) { - containsTrue = true; - } else { - containsFalse = true; - } - if (containsTrue && containsFalse) { - break; - } - } - - if (containsTrue && containsFalse) { - while (it.hasNext()) { - Object value = it.next(); - if (!(value instanceof Boolean)) { - return false; - } - } - } else if (containsTrue) { - while (it.hasNext()) { - Object value = it.next(); - if (!(value instanceof Boolean) || !(Boolean) value) { - return false; - } - } - } else if (containsFalse) { - while (it.hasNext()) { - Object value = it.next(); - if (!(value instanceof Boolean) || (Boolean) value) { - return false; - } - } - } else { - throw new AssertionError(); - } - return true; - } -<#else> - default boolean containsAll(${PrimitiveType} @NotNull [] values) { - loop: - while (hasNext()) { - final ${PrimitiveType} v = next${Type}(); - for (${PrimitiveType} i : values) { - if (${PrimitiveEquals("i", "v")}) { - continue loop; - } - } - return false; - } - return true; - } - - -<#if IsSpecialized> - default boolean sameElements(@NotNull ${Type}Iterator other) { - return sameElements((${PrimitiveIteratorType}) other); - } - - - default boolean sameElements(@NotNull ${PrimitiveIteratorType} other) { - while (this.hasNext() && other.hasNext()) { - if (${PrimitiveNotEquals("this.next${Type}()", "other.next${Type}()")}) { - return false; - } - } - return this.hasNext() == other.hasNext(); - } - - @Override - default boolean sameElements(@NotNull Iterator other) { - if (other instanceof ${PrimitiveIteratorType}) { - return sameElements((${PrimitiveIteratorType}) other); - } - while (this.hasNext() && other.hasNext()) { - Object value = other.next(); - if(!(value instanceof ${WrapperType})) return false; - - if ((${PrimitiveNotEquals("(${WrapperType}) value", "this.next${Type}()")})) { - return false; - } - } - return this.hasNext() == other.hasNext(); - } - - default boolean anyMatch(@NotNull ${Type}Predicate predicate) { - while (hasNext()) { - if (predicate.test(next${Type}())) { - return true; - } - } - return false; - } - - default boolean allMatch(@NotNull ${Type}Predicate predicate) { - while (hasNext()) { - if (!predicate.test(next${Type}())) { - return false; - } - } - return true; - } - - default boolean noneMatch(@NotNull ${Type}Predicate predicate) { - while (hasNext()) { - if (predicate.test(next${Type}())) { - return false; - } - } - return true; - } - - //endregion - - //region Misc Operations - - @Override - default @NotNull ${Type}Iterator drop(int n) { - if (n < 0) { - throw new IllegalArgumentException(); - } - while (n > 0 && hasNext()) { - next${Type}(); - --n; - } - return this; - } - - default @NotNull ${Type}Iterator dropWhile(@NotNull ${Type}Predicate predicate) { - if (!hasNext()) { - return this; - } - - ${PrimitiveType} value = ${Values.Default}; - boolean p = false; - while (hasNext()) { - if (!predicate.test(value = next${Type}())) { - p = true; - break; - } - } - - if (p) { - return hasNext() ? prepended(value) : ${Type}Iterator.of(value); - } else { - return this; - } - } - - @Override - default @NotNull ${Type}Iterator take(int n) { - if (n < 0) { - throw new IllegalArgumentException(); - } - if (!hasNext() || n == 0) { - return empty(); - } - - return new ${Type}Iterators.Take(this, n); - } - - default @NotNull ${Type}Iterator takeWhile(@NotNull ${Type}Predicate predicate) { - Objects.requireNonNull(predicate); - if (!hasNext()) { - return this; - } - return new ${Type}Iterators.TakeWhile(this, predicate); - } - - default @NotNull ${Type}Iterator updated(int n, ${PrimitiveType} newValue) { - if (!hasNext() || n < 0) { - return this; - } - - if (n == 0) { - this.next${Type}(); - return prepended(newValue); - } - - return new ${Type}Iterators.Updated(this, n, newValue); - } - - default @NotNull ${Type}Iterator prepended(${PrimitiveType} value) { - return new ${Type}Iterators.Prepended(this, value); - } - - default @NotNull ${Type}Iterator appended(${PrimitiveType} value) { - return new ${Type}Iterators.Appended(this, value); - } - - default @NotNull ${Type}Iterator filter(@NotNull ${Type}Predicate predicate) { - Objects.requireNonNull(predicate); - if (!hasNext()) { - return empty(); - } - return new ${Type}Iterators.Filter(this, predicate, false); - } - - default @NotNull ${Type}Iterator filterNot(@NotNull ${Type}Predicate predicate) { - Objects.requireNonNull(predicate); - if (!hasNext()) { - return empty(); - } - return new ${Type}Iterators.Filter(this, predicate, true); - } - - default @NotNull ${Type}Iterator map(@NotNull ${Type}UnaryOperator mapper) { - Objects.requireNonNull(mapper); - if (!hasNext()) { - return this; - } - return new Abstract${Type}Iterator() { - @Override - public boolean hasNext() { - return ${Type}Iterator.this.hasNext(); - } - - @Override - public ${PrimitiveType} next${Type}() { - return mapper.applyAs${Type}(${Type}Iterator.this.next${Type}()); - } - }; - } - - default @NotNull Iterator mapToObj(@NotNull ${Type}Function mapper) { - Objects.requireNonNull(mapper); - if (!hasNext()) { - return Iterators.empty(); - } - return new AbstractIterator() { - @Override - public boolean hasNext() { - return ${Type}Iterator.this.hasNext(); - } - - @Override - public U next() { - return mapper.apply(${Type}Iterator.this.next${Type}()); - } - }; - } - - default @NotNull Tuple2<${r'@NotNull'} ${Type}Iterator, @NotNull ${Type}Iterator> span(@NotNull ${Type}Predicate predicate) { - if (!hasNext()) { - return Tuple.of(empty(), empty()); - } - - Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); - ${Type}Iterator it = this; - - while (it.hasNext()) { - ${PrimitiveType} e = it.next${Type}(); - if (predicate.test(e)) { - builder.append(e); - } else { - it = it.prepended(e); - break; - } - } - - return Tuple.of(builder.iterator(), it); - } - - //endregion - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G filterTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { - ${Type}Iterator it = this; - while (it.hasNext()) { - ${PrimitiveType} e = it.next${Type}(); - if (predicate.test(e)) { - destination.plusAssign(e); - } - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G filterNotTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { - ${Type}Iterator it = this; - while (it.hasNext()) { - ${PrimitiveType} e = it.next${Type}(); - if (!predicate.test(e)) { - destination.plusAssign(e); - } - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapTo(@NotNull G destination, @NotNull ${Type}UnaryOperator mapper) { - ${Type}Iterator it = this; - while (it.hasNext()) { - destination.plusAssign(mapper.applyAs${Type}(it.next${Type}())); - } - return destination; - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G mapToObjTo(@NotNull G destination, @NotNull ${Type}Function mapper) { - ${Type}Iterator it = this; - while (it.hasNext()) { - destination.plusAssign(mapper.apply(it.next${Type}())); - } - return destination; - } - - //region Aggregate Operations - - default int count(@NotNull ${Type}Predicate predicate) { - int c = 0; - while (hasNext()) { - if (predicate.test(next${Type}())) { - ++c; - } - } - return c; - } - - default ${PrimitiveType} max() { - if (!hasNext()) { - throw new NoSuchElementException(); - } -<#if Type == 'Boolean'> - - while (hasNext()) { - if (nextBoolean()) return true; - } - - return false; -<#else> - ${PrimitiveType} value = next${Type}(); - while (hasNext()) { -<#if IsSpecialized || Type == 'Float'> - value = Math.max(value, next${Type}()); -<#else> - value = (${PrimitiveType}) Math.max(value, next${Type}()); - - } - return value; - - } - - @Override - default @Nullable ${WrapperType} maxOrNull() { - return hasNext() ? max() : null; - } - - @Override - default @NotNull ${Type}Option maxOption() { - return hasNext() ? ${Type}Option.some(max()) : ${Type}Option.none(); - } - - default ${PrimitiveType} min() { - if (!hasNext()) { - throw new NoSuchElementException(); - } -<#if Type == 'Boolean'> - - while (hasNext()) { - if (!nextBoolean()) return false; - } - - return true; -<#else> - ${PrimitiveType} value = next${Type}(); - while (hasNext()) { -<#if IsSpecialized || Type == 'Float'> - value = Math.min(value, next${Type}()); -<#else> - value = (${PrimitiveType}) Math.min(value, next${Type}()); - - } - return value; - - } - - @Override - default @Nullable ${WrapperType} minOrNull() { - return hasNext() ? min() : null; - } - - @Override - default @NotNull ${Type}Option minOption() { - return hasNext() ? ${Type}Option.some(min()) : ${Type}Option.none(); - } - - default ${PrimitiveType} fold(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - return foldLeft(zero, op); - } - - default ${PrimitiveType} foldLeft(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - while (hasNext()) { - zero = op.applyAs${Type}(zero, this.next${Type}()); - } - return zero; - } - - default U foldLeftToObj(U zero, @NotNull Obj${Type}BiFunction op) { - while (hasNext()) { - zero = op.apply(zero, this.next${Type}()); - } - return zero; - } - - default ${PrimitiveType} foldRight(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - if (!hasNext()) { - return zero; - } - Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); - while (hasNext()) { - builder.append(next${Type}()); - } - for (int i = builder.size() - 1; i >= 0; i--) { - zero = op.applyAs${Type}(builder.get(i), zero); - } - return zero; - } - - default U foldRightToObj(U zero, @NotNull ${Type}ObjBiFunction op) { - if (!hasNext()) { - return zero; - } - Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); - while (hasNext()) { - builder.append(next${Type}()); - } - for (int i = builder.size() - 1; i >= 0; i--) { - zero = op.apply(builder.get(i), zero); - } - return zero; - } - - default ${PrimitiveType} reduce(@NotNull ${Type}BinaryOperator op) { - return reduceLeft(op); - } - - default @Nullable ${WrapperType} reduceOrNull(@NotNull ${Type}BinaryOperator op) { - return reduceLeftOrNull(op); - } - - default @NotNull ${Type}Option reduceOption(@NotNull ${Type}BinaryOperator op) { - return reduceLeftOption(op); - } - - default ${PrimitiveType} reduceLeft(@NotNull ${Type}BinaryOperator op) { - ${PrimitiveType} e = next${Type}(); - while (hasNext()) { - e = op.applyAs${Type}(e, next${Type}()); - } - return e; - } - - default @Nullable ${WrapperType} reduceLeftOrNull(@NotNull ${Type}BinaryOperator op) { - return hasNext() ? reduceLeft(op) : null; - } - - default @NotNull ${Type}Option reduceLeftOption(@NotNull ${Type}BinaryOperator op) { - return hasNext() ? ${Type}Option.some(reduceLeft(op)) : ${Type}Option.none(); - } - - default ${PrimitiveType} reduceRight(@NotNull ${Type}BinaryOperator op) { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Internal${Type}ArrayBuilder list = new Internal${Type}ArrayBuilder(); - list.append(next${Type}()); - while (hasNext()) { - list.append(next${Type}()); - } - final int size = list.size(); - ${PrimitiveType} e = list.get(size - 1); - - for (int i = size - 2; i >= 0; i--) { - e = op.applyAs${Type}(list.get(i), e); - } - return e; - } - - default @Nullable ${WrapperType} reduceRightOrNull(@NotNull ${Type}BinaryOperator op) { - return hasNext() ? reduceRight(op) : null; - } - - default @NotNull ${Type}Option reduceRightOption(@NotNull ${Type}BinaryOperator op) { - return hasNext() ? ${Type}Option.some(reduceRight(op)) : ${Type}Option.none(); - } - - //endregion - - //region Conversion Operations - - @Override - default ${PrimitiveType} @NotNull [] toArray() { - if (!hasNext()) { - return ${Type}Arrays.EMPTY; - } - Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); - while (hasNext()) { - builder.append(next${Type}()); - } - - return builder.toArray(); - } - - //endregion - - //region Traverse Operations - - @Override - default void forEach(@NotNull ${Type}Consumer action) { - while (hasNext()) { - action.accept(next${Type}()); - } - } - - @Override - default void forEachRemaining(@NotNull Consumer action) { - if (action instanceof ${Type}Consumer) { - forEach(((${Type}Consumer) action)); - } else { - forEach(action::accept); - } - } - - @Override - default void forEachRemaining(@NotNull ${Type}Consumer action) { - forEach(action); - } - - //endregion - - //region - - @Override - default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, CharSequence prefix, CharSequence postfix) { - try { - buffer.append(prefix); - if (hasNext()) { - buffer.append(String.valueOf(next${Type}())); - } - while (hasNext()) { - buffer.append(separator).append(String.valueOf(next${Type}())); - } - buffer.append(postfix); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return buffer; - } - - //endregion - - @Override - default int hash() { - int res = 0; - while (hasNext()) { - res = res * 31 + ${WrapperType}.hashCode(next${Type}()); - } - return res; - } +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base.primitive; + +import kala.annotations.ReplaceWith; +import kala.collection.base.GenericArrays; +import kala.collection.base.Growable; +import kala.collection.base.Iterators; +import kala.control.primitive.${Type}Option; +import kala.function.*; +import kala.internal.*; +import kala.tuple.Tuple; +import kala.tuple.Tuple2; +import kala.collection.base.AbstractIterator; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.function.*; + +public interface ${Type}Iterator extends PrimitiveIterator<${WrapperType}, ${Type}Consumer><#if IsSpecialized>, java.util.PrimitiveIterator.Of${Type} { + + static @NotNull ${Type}Iterator empty() { + return ${Type}Iterators.EMPTY; + } + + static @NotNull ${Type}Iterator of() { + return empty(); + } + + static @NotNull ${Type}Iterator of(${PrimitiveType} value) { + return new ${Type}Iterator() { + private boolean hasNext = true; + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public ${PrimitiveType} next${Type}() { + if (hasNext) { + hasNext = false; + return value; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public String toString() { + if (hasNext) { + return "${Type}Iterator[" + value + "]"; + } else { + return "${Type}Iterator[]"; + } + } + }; + } + + static @NotNull ${Type}Iterator of(${PrimitiveType}... values) { + return ${Type}Arrays.iterator(values); + } +<#if Type == 'Char'> + + static @NotNull CharIterator of(@NotNull String str) { + return str.isEmpty() ? ${Type}Iterators.EMPTY : new ${Type}Iterators.OfString(str); + } + + + static @NotNull ${Type}Iterator ofIterator(@NotNull Iterator it) { + Objects.requireNonNull(it); + if (it instanceof ${Type}Iterator) { + return (${Type}Iterator) it; + } + return new ${Type}Iterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public ${PrimitiveType} next${Type}() { + return it.next(); + } + + @Override + public String toString() { + return it.toString(); + } + }; + } + +<#if IsSpecialized> + static @NotNull ${Type}Iterator ofIterator(@NotNull ${PrimitiveIteratorType} it) { + Objects.requireNonNull(it); + if (it instanceof ${Type}Iterator) { + return (${Type}Iterator) it; + } + return new ${Type}Iterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public ${PrimitiveType} next${Type}() { + return it.next${Type}(); + } + + @Override + public String toString() { + return it.toString(); + } + }; + } + + + static @NotNull ${Type}Iterator concat(@NotNull ${Type}Iterator it1, @NotNull ${Type}Iterator it2) { + if (!it1.hasNext()) { //implicit null check of it1 + return Objects.requireNonNull(it2); + } + if (!it2.hasNext()) {//implicit null check of it1 + return it1; + } + return new ${Type}Iterators.Concat(it1, it2); + } + + static @NotNull ${Type}Iterator concat(@NotNull ${Type}Iterator... its) { + return switch (its.length) { // implicit null check of its + case 0 -> ${Type}Iterator.empty(); + case 1 -> Objects.requireNonNull(its[0]); + case 2 -> concat(its[0], its[1]); + default -> new ${Type}Iterators.ConcatAll(GenericArrays.iterator(its)); + }; + } + + static @NotNull ${Type}Iterator concat(@NotNull Iterable its) { + return concat(its.iterator()); // implicit null check of its + } + + static @NotNull ${Type}Iterator concat(@NotNull Iterator its) { + if (!its.hasNext()) { // implicit null check of its + return ${Type}Iterator.empty(); + } + return new ${Type}Iterators.ConcatAll(its); + } + + /** + * Returns the next {@code ${PrimitiveType}} element in the iteration. + * + * @return the next {@code ${PrimitiveType}} element in the iteration + * @throws NoSuchElementException if the iteration has no more elements + */ + ${PrimitiveType} next${Type}(); + + @Override + default void nextIgnoreResult() { + next${Type}(); + } + + @Override + @Deprecated + @ReplaceWith("next${Type}()") + default @NotNull ${WrapperType} next() { + return next${Type}(); + } + + default @NotNull ${Type}Option find(@NotNull ${Type}Predicate predicate) { + while (hasNext()) { + ${PrimitiveType} value = next${Type}(); + if (predicate.test(value)) { + return ${Type}Option.some(value); + } + } + return ${Type}Option.None; + } + + //region Element Conditions + + default boolean contains(${PrimitiveType} value) { + while (hasNext()) { + if (${PrimitiveEquals("value", "next${Type}()")}) { + return true; + } + } + return false; + } + + default boolean contains(Object value) { + if (!(value instanceof ${WrapperType})) { + return false; + } + + ${PrimitiveType} v = (${WrapperType}) value; + + while (hasNext()) { + if (${PrimitiveEquals("v", "next${Type}()")}) { + return true; + } + } + return false; + } + +<#if Type == "Boolean"> + default boolean containsAll(boolean @NotNull [] values) { + if (!hasNext()) { + return values.length == 0; + } + boolean containsTrue = false; + boolean containsFalse = false; + + while (hasNext()) { + boolean v = nextBoolean(); + if (v) { + containsTrue = true; + } else { + containsFalse = true; + } + if (containsTrue && containsFalse) { + return true; + } + } + + if (containsTrue && containsFalse) { + throw new AssertionError(); + } else if (containsTrue) { + for (boolean value : values) { + if (!value) { + return false; + } + } + } else if (containsFalse) { + for (boolean value : values) { + if (value) { + return false; + } + } + } else { + throw new AssertionError(); + } + return true; + } + + @Override + default boolean containsAll(Boolean @NotNull [] values) { + if (values.length == 0) { + return true; + } + if (!hasNext()) { + return false; + } + + boolean containsTrue = false; + boolean containsFalse = false; + + while (hasNext()) { + boolean v = nextBoolean(); + if (v) { + containsTrue = true; + } else { + containsFalse = true; + } + if (containsTrue && containsFalse) { + break; + } + } + + if (containsTrue && containsFalse) { + for (Boolean value : values) { + if (value == null) { + return false; + } + } + } else if (containsTrue) { + for (Boolean value : values) { + if (value == null || !value) { + return false; + } + } + } else if (containsFalse) { + for (Boolean value : values) { + if (value == null || value) { + return false; + } + } + } else { + throw new AssertionError(); + } + return true; + } + + @Override + default boolean containsAll(@NotNull Iterable values) { + Iterator it = values.iterator(); + if (!it.hasNext()) { + return true; + } + if (!hasNext()) { + return false; + } + + boolean containsTrue = false; + boolean containsFalse = false; + + while (hasNext()) { + boolean v = nextBoolean(); + if (v) { + containsTrue = true; + } else { + containsFalse = true; + } + if (containsTrue && containsFalse) { + break; + } + } + + if (containsTrue && containsFalse) { + while (it.hasNext()) { + Object value = it.next(); + if (!(value instanceof Boolean)) { + return false; + } + } + } else if (containsTrue) { + while (it.hasNext()) { + Object value = it.next(); + if (!(value instanceof Boolean) || !(Boolean) value) { + return false; + } + } + } else if (containsFalse) { + while (it.hasNext()) { + Object value = it.next(); + if (!(value instanceof Boolean) || (Boolean) value) { + return false; + } + } + } else { + throw new AssertionError(); + } + return true; + } +<#else> + default boolean containsAll(${PrimitiveType} @NotNull [] values) { + loop: + while (hasNext()) { + final ${PrimitiveType} v = next${Type}(); + for (${PrimitiveType} i : values) { + if (${PrimitiveEquals("i", "v")}) { + continue loop; + } + } + return false; + } + return true; + } + + +<#if IsSpecialized> + default boolean sameElements(@NotNull ${Type}Iterator other) { + return sameElements((${PrimitiveIteratorType}) other); + } + + + default boolean sameElements(@NotNull ${PrimitiveIteratorType} other) { + while (this.hasNext() && other.hasNext()) { + if (${PrimitiveNotEquals("this.next${Type}()", "other.next${Type}()")}) { + return false; + } + } + return this.hasNext() == other.hasNext(); + } + + @Override + default boolean sameElements(@NotNull Iterator other) { + if (other instanceof ${PrimitiveIteratorType}) { + return sameElements((${PrimitiveIteratorType}) other); + } + while (this.hasNext() && other.hasNext()) { + Object value = other.next(); + if(!(value instanceof ${WrapperType})) return false; + + if ((${PrimitiveNotEquals("(${WrapperType}) value", "this.next${Type}()")})) { + return false; + } + } + return this.hasNext() == other.hasNext(); + } + + default boolean anyMatch(@NotNull ${Type}Predicate predicate) { + while (hasNext()) { + if (predicate.test(next${Type}())) { + return true; + } + } + return false; + } + + default boolean allMatch(@NotNull ${Type}Predicate predicate) { + while (hasNext()) { + if (!predicate.test(next${Type}())) { + return false; + } + } + return true; + } + + default boolean noneMatch(@NotNull ${Type}Predicate predicate) { + while (hasNext()) { + if (predicate.test(next${Type}())) { + return false; + } + } + return true; + } + + //endregion + + //region Misc Operations + + @Override + default @NotNull ${Type}Iterator drop(int n) { + if (n < 0) { + throw new IllegalArgumentException(); + } + while (n > 0 && hasNext()) { + next${Type}(); + --n; + } + return this; + } + + default @NotNull ${Type}Iterator dropWhile(@NotNull ${Type}Predicate predicate) { + if (!hasNext()) { + return this; + } + + ${PrimitiveType} value = ${Values.Default}; + boolean p = false; + while (hasNext()) { + if (!predicate.test(value = next${Type}())) { + p = true; + break; + } + } + + if (p) { + return hasNext() ? prepended(value) : ${Type}Iterator.of(value); + } else { + return this; + } + } + + @Override + default @NotNull ${Type}Iterator take(int n) { + if (n < 0) { + throw new IllegalArgumentException(); + } + if (!hasNext() || n == 0) { + return empty(); + } + + return new ${Type}Iterators.Take(this, n); + } + + default @NotNull ${Type}Iterator takeWhile(@NotNull ${Type}Predicate predicate) { + Objects.requireNonNull(predicate); + if (!hasNext()) { + return this; + } + return new ${Type}Iterators.TakeWhile(this, predicate); + } + + default @NotNull ${Type}Iterator updated(int n, ${PrimitiveType} newValue) { + if (!hasNext() || n < 0) { + return this; + } + + if (n == 0) { + this.next${Type}(); + return prepended(newValue); + } + + return new ${Type}Iterators.Updated(this, n, newValue); + } + + default @NotNull ${Type}Iterator prepended(${PrimitiveType} value) { + return new ${Type}Iterators.Prepended(this, value); + } + + default @NotNull ${Type}Iterator appended(${PrimitiveType} value) { + return new ${Type}Iterators.Appended(this, value); + } + + default @NotNull ${Type}Iterator filter(@NotNull ${Type}Predicate predicate) { + Objects.requireNonNull(predicate); + if (!hasNext()) { + return empty(); + } + return new ${Type}Iterators.Filter(this, predicate, false); + } + + default @NotNull ${Type}Iterator filterNot(@NotNull ${Type}Predicate predicate) { + Objects.requireNonNull(predicate); + if (!hasNext()) { + return empty(); + } + return new ${Type}Iterators.Filter(this, predicate, true); + } + + default @NotNull ${Type}Iterator map(@NotNull ${Type}UnaryOperator mapper) { + Objects.requireNonNull(mapper); + if (!hasNext()) { + return this; + } + return new Abstract${Type}Iterator() { + @Override + public boolean hasNext() { + return ${Type}Iterator.this.hasNext(); + } + + @Override + public ${PrimitiveType} next${Type}() { + return mapper.applyAs${Type}(${Type}Iterator.this.next${Type}()); + } + }; + } + + default @NotNull Iterator mapToObj(@NotNull ${Type}Function mapper) { + Objects.requireNonNull(mapper); + if (!hasNext()) { + return Iterators.empty(); + } + return new AbstractIterator() { + @Override + public boolean hasNext() { + return ${Type}Iterator.this.hasNext(); + } + + @Override + public U next() { + return mapper.apply(${Type}Iterator.this.next${Type}()); + } + }; + } + + default @NotNull Tuple2<${r'@NotNull'} ${Type}Iterator, @NotNull ${Type}Iterator> span(@NotNull ${Type}Predicate predicate) { + if (!hasNext()) { + return Tuple.of(empty(), empty()); + } + + Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); + ${Type}Iterator it = this; + + while (it.hasNext()) { + ${PrimitiveType} e = it.next${Type}(); + if (predicate.test(e)) { + builder.append(e); + } else { + it = it.prepended(e); + break; + } + } + + return Tuple.of(builder.iterator(), it); + } + + //endregion + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G filterTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { + ${Type}Iterator it = this; + while (it.hasNext()) { + ${PrimitiveType} e = it.next${Type}(); + if (predicate.test(e)) { + destination.plusAssign(e); + } + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G filterNotTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { + ${Type}Iterator it = this; + while (it.hasNext()) { + ${PrimitiveType} e = it.next${Type}(); + if (!predicate.test(e)) { + destination.plusAssign(e); + } + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapTo(@NotNull G destination, @NotNull ${Type}UnaryOperator mapper) { + ${Type}Iterator it = this; + while (it.hasNext()) { + destination.plusAssign(mapper.applyAs${Type}(it.next${Type}())); + } + return destination; + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G mapToObjTo(@NotNull G destination, @NotNull ${Type}Function mapper) { + ${Type}Iterator it = this; + while (it.hasNext()) { + destination.plusAssign(mapper.apply(it.next${Type}())); + } + return destination; + } + + //region Aggregate Operations + + default int count(@NotNull ${Type}Predicate predicate) { + int c = 0; + while (hasNext()) { + if (predicate.test(next${Type}())) { + ++c; + } + } + return c; + } + + default ${PrimitiveType} max() { + if (!hasNext()) { + throw new NoSuchElementException(); + } +<#if Type == 'Boolean'> + + while (hasNext()) { + if (nextBoolean()) return true; + } + + return false; +<#else> + ${PrimitiveType} value = next${Type}(); + while (hasNext()) { +<#if IsSpecialized || Type == 'Float'> + value = Math.max(value, next${Type}()); +<#else> + value = (${PrimitiveType}) Math.max(value, next${Type}()); + + } + return value; + + } + + @Override + default @Nullable ${WrapperType} maxOrNull() { + return hasNext() ? max() : null; + } + + @Override + default @NotNull ${Type}Option maxOption() { + return hasNext() ? ${Type}Option.some(max()) : ${Type}Option.none(); + } + + default ${PrimitiveType} min() { + if (!hasNext()) { + throw new NoSuchElementException(); + } +<#if Type == 'Boolean'> + + while (hasNext()) { + if (!nextBoolean()) return false; + } + + return true; +<#else> + ${PrimitiveType} value = next${Type}(); + while (hasNext()) { +<#if IsSpecialized || Type == 'Float'> + value = Math.min(value, next${Type}()); +<#else> + value = (${PrimitiveType}) Math.min(value, next${Type}()); + + } + return value; + + } + + @Override + default @Nullable ${WrapperType} minOrNull() { + return hasNext() ? min() : null; + } + + @Override + default @NotNull ${Type}Option minOption() { + return hasNext() ? ${Type}Option.some(min()) : ${Type}Option.none(); + } + + default ${PrimitiveType} fold(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + return foldLeft(zero, op); + } + + default ${PrimitiveType} foldLeft(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + while (hasNext()) { + zero = op.applyAs${Type}(zero, this.next${Type}()); + } + return zero; + } + + default U foldLeftToObj(U zero, @NotNull Obj${Type}BiFunction op) { + while (hasNext()) { + zero = op.apply(zero, this.next${Type}()); + } + return zero; + } + + default ${PrimitiveType} foldRight(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + if (!hasNext()) { + return zero; + } + Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); + while (hasNext()) { + builder.append(next${Type}()); + } + for (int i = builder.size() - 1; i >= 0; i--) { + zero = op.applyAs${Type}(builder.get(i), zero); + } + return zero; + } + + default U foldRightToObj(U zero, @NotNull ${Type}ObjBiFunction op) { + if (!hasNext()) { + return zero; + } + Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); + while (hasNext()) { + builder.append(next${Type}()); + } + for (int i = builder.size() - 1; i >= 0; i--) { + zero = op.apply(builder.get(i), zero); + } + return zero; + } + + default ${PrimitiveType} reduce(@NotNull ${Type}BinaryOperator op) { + return reduceLeft(op); + } + + default @Nullable ${WrapperType} reduceOrNull(@NotNull ${Type}BinaryOperator op) { + return reduceLeftOrNull(op); + } + + default @NotNull ${Type}Option reduceOption(@NotNull ${Type}BinaryOperator op) { + return reduceLeftOption(op); + } + + default ${PrimitiveType} reduceLeft(@NotNull ${Type}BinaryOperator op) { + ${PrimitiveType} e = next${Type}(); + while (hasNext()) { + e = op.applyAs${Type}(e, next${Type}()); + } + return e; + } + + default @Nullable ${WrapperType} reduceLeftOrNull(@NotNull ${Type}BinaryOperator op) { + return hasNext() ? reduceLeft(op) : null; + } + + default @NotNull ${Type}Option reduceLeftOption(@NotNull ${Type}BinaryOperator op) { + return hasNext() ? ${Type}Option.some(reduceLeft(op)) : ${Type}Option.none(); + } + + default ${PrimitiveType} reduceRight(@NotNull ${Type}BinaryOperator op) { + if (!hasNext()) { + throw new NoSuchElementException(); + } + Internal${Type}ArrayBuilder list = new Internal${Type}ArrayBuilder(); + list.append(next${Type}()); + while (hasNext()) { + list.append(next${Type}()); + } + final int size = list.size(); + ${PrimitiveType} e = list.get(size - 1); + + for (int i = size - 2; i >= 0; i--) { + e = op.applyAs${Type}(list.get(i), e); + } + return e; + } + + default @Nullable ${WrapperType} reduceRightOrNull(@NotNull ${Type}BinaryOperator op) { + return hasNext() ? reduceRight(op) : null; + } + + default @NotNull ${Type}Option reduceRightOption(@NotNull ${Type}BinaryOperator op) { + return hasNext() ? ${Type}Option.some(reduceRight(op)) : ${Type}Option.none(); + } + + //endregion + + //region Conversion Operations + + @Override + default ${PrimitiveType} @NotNull [] toArray() { + if (!hasNext()) { + return ${Type}Arrays.EMPTY; + } + Internal${Type}ArrayBuilder builder = new Internal${Type}ArrayBuilder(); + while (hasNext()) { + builder.append(next${Type}()); + } + + return builder.toArray(); + } + + //endregion + + //region Traverse Operations + + @Override + default void forEach(@NotNull ${Type}Consumer action) { + while (hasNext()) { + action.accept(next${Type}()); + } + } + + @Override + default void forEachRemaining(@NotNull Consumer action) { + if (action instanceof ${Type}Consumer) { + forEach(((${Type}Consumer) action)); + } else { + forEach(action::accept); + } + } + + @Override + default void forEachRemaining(@NotNull ${Type}Consumer action) { + forEach(action); + } + + //endregion + + //region + + @Override + default @NotNull A joinTo(@NotNull A buffer, CharSequence separator, CharSequence prefix, CharSequence postfix) { + try { + buffer.append(prefix); + if (hasNext()) { + buffer.append(String.valueOf(next${Type}())); + } + while (hasNext()) { + buffer.append(separator).append(String.valueOf(next${Type}())); + } + buffer.append(postfix); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return buffer; + } + + //endregion + + @Override + default int hash() { + int res = 0; + while (hasNext()) { + res = res * 31 + ${WrapperType}.hashCode(next${Type}()); + } + return res; + } } \ No newline at end of file diff --git a/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveTraversable.java.ftl b/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveTraversable.java.ftl index e05cc68f..6e677207 100644 --- a/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveTraversable.java.ftl +++ b/kala-base/src/main/template/kala/collection/base/primitive/PrimitiveTraversable.java.ftl @@ -1,454 +1,454 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.base.primitive; - -import kala.collection.base.Growable; -import kala.collection.factory.primitive.${Type}CollectionFactory; -import kala.control.primitive.${Type}Option; -import kala.function.*; - -import org.intellij.lang.annotations.Flow; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Contract; - -import java.util.NoSuchElementException; -import java.util.Objects; -<#if IsSpecialized> -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.*; -import java.util.stream.${Type}Stream; -import java.util.stream.StreamSupport; - - -public interface ${Type}Traversable extends PrimitiveTraversable<${WrapperType}> { - - @Override - @NotNull ${Type}Iterator iterator(); -<#if IsSpecialized> - - @Override - default @NotNull Spliterator.Of${Type} spliterator() { - final int ks = this.knownSize(); - if (ks == 0) { - return Spliterators.empty${Type}Spliterator(); - } else if (ks > 0) { - return Spliterators.spliterator(iterator(), ks, characteristics()); - } else { - return Spliterators.spliteratorUnknownSize(iterator(), characteristics()); - } - } - - @Override - default @NotNull ${Type}Stream stream() { - return StreamSupport.${PrimitiveType}Stream(spliterator(), false); - } - - @Override - default @NotNull ${Type}Stream parallelStream() { - return StreamSupport.${PrimitiveType}Stream(spliterator(), true); - } - - - default ${PrimitiveType} elementAt(int index) { - if (index < 0) { - throw new IndexOutOfBoundsException(); - } - - final int knownSize = this.knownSize(); - if (knownSize >= 0 && index >= knownSize) { - throw new IndexOutOfBoundsException(); - } - - final ${Type}Iterator it = this.iterator(); - for (int i = 0; i < index; i++) { - if (it.hasNext()) { - it.next${Type}(); - } else { - throw new IndexOutOfBoundsException("index: " + index); - } - } - if (it.hasNext()) { - return it.next${Type}(); - } else { - throw new IndexOutOfBoundsException("index: " + index); - } - } - - - //region Element Retrieval Operations - - default @NotNull ${Type}Option find(@NotNull ${Type}Predicate predicate) { - return iterator().find(predicate); - } - - //endregion - - //region Element Conditions - - default boolean contains(${PrimitiveType} value) { - return knownSize() != 0 && iterator().contains(value); - } - - default boolean containsAll(${PrimitiveType} @NotNull [] values) { - return iterator().containsAll(values); - } - - default boolean containsAll(@NotNull ${Type}Traversable values) { -<#if Type == 'Boolean'> - BooleanIterator it1 = this.iterator(); - BooleanIterator it2 = values.iterator(); - if (!it2.hasNext()) { - return true; - } - if (!it1.hasNext()) { - return false; - } - - boolean containsTrue = false; - boolean containsFalse = false; - - while (it1.hasNext()) { - boolean v = it1.nextBoolean(); - if (v) { - containsTrue = true; - } else { - containsFalse = true; - } - if (containsTrue && containsFalse) { - return true; - } - } - - if (containsTrue) { - while (it2.hasNext()) { - boolean value = it2.nextBoolean(); - if (!value) { - return false; - } - } - } else { - while (it2.hasNext()) { - boolean value = it2.nextBoolean(); - if (value) { - return false; - } - } - } - return true; -<#else> - ${Type}Iterator it = values.iterator(); - if (knownSize() == 0) { - return !it.hasNext(); - } - while (it.hasNext()) { - if (!contains(it.next${Type}())) { - return false; - } - } - return true; - - } - - default boolean sameElements(@NotNull ${Type}Traversable other) { - return iterator().sameElements(other.iterator()); - } - - default boolean sameElements(@NotNull Iterable other) { - return iterator().sameElements(other.iterator()); - } - - /** - * Tests whether any element of this {@code ${Type}Traversable} match the {@code predicate}. - * - * @return {@code true} if either any element of this {@code Traversable} match the {@code predicate}, - * otherwise {@code false} - */ - default boolean anyMatch(@NotNull ${Type}Predicate predicate) { - return iterator().anyMatch(predicate); - } - - /** - * Tests whether all elements of this {@code ${Type}Traversable} match the {@code predicate}. - * - * @return {@code true} if either all elements of this {@code Traversable} match the {@code predicate} or - * the {@code Traversable} is empty, otherwise {@code false} - */ - default boolean allMatch(@NotNull ${Type}Predicate predicate) { - return iterator().allMatch(predicate); - } - - /** - * Tests whether none elements of this {@code ${Type}Traversable} match the {@code predicate}. - * - * @return {@code true} if either none elements of this {@code Traversable} match the {@code predicate} or - * the {@code Traversable} is empty, otherwise {@code false} - */ - default boolean noneMatch(@NotNull ${Type}Predicate predicate) { - return iterator().noneMatch(predicate); - } - - //endregion - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G filterTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { - return iterator().filterTo(destination, predicate); - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G filterNotTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { - return iterator().filterNotTo(destination, predicate); - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default @NotNull G mapTo(@NotNull G destination, @NotNull ${Type}UnaryOperator mapper) { - return iterator().mapTo(destination, mapper); - } - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G mapToObjTo(@NotNull G destination, @NotNull ${Type}Function mapper) { - return iterator().mapToObjTo(destination, mapper); - } - - - //region Aggregate Operations - - default int count(@NotNull ${Type}Predicate predicate) { - return iterator().count(predicate); - } - - default ${PrimitiveType} max() { - if (knownSize() == 0) { - throw new NoSuchElementException(); - } - return iterator().max(); - } - - @Override - default @Nullable ${WrapperType} maxOrNull() { - return isNotEmpty() ? max() : null; - } - - @Override - default @NotNull ${Type}Option maxOption() { - return knownSize() == 0 ? ${Type}Option.none() : iterator().maxOption(); - } - - default ${PrimitiveType} min() { - if (knownSize() == 0) { - throw new NoSuchElementException(); - } - return iterator().min(); - } - - @Override - default @Nullable ${WrapperType} minOrNull() { - return knownSize() == 0 ? null : iterator().minOrNull(); - } - - @Override - default @NotNull ${Type}Option minOption() { - return knownSize() == 0 ? ${Type}Option.none() : iterator().minOption(); - } - - default ${PrimitiveType} fold(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - return foldLeft(zero, op); - } - - default ${PrimitiveType} foldLeft(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - return iterator().foldLeft(zero, op); - } - - default U foldLeftToObj(U zero, @NotNull Obj${Type}BiFunction op) { - return iterator().foldLeftToObj(zero, op); - } - - default ${PrimitiveType} foldRight(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { - return iterator().foldRight(zero, op); - } - - default U foldRightToObj(U zero, @NotNull ${Type}ObjBiFunction op) { - return iterator().foldRightToObj(zero, op); - } - - default ${PrimitiveType} reduce(@NotNull ${Type}BinaryOperator op) { - return reduceLeft(op); - } - - default @Nullable ${WrapperType} reduceOrNull(@NotNull ${Type}BinaryOperator op) { - return reduceLeftOrNull(op); - } - - default @NotNull ${Type}Option reduceOption(@NotNull ${Type}BinaryOperator op) { - return reduceLeftOption(op); - } - - default ${PrimitiveType} reduceLeft(@NotNull ${Type}BinaryOperator op) { - return iterator().reduceLeft(op); - } - - default @Nullable ${WrapperType} reduceLeftOrNull(@NotNull ${Type}BinaryOperator op) { - return isNotEmpty() ? reduceLeft(op) : null; - } - - default @NotNull ${Type}Option reduceLeftOption(@NotNull ${Type}BinaryOperator op) { - return isNotEmpty() ? ${Type}Option.some(reduceLeft(op)) : ${Type}Option.none(); - } - - default ${PrimitiveType} reduceRight(@NotNull ${Type}BinaryOperator op) { - return iterator().reduceRight(op); - } - - default @Nullable ${WrapperType} reduceRightOrNull(@NotNull ${Type}BinaryOperator op) { - return isNotEmpty() ? reduceRight(op) : null; - } - - default @NotNull ${Type}Option reduceRightOption(@NotNull ${Type}BinaryOperator op) { - return isNotEmpty() ? ${Type}Option.some(reduceRight(op)) : ${Type}Option.none(); - } - - //endregion - - //region Copy Operations - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(${PrimitiveType} @NotNull [] dest) { - return copyToArray(0, dest, 0, Integer.MAX_VALUE); - } - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(${PrimitiveType} @NotNull [] dest, int destPos) { - return copyToArray(0, dest, destPos, Integer.MAX_VALUE); - } - - @Contract(mutates = "param1") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(${PrimitiveType} @NotNull [] dest, int destPos, int limit) { - return copyToArray(0, dest, destPos, limit); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest) { - return copyToArray(srcPos, dest, 0, Integer.MAX_VALUE); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest, int destPos) { - return copyToArray(srcPos, dest, destPos, Integer.MAX_VALUE); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest, int destPos, int limit) { - if (srcPos < 0) { - throw new IllegalArgumentException("srcPos(" + srcPos + ") < 0"); - } - if (destPos < 0) { - throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); - } - - if (limit <= 0) { - return 0; - } - - final int dl = dest.length; //implicit null check of dest - if (destPos > dl) { - return 0; - } - - final int kn = this.knownSize(); - if (kn >= 0 && srcPos >= kn) { - return 0; - } - - int end = Math.min(dl - destPos, limit) + destPos; - - int n = 0; - ${Type}Iterator it = this.iterator(); - while (n++ < srcPos) { - if (it.hasNext()) { - it.next${Type}(); - } else { - return 0; - } - } - - int idx = destPos; - while (it.hasNext() && idx < end) { - dest[idx++] = it.next${Type}(); - } - return idx - destPos; - } - - //endregion - - default R collect(@NotNull ${Type}CollectionFactory factory) { - return ${Type}CollectionFactory.buildBy(factory, this::forEach); - } - - default @NotNull G collect(@NotNull G destination) { - destination.plusAssign(this); - return destination; - } - - default ${PrimitiveType} @NotNull [] toArray() { - int s = knownSize(); - if (s == 0) { - return ${Type}Arrays.EMPTY; - } else if (s > 0) { - ${PrimitiveType}[] arr = new ${PrimitiveType}[s]; - int i = 0; - for (${Type}Iterator iterator = this.iterator(); iterator.hasNext(); ) { - ${PrimitiveType} t = iterator.next${Type}(); - arr[i++] = t; - } - return arr; - } else { - return iterator().toArray(); - } - } - - //region Traverse Operations - - default void forEach(@NotNull ${Type}Consumer action) { - iterator().forEach(action); - } - - default void forEachChecked(@NotNull Checked${Type}Consumer action) throws Ex { - forEach(action); - } - - default void forEachUnchecked(@NotNull Checked${Type}Consumer action) { - forEach(action); - } - - default void forEachBreakable(@NotNull ${Type}Predicate action) { - Objects.requireNonNull(action); - ${Type}Iterator it = this.iterator(); - while (it.hasNext()) { - if (!action.test(it.next${Type}())) { - break; - } - } - } - - //endregion -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.base.primitive; + +import kala.collection.base.Growable; +import kala.collection.factory.primitive.${Type}CollectionFactory; +import kala.control.primitive.${Type}Option; +import kala.function.*; + +import org.intellij.lang.annotations.Flow; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Contract; + +import java.util.NoSuchElementException; +import java.util.Objects; +<#if IsSpecialized> +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.*; +import java.util.stream.${Type}Stream; +import java.util.stream.StreamSupport; + + +public interface ${Type}Traversable extends PrimitiveTraversable<${WrapperType}> { + + @Override + @NotNull ${Type}Iterator iterator(); +<#if IsSpecialized> + + @Override + default @NotNull Spliterator.Of${Type} spliterator() { + final int ks = this.knownSize(); + if (ks == 0) { + return Spliterators.empty${Type}Spliterator(); + } else if (ks > 0) { + return Spliterators.spliterator(iterator(), ks, characteristics()); + } else { + return Spliterators.spliteratorUnknownSize(iterator(), characteristics()); + } + } + + @Override + default @NotNull ${Type}Stream stream() { + return StreamSupport.${PrimitiveType}Stream(spliterator(), false); + } + + @Override + default @NotNull ${Type}Stream parallelStream() { + return StreamSupport.${PrimitiveType}Stream(spliterator(), true); + } + + + default ${PrimitiveType} elementAt(int index) { + if (index < 0) { + throw new IndexOutOfBoundsException(); + } + + final int knownSize = this.knownSize(); + if (knownSize >= 0 && index >= knownSize) { + throw new IndexOutOfBoundsException(); + } + + final ${Type}Iterator it = this.iterator(); + for (int i = 0; i < index; i++) { + if (it.hasNext()) { + it.next${Type}(); + } else { + throw new IndexOutOfBoundsException("index: " + index); + } + } + if (it.hasNext()) { + return it.next${Type}(); + } else { + throw new IndexOutOfBoundsException("index: " + index); + } + } + + + //region Element Retrieval Operations + + default @NotNull ${Type}Option find(@NotNull ${Type}Predicate predicate) { + return iterator().find(predicate); + } + + //endregion + + //region Element Conditions + + default boolean contains(${PrimitiveType} value) { + return knownSize() != 0 && iterator().contains(value); + } + + default boolean containsAll(${PrimitiveType} @NotNull [] values) { + return iterator().containsAll(values); + } + + default boolean containsAll(@NotNull ${Type}Traversable values) { +<#if Type == 'Boolean'> + BooleanIterator it1 = this.iterator(); + BooleanIterator it2 = values.iterator(); + if (!it2.hasNext()) { + return true; + } + if (!it1.hasNext()) { + return false; + } + + boolean containsTrue = false; + boolean containsFalse = false; + + while (it1.hasNext()) { + boolean v = it1.nextBoolean(); + if (v) { + containsTrue = true; + } else { + containsFalse = true; + } + if (containsTrue && containsFalse) { + return true; + } + } + + if (containsTrue) { + while (it2.hasNext()) { + boolean value = it2.nextBoolean(); + if (!value) { + return false; + } + } + } else { + while (it2.hasNext()) { + boolean value = it2.nextBoolean(); + if (value) { + return false; + } + } + } + return true; +<#else> + ${Type}Iterator it = values.iterator(); + if (knownSize() == 0) { + return !it.hasNext(); + } + while (it.hasNext()) { + if (!contains(it.next${Type}())) { + return false; + } + } + return true; + + } + + default boolean sameElements(@NotNull ${Type}Traversable other) { + return iterator().sameElements(other.iterator()); + } + + default boolean sameElements(@NotNull Iterable other) { + return iterator().sameElements(other.iterator()); + } + + /** + * Tests whether any element of this {@code ${Type}Traversable} match the {@code predicate}. + * + * @return {@code true} if either any element of this {@code Traversable} match the {@code predicate}, + * otherwise {@code false} + */ + default boolean anyMatch(@NotNull ${Type}Predicate predicate) { + return iterator().anyMatch(predicate); + } + + /** + * Tests whether all elements of this {@code ${Type}Traversable} match the {@code predicate}. + * + * @return {@code true} if either all elements of this {@code Traversable} match the {@code predicate} or + * the {@code Traversable} is empty, otherwise {@code false} + */ + default boolean allMatch(@NotNull ${Type}Predicate predicate) { + return iterator().allMatch(predicate); + } + + /** + * Tests whether none elements of this {@code ${Type}Traversable} match the {@code predicate}. + * + * @return {@code true} if either none elements of this {@code Traversable} match the {@code predicate} or + * the {@code Traversable} is empty, otherwise {@code false} + */ + default boolean noneMatch(@NotNull ${Type}Predicate predicate) { + return iterator().noneMatch(predicate); + } + + //endregion + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G filterTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { + return iterator().filterTo(destination, predicate); + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G filterNotTo(@NotNull G destination, @NotNull ${Type}Predicate predicate) { + return iterator().filterNotTo(destination, predicate); + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default @NotNull G mapTo(@NotNull G destination, @NotNull ${Type}UnaryOperator mapper) { + return iterator().mapTo(destination, mapper); + } + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G mapToObjTo(@NotNull G destination, @NotNull ${Type}Function mapper) { + return iterator().mapToObjTo(destination, mapper); + } + + + //region Aggregate Operations + + default int count(@NotNull ${Type}Predicate predicate) { + return iterator().count(predicate); + } + + default ${PrimitiveType} max() { + if (knownSize() == 0) { + throw new NoSuchElementException(); + } + return iterator().max(); + } + + @Override + default @Nullable ${WrapperType} maxOrNull() { + return isNotEmpty() ? max() : null; + } + + @Override + default @NotNull ${Type}Option maxOption() { + return knownSize() == 0 ? ${Type}Option.none() : iterator().maxOption(); + } + + default ${PrimitiveType} min() { + if (knownSize() == 0) { + throw new NoSuchElementException(); + } + return iterator().min(); + } + + @Override + default @Nullable ${WrapperType} minOrNull() { + return knownSize() == 0 ? null : iterator().minOrNull(); + } + + @Override + default @NotNull ${Type}Option minOption() { + return knownSize() == 0 ? ${Type}Option.none() : iterator().minOption(); + } + + default ${PrimitiveType} fold(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + return foldLeft(zero, op); + } + + default ${PrimitiveType} foldLeft(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + return iterator().foldLeft(zero, op); + } + + default U foldLeftToObj(U zero, @NotNull Obj${Type}BiFunction op) { + return iterator().foldLeftToObj(zero, op); + } + + default ${PrimitiveType} foldRight(${PrimitiveType} zero, @NotNull ${Type}BinaryOperator op) { + return iterator().foldRight(zero, op); + } + + default U foldRightToObj(U zero, @NotNull ${Type}ObjBiFunction op) { + return iterator().foldRightToObj(zero, op); + } + + default ${PrimitiveType} reduce(@NotNull ${Type}BinaryOperator op) { + return reduceLeft(op); + } + + default @Nullable ${WrapperType} reduceOrNull(@NotNull ${Type}BinaryOperator op) { + return reduceLeftOrNull(op); + } + + default @NotNull ${Type}Option reduceOption(@NotNull ${Type}BinaryOperator op) { + return reduceLeftOption(op); + } + + default ${PrimitiveType} reduceLeft(@NotNull ${Type}BinaryOperator op) { + return iterator().reduceLeft(op); + } + + default @Nullable ${WrapperType} reduceLeftOrNull(@NotNull ${Type}BinaryOperator op) { + return isNotEmpty() ? reduceLeft(op) : null; + } + + default @NotNull ${Type}Option reduceLeftOption(@NotNull ${Type}BinaryOperator op) { + return isNotEmpty() ? ${Type}Option.some(reduceLeft(op)) : ${Type}Option.none(); + } + + default ${PrimitiveType} reduceRight(@NotNull ${Type}BinaryOperator op) { + return iterator().reduceRight(op); + } + + default @Nullable ${WrapperType} reduceRightOrNull(@NotNull ${Type}BinaryOperator op) { + return isNotEmpty() ? reduceRight(op) : null; + } + + default @NotNull ${Type}Option reduceRightOption(@NotNull ${Type}BinaryOperator op) { + return isNotEmpty() ? ${Type}Option.some(reduceRight(op)) : ${Type}Option.none(); + } + + //endregion + + //region Copy Operations + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(${PrimitiveType} @NotNull [] dest) { + return copyToArray(0, dest, 0, Integer.MAX_VALUE); + } + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(${PrimitiveType} @NotNull [] dest, int destPos) { + return copyToArray(0, dest, destPos, Integer.MAX_VALUE); + } + + @Contract(mutates = "param1") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(${PrimitiveType} @NotNull [] dest, int destPos, int limit) { + return copyToArray(0, dest, destPos, limit); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest) { + return copyToArray(srcPos, dest, 0, Integer.MAX_VALUE); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest, int destPos) { + return copyToArray(srcPos, dest, destPos, Integer.MAX_VALUE); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyToArray(int srcPos, ${PrimitiveType} @NotNull [] dest, int destPos, int limit) { + if (srcPos < 0) { + throw new IllegalArgumentException("srcPos(" + srcPos + ") < 0"); + } + if (destPos < 0) { + throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); + } + + if (limit <= 0) { + return 0; + } + + final int dl = dest.length; //implicit null check of dest + if (destPos > dl) { + return 0; + } + + final int kn = this.knownSize(); + if (kn >= 0 && srcPos >= kn) { + return 0; + } + + int end = Math.min(dl - destPos, limit) + destPos; + + int n = 0; + ${Type}Iterator it = this.iterator(); + while (n++ < srcPos) { + if (it.hasNext()) { + it.next${Type}(); + } else { + return 0; + } + } + + int idx = destPos; + while (it.hasNext() && idx < end) { + dest[idx++] = it.next${Type}(); + } + return idx - destPos; + } + + //endregion + + default R collect(@NotNull ${Type}CollectionFactory factory) { + return ${Type}CollectionFactory.buildBy(factory, this::forEach); + } + + default @NotNull G collect(@NotNull G destination) { + destination.plusAssign(this); + return destination; + } + + default ${PrimitiveType} @NotNull [] toArray() { + int s = knownSize(); + if (s == 0) { + return ${Type}Arrays.EMPTY; + } else if (s > 0) { + ${PrimitiveType}[] arr = new ${PrimitiveType}[s]; + int i = 0; + for (${Type}Iterator iterator = this.iterator(); iterator.hasNext(); ) { + ${PrimitiveType} t = iterator.next${Type}(); + arr[i++] = t; + } + return arr; + } else { + return iterator().toArray(); + } + } + + //region Traverse Operations + + default void forEach(@NotNull ${Type}Consumer action) { + iterator().forEach(action); + } + + default void forEachChecked(@NotNull Checked${Type}Consumer action) throws Ex { + forEach(action); + } + + default void forEachUnchecked(@NotNull Checked${Type}Consumer action) { + forEach(action); + } + + default void forEachBreakable(@NotNull ${Type}Predicate action) { + Objects.requireNonNull(action); + ${Type}Iterator it = this.iterator(); + while (it.hasNext()) { + if (!action.test(it.next${Type}())) { + break; + } + } + } + + //endregion +} diff --git a/kala-base/src/main/template/kala/comparator/primitive/PrimitiveComparators.java.ftl b/kala-base/src/main/template/kala/comparator/primitive/PrimitiveComparators.java.ftl index cd8d1697..5cf10743 100644 --- a/kala-base/src/main/template/kala/comparator/primitive/PrimitiveComparators.java.ftl +++ b/kala-base/src/main/template/kala/comparator/primitive/PrimitiveComparators.java.ftl @@ -1,218 +1,218 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.comparator.primitive; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.Serial; -import java.io.Serializable; - -final class ${Type}Comparators { - enum NaturalOrderComparator implements ${Type}Comparator { - INSTANCE; - - @Override - public final int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { - return ${WrapperType}.compare(${Var}1, b2); - } - - @Override - public final @NotNull ${Type}Comparator nullsFirst() { - return NaturalOrderNullComparator.NULLS_FIRST; - } - - @Override - public final @NotNull ${Type}Comparator nullsLast() { - return NaturalOrderNullComparator.NULLS_LAST; - } - - @Override - public final @NotNull ${Type}Comparator reversed() { - return ReverseOrderComparator.INSTANCE; - } - } - - enum ReverseOrderComparator implements ${Type}Comparator { - INSTANCE; - - @Override - public final int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { - return ${WrapperType}.compare(b2, ${Var}1); - } - - @Override - public final @NotNull ${Type}Comparator nullsFirst() { - return ReverseOrderNullComparator.NULLS_FIRST; - } - - @Override - public final @NotNull ${Type}Comparator nullsLast() { - return ReverseOrderNullComparator.NULLS_LAST; - } - - @Override - public final @NotNull ${Type}Comparator reversed() { - return NaturalOrderComparator.INSTANCE; - } - } - - static final class NullComparator implements ${Type}Comparator, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - private final boolean nullFirst; - - private final @NotNull ${Type}Comparator real; - - NullComparator(boolean nullFirst, @NotNull ${Type}Comparator real) { - this.nullFirst = nullFirst; - this.real = real; - } - - @Override - public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { - return real.compare(${Var}1, b2); - } - - @Override - public int compare(@Nullable ${WrapperType} ${Var}1, @Nullable ${WrapperType} b2) { - if (${Var}1 == null) { - return (b2 == null) ? 0 : (nullFirst ? -1 : 1); - } else if (b2 == null) { - return nullFirst ? 1 : -1; - } else { - return real.compare(${Var}1, b2); - } - } - - @Override - public @NotNull ${Type}Comparator nullsFirst() { - return nullFirst ? this : new NullComparator(true, real); - } - - @Override - public @NotNull ${Type}Comparator nullsLast() { - return nullFirst ? new NullComparator(false, real) : this; - } - - @Override - public @NotNull ${Type}Comparator reversed() { - return new NullComparator(!nullFirst, real.reversed()); - } - - } - - static final class NaturalOrderNullComparator implements ${Type}Comparator, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - static final NaturalOrderNullComparator NULLS_FIRST = new NaturalOrderNullComparator(true); - static final NaturalOrderNullComparator NULLS_LAST = new NaturalOrderNullComparator(false); - - private final boolean nullFirst; - - NaturalOrderNullComparator(boolean nullFirst) { - this.nullFirst = nullFirst; - } - - @Override - public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { - return ${WrapperType}.compare(${Var}1, b2); - } - - @Override - public int compare(${WrapperType} ${Var}1, ${WrapperType} b2) { - if (${Var}1 == null) { - return (b2 == null) ? 0 : (nullFirst ? -1 : 1); - } else if (b2 == null) { - return nullFirst ? 1 : -1; - } else { - return ${Var}1.compareTo(b2); - } - } - - @Override - public @NotNull ${Type}Comparator nullsFirst() { - return NULLS_FIRST; - } - - @Override - public @NotNull ${Type}Comparator nullsLast() { - return NULLS_LAST; - } - - @Override - public @NotNull ${Type}Comparator reversed() { - return nullFirst ? ReverseOrderNullComparator.NULLS_LAST : ReverseOrderNullComparator.NULLS_FIRST; - } - - @Serial - private Object readResolve() { - return nullFirst ? NULLS_FIRST : NULLS_LAST; - } - } - - static final class ReverseOrderNullComparator implements ${Type}Comparator, Serializable { - @Serial - private static final long serialVersionUID = 0L; - - static final ReverseOrderNullComparator NULLS_FIRST = new ReverseOrderNullComparator(true); - static final ReverseOrderNullComparator NULLS_LAST = new ReverseOrderNullComparator(false); - - private final boolean nullFirst; - - ReverseOrderNullComparator(boolean nullFirst) { - this.nullFirst = nullFirst; - } - - @Override - public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} ${Var}2) { - return ${WrapperType}.compare(${Var}2, ${Var}1); - } - - @Override - public int compare(${WrapperType} ${Var}1, ${WrapperType} ${Var}2) { - if (${Var}1 == null) { - return (${Var}2 == null) ? 0 : (nullFirst ? -1 : 1); - } else if (${Var}2 == null) { - return nullFirst ? 1 : -1; - } else { - return ${Var}2.compareTo(${Var}1); - } - } - - @Override - public @NotNull ${Type}Comparator nullsFirst() { - return NULLS_FIRST; - } - - @Override - public @NotNull ${Type}Comparator nullsLast() { - return NULLS_LAST; - } - - @Override - public @NotNull ${Type}Comparator reversed() { - return nullFirst ? NaturalOrderNullComparator.NULLS_LAST : NaturalOrderNullComparator.NULLS_FIRST; - } - - @Serial - private Object readResolve() { - return nullFirst ? NULLS_FIRST : NULLS_LAST; - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.comparator.primitive; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.Serial; +import java.io.Serializable; + +final class ${Type}Comparators { + enum NaturalOrderComparator implements ${Type}Comparator { + INSTANCE; + + @Override + public final int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { + return ${WrapperType}.compare(${Var}1, b2); + } + + @Override + public final @NotNull ${Type}Comparator nullsFirst() { + return NaturalOrderNullComparator.NULLS_FIRST; + } + + @Override + public final @NotNull ${Type}Comparator nullsLast() { + return NaturalOrderNullComparator.NULLS_LAST; + } + + @Override + public final @NotNull ${Type}Comparator reversed() { + return ReverseOrderComparator.INSTANCE; + } + } + + enum ReverseOrderComparator implements ${Type}Comparator { + INSTANCE; + + @Override + public final int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { + return ${WrapperType}.compare(b2, ${Var}1); + } + + @Override + public final @NotNull ${Type}Comparator nullsFirst() { + return ReverseOrderNullComparator.NULLS_FIRST; + } + + @Override + public final @NotNull ${Type}Comparator nullsLast() { + return ReverseOrderNullComparator.NULLS_LAST; + } + + @Override + public final @NotNull ${Type}Comparator reversed() { + return NaturalOrderComparator.INSTANCE; + } + } + + static final class NullComparator implements ${Type}Comparator, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + private final boolean nullFirst; + + private final @NotNull ${Type}Comparator real; + + NullComparator(boolean nullFirst, @NotNull ${Type}Comparator real) { + this.nullFirst = nullFirst; + this.real = real; + } + + @Override + public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { + return real.compare(${Var}1, b2); + } + + @Override + public int compare(@Nullable ${WrapperType} ${Var}1, @Nullable ${WrapperType} b2) { + if (${Var}1 == null) { + return (b2 == null) ? 0 : (nullFirst ? -1 : 1); + } else if (b2 == null) { + return nullFirst ? 1 : -1; + } else { + return real.compare(${Var}1, b2); + } + } + + @Override + public @NotNull ${Type}Comparator nullsFirst() { + return nullFirst ? this : new NullComparator(true, real); + } + + @Override + public @NotNull ${Type}Comparator nullsLast() { + return nullFirst ? new NullComparator(false, real) : this; + } + + @Override + public @NotNull ${Type}Comparator reversed() { + return new NullComparator(!nullFirst, real.reversed()); + } + + } + + static final class NaturalOrderNullComparator implements ${Type}Comparator, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + static final NaturalOrderNullComparator NULLS_FIRST = new NaturalOrderNullComparator(true); + static final NaturalOrderNullComparator NULLS_LAST = new NaturalOrderNullComparator(false); + + private final boolean nullFirst; + + NaturalOrderNullComparator(boolean nullFirst) { + this.nullFirst = nullFirst; + } + + @Override + public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} b2) { + return ${WrapperType}.compare(${Var}1, b2); + } + + @Override + public int compare(${WrapperType} ${Var}1, ${WrapperType} b2) { + if (${Var}1 == null) { + return (b2 == null) ? 0 : (nullFirst ? -1 : 1); + } else if (b2 == null) { + return nullFirst ? 1 : -1; + } else { + return ${Var}1.compareTo(b2); + } + } + + @Override + public @NotNull ${Type}Comparator nullsFirst() { + return NULLS_FIRST; + } + + @Override + public @NotNull ${Type}Comparator nullsLast() { + return NULLS_LAST; + } + + @Override + public @NotNull ${Type}Comparator reversed() { + return nullFirst ? ReverseOrderNullComparator.NULLS_LAST : ReverseOrderNullComparator.NULLS_FIRST; + } + + @Serial + private Object readResolve() { + return nullFirst ? NULLS_FIRST : NULLS_LAST; + } + } + + static final class ReverseOrderNullComparator implements ${Type}Comparator, Serializable { + @Serial + private static final long serialVersionUID = 0L; + + static final ReverseOrderNullComparator NULLS_FIRST = new ReverseOrderNullComparator(true); + static final ReverseOrderNullComparator NULLS_LAST = new ReverseOrderNullComparator(false); + + private final boolean nullFirst; + + ReverseOrderNullComparator(boolean nullFirst) { + this.nullFirst = nullFirst; + } + + @Override + public int compare(${PrimitiveType} ${Var}1, ${PrimitiveType} ${Var}2) { + return ${WrapperType}.compare(${Var}2, ${Var}1); + } + + @Override + public int compare(${WrapperType} ${Var}1, ${WrapperType} ${Var}2) { + if (${Var}1 == null) { + return (${Var}2 == null) ? 0 : (nullFirst ? -1 : 1); + } else if (${Var}2 == null) { + return nullFirst ? 1 : -1; + } else { + return ${Var}2.compareTo(${Var}1); + } + } + + @Override + public @NotNull ${Type}Comparator nullsFirst() { + return NULLS_FIRST; + } + + @Override + public @NotNull ${Type}Comparator nullsLast() { + return NULLS_LAST; + } + + @Override + public @NotNull ${Type}Comparator reversed() { + return nullFirst ? NaturalOrderNullComparator.NULLS_LAST : NaturalOrderNullComparator.NULLS_FIRST; + } + + @Serial + private Object readResolve() { + return nullFirst ? NULLS_FIRST : NULLS_LAST; + } + } +} diff --git a/kala-collection-primitive/build.gradle.kts b/kala-collection-primitive/build.gradle.kts index 2086d820..587d5981 100644 --- a/kala-collection-primitive/build.gradle.kts +++ b/kala-collection-primitive/build.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + apply { plugin(GeneratePlugin::class) } diff --git a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/AbstractImmutablePrimitiveSet.java.ftl b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/AbstractImmutablePrimitiveSet.java.ftl index eb23b801..a123d87a 100644 --- a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/AbstractImmutablePrimitiveSet.java.ftl +++ b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/AbstractImmutablePrimitiveSet.java.ftl @@ -1,50 +1,50 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.immutable.primitive; - -import kala.collection.primitive.*; -import kala.collection.base.primitive.${Type}Traversable; -import kala.collection.factory.primitive.${Type}CollectionFactory; -import org.jetbrains.annotations.NotNull; - -public abstract class AbstractImmutable${Type}Set extends Abstract${Type}Set implements Immutable${Type}Set { - static T added( - @NotNull Immutable${Type}Set set, - ${PrimitiveType} value, - @NotNull ${Type}CollectionFactory factory - ) { - Builder builder = factory.newBuilder(); - factory.sizeHint(builder, set, 1); - factory.addAllToBuilder(builder, set); - factory.addToBuilder(builder, value); - return factory.build(builder); - } - - static T addedAll( - @NotNull Immutable${Type}Set set, - @NotNull ${Type}Traversable values, - @NotNull ${Type}CollectionFactory factory - ) { - Builder builder = factory.newBuilder(); - - factory.sizeHint(builder, set); - factory.addAllToBuilder(builder, set); - factory.sizeHint(builder, values); - factory.addAllToBuilder(builder, values); - - return factory.build(builder); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.immutable.primitive; + +import kala.collection.primitive.*; +import kala.collection.base.primitive.${Type}Traversable; +import kala.collection.factory.primitive.${Type}CollectionFactory; +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractImmutable${Type}Set extends Abstract${Type}Set implements Immutable${Type}Set { + static T added( + @NotNull Immutable${Type}Set set, + ${PrimitiveType} value, + @NotNull ${Type}CollectionFactory factory + ) { + Builder builder = factory.newBuilder(); + factory.sizeHint(builder, set, 1); + factory.addAllToBuilder(builder, set); + factory.addToBuilder(builder, value); + return factory.build(builder); + } + + static T addedAll( + @NotNull Immutable${Type}Set set, + @NotNull ${Type}Traversable values, + @NotNull ${Type}CollectionFactory factory + ) { + Builder builder = factory.newBuilder(); + + factory.sizeHint(builder, set); + factory.addAllToBuilder(builder, set); + factory.sizeHint(builder, values); + factory.addAllToBuilder(builder, values); + + return factory.build(builder); + } +} diff --git a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutablePrimitiveSet.java.ftl b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutablePrimitiveSet.java.ftl index ff77fdc8..8cb9285a 100644 --- a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutablePrimitiveSet.java.ftl +++ b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutablePrimitiveSet.java.ftl @@ -1,184 +1,184 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.immutable.primitive; - -import kala.collection.base.primitive.*; -import kala.collection.primitive.*; -import kala.collection.factory.primitive.${Type}CollectionFactory; -import kala.function.*; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.*; -import java.util.function.*; - -public interface Immutable${Type}Set extends ImmutablePrimitiveSet<${WrapperType}>, ${Type}Set, Immutable${Type}Collection { - - //region Static Factories - - static ${Type}CollectionFactory factory() { -<#if Type == "Boolean" || Type == "Byte"> - return ${Type}CollectionFactory.narrow(DefaultImmutable${Type}Set.factory()); -<#else> - return ${Type}CollectionFactory.narrow(ImmutableSorted${Type}ArraySet.factory()); - - } - - static @NotNull Immutable${Type}Set empty() { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.empty(); -<#else> - return ImmutableSorted${Type}ArraySet.empty(); - - } - - static @NotNull Immutable${Type}Set of() { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(); -<#else> - return ImmutableSorted${Type}ArraySet.of(); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType} value1) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(value1); -<#else> - return ImmutableSorted${Type}ArraySet.of(value1); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(value1, value2); -<#else> - return ImmutableSorted${Type}ArraySet.of(value1, value2); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(value1, value2, value3); -<#else> - return ImmutableSorted${Type}ArraySet.of(value1, value2, value3); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(value1, value2, value3, value4); -<#else> - return ImmutableSorted${Type}ArraySet.of(value1, value2, value3, value4); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4, ${PrimitiveType} value5) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(value1, value2, value3, value4, value5); -<#else> - return ImmutableSorted${Type}ArraySet.of(value1, value2, value3, value4, value5); - - } - - static @NotNull Immutable${Type}Set of(${PrimitiveType}... values) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.of(values); -<#else> - return ImmutableSorted${Type}ArraySet.of(values); - - } - - static @NotNull Immutable${Type}Set from(${PrimitiveType} @NotNull [] values) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.from(values); -<#else> - return ImmutableSorted${Type}ArraySet.from(values); - - } - - static @NotNull Immutable${Type}Set from(@NotNull ${Type}Traversable values) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.from(values); -<#else> - return ImmutableSorted${Type}ArraySet.from(values); - - } - - static @NotNull Immutable${Type}Set from(@NotNull ${Type}Iterator it) { -<#if Type == "Boolean" || Type == "Byte"> - return DefaultImmutable${Type}Set.from(it); -<#else> - return ImmutableSorted${Type}ArraySet.from(it); - - } - - //endregion - - @Override - default @NotNull String className() { - return "Immutable${Type}Set"; - } - - @Override - default @NotNull ${Type}CollectionFactory iterableFactory() { - return factory(); - } - - default @NotNull Immutable${Type}Set added(${PrimitiveType} value) { - if (contains(value)) { - return this; - } - /* - if (this instanceof SortedSet) { - @SuppressWarnings("unchecked") - CollectionFactory factory = - (CollectionFactory) - ((SortedSet) this).iterableFactory(((SortedSet) this).comparator()); - - return AbstractImmutable${Type}Set.added(this, value, factory); - } - */ - return AbstractImmutable${Type}Set.added(this, value, iterableFactory()); - } - - default @NotNull Immutable${Type}Set addedAll(@NotNull ${Type}Traversable values) { - /* - if (this instanceof SortedSet) { - @SuppressWarnings("unchecked") - CollectionFactory factory = - (CollectionFactory) - ((SortedSet) this).iterableFactory(((SortedSet) this).comparator()); - - return AbstractImmutable${Type}Set.addedAll(this, values, factory); - } - */ - return AbstractImmutable${Type}Set.addedAll(this, values, iterableFactory()); - } - - default @NotNull Immutable${Type}Set addedAll(${PrimitiveType} @NotNull [] values) { - return addedAll(${Type}ArraySeq.wrap(values)); - } - - @Override - default @NotNull Immutable${Type}Set filter(@NotNull ${Type}Predicate predicate) { - return AbstractImmutable${Type}Collection.filter(this, predicate, factory()); - } - - @Override - default @NotNull Immutable${Type}Set filterNot(@NotNull ${Type}Predicate predicate) { - return AbstractImmutable${Type}Collection.filterNot(this, predicate, factory()); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.immutable.primitive; + +import kala.collection.base.primitive.*; +import kala.collection.primitive.*; +import kala.collection.factory.primitive.${Type}CollectionFactory; +import kala.function.*; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.*; + +public interface Immutable${Type}Set extends ImmutablePrimitiveSet<${WrapperType}>, ${Type}Set, Immutable${Type}Collection { + + //region Static Factories + + static ${Type}CollectionFactory factory() { +<#if Type == "Boolean" || Type == "Byte"> + return ${Type}CollectionFactory.narrow(DefaultImmutable${Type}Set.factory()); +<#else> + return ${Type}CollectionFactory.narrow(ImmutableSorted${Type}ArraySet.factory()); + + } + + static @NotNull Immutable${Type}Set empty() { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.empty(); +<#else> + return ImmutableSorted${Type}ArraySet.empty(); + + } + + static @NotNull Immutable${Type}Set of() { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(); +<#else> + return ImmutableSorted${Type}ArraySet.of(); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType} value1) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(value1); +<#else> + return ImmutableSorted${Type}ArraySet.of(value1); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(value1, value2); +<#else> + return ImmutableSorted${Type}ArraySet.of(value1, value2); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(value1, value2, value3); +<#else> + return ImmutableSorted${Type}ArraySet.of(value1, value2, value3); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(value1, value2, value3, value4); +<#else> + return ImmutableSorted${Type}ArraySet.of(value1, value2, value3, value4); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4, ${PrimitiveType} value5) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(value1, value2, value3, value4, value5); +<#else> + return ImmutableSorted${Type}ArraySet.of(value1, value2, value3, value4, value5); + + } + + static @NotNull Immutable${Type}Set of(${PrimitiveType}... values) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.of(values); +<#else> + return ImmutableSorted${Type}ArraySet.of(values); + + } + + static @NotNull Immutable${Type}Set from(${PrimitiveType} @NotNull [] values) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.from(values); +<#else> + return ImmutableSorted${Type}ArraySet.from(values); + + } + + static @NotNull Immutable${Type}Set from(@NotNull ${Type}Traversable values) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.from(values); +<#else> + return ImmutableSorted${Type}ArraySet.from(values); + + } + + static @NotNull Immutable${Type}Set from(@NotNull ${Type}Iterator it) { +<#if Type == "Boolean" || Type == "Byte"> + return DefaultImmutable${Type}Set.from(it); +<#else> + return ImmutableSorted${Type}ArraySet.from(it); + + } + + //endregion + + @Override + default @NotNull String className() { + return "Immutable${Type}Set"; + } + + @Override + default @NotNull ${Type}CollectionFactory iterableFactory() { + return factory(); + } + + default @NotNull Immutable${Type}Set added(${PrimitiveType} value) { + if (contains(value)) { + return this; + } + /* + if (this instanceof SortedSet) { + @SuppressWarnings("unchecked") + CollectionFactory factory = + (CollectionFactory) + ((SortedSet) this).iterableFactory(((SortedSet) this).comparator()); + + return AbstractImmutable${Type}Set.added(this, value, factory); + } + */ + return AbstractImmutable${Type}Set.added(this, value, iterableFactory()); + } + + default @NotNull Immutable${Type}Set addedAll(@NotNull ${Type}Traversable values) { + /* + if (this instanceof SortedSet) { + @SuppressWarnings("unchecked") + CollectionFactory factory = + (CollectionFactory) + ((SortedSet) this).iterableFactory(((SortedSet) this).comparator()); + + return AbstractImmutable${Type}Set.addedAll(this, values, factory); + } + */ + return AbstractImmutable${Type}Set.addedAll(this, values, iterableFactory()); + } + + default @NotNull Immutable${Type}Set addedAll(${PrimitiveType} @NotNull [] values) { + return addedAll(${Type}ArraySeq.wrap(values)); + } + + @Override + default @NotNull Immutable${Type}Set filter(@NotNull ${Type}Predicate predicate) { + return AbstractImmutable${Type}Collection.filter(this, predicate, factory()); + } + + @Override + default @NotNull Immutable${Type}Set filterNot(@NotNull ${Type}Predicate predicate) { + return AbstractImmutable${Type}Collection.filterNot(this, predicate, factory()); + } +} diff --git a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutableSortedPrimitiveArraySet.java.ftl b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutableSortedPrimitiveArraySet.java.ftl index 20467e2b..16cd2a67 100644 --- a/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutableSortedPrimitiveArraySet.java.ftl +++ b/kala-collection-primitive/src/main/template/kala/collection/immutable/primitive/ImmutableSortedPrimitiveArraySet.java.ftl @@ -1,294 +1,294 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.immutable.primitive; - -import kala.collection.base.primitive.*; -import kala.collection.factory.primitive.${Type}CollectionFactory; -import kala.collection.mutable.primitive.*; -import kala.function.*; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.Serializable; -import java.util.*; -import java.util.function.*; - -public final class ImmutableSorted${Type}ArraySet extends AbstractImmutable${Type}Set implements Serializable { - private static final long serialVersionUID = 0L; - - private static final ImmutableSorted${Type}ArraySet.Factory FACTORY = - new ImmutableSorted${Type}ArraySet.Factory(); - private static final ImmutableSorted${Type}ArraySet EMPTY = new ImmutableSorted${Type}ArraySet(${Type}Arrays.EMPTY); - - final ${PrimitiveType}[] elements; - - ImmutableSorted${Type}ArraySet(${PrimitiveType}[] elements) { - this.elements = elements; - } - - //region Static Factories - - public static @NotNull ${Type}CollectionFactory factory() { - return FACTORY; - } - - @Contract - public static @NotNull ImmutableSorted${Type}ArraySet empty() { - return EMPTY; - } - - public static @NotNull ImmutableSorted${Type}ArraySet of() { - return empty(); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1) { - return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1}); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2) { - int c = ${WrapperType}.compare(value1, value2); - if (c < 0) { - return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1, value2}); - } - if (c > 0) { - return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value2, value1}); - } - return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1}); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3) { - Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); - s.add(value1); - s.add(value2); - s.add(value3); - return new ImmutableSorted${Type}ArraySet(s.toArray()); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4) { - Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); - s.add(value1); - s.add(value2); - s.add(value3); - s.add(value4); - return new ImmutableSorted${Type}ArraySet(s.toArray()); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of( - ${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4, ${PrimitiveType} value5 - ) { - Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); - s.add(value1); - s.add(value2); - s.add(value3); - s.add(value4); - s.add(value5); - return new ImmutableSorted${Type}ArraySet(s.toArray()); - } - - public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType}... values) { - return from(values); - } - - public static @NotNull ImmutableSorted${Type}ArraySet from(${PrimitiveType} @NotNull [] values) { - if (values.length == 0) { // implicit null check of values - return empty(); - } - Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); - s.addAll(values); - return new ImmutableSorted${Type}ArraySet(s.toArray()); - } - - public static @NotNull ImmutableSorted${Type}ArraySet from(@NotNull ${Type}Traversable values) { - return from(values.iterator()); - } - - public static @NotNull ImmutableSorted${Type}ArraySet from(@NotNull ${Type}Iterator it) { - if (!it.hasNext()) { // implicit null check of it - return empty(); - } - - Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); - while (it.hasNext()) { - s.add(it.next${Type}()); - } - return new ImmutableSorted${Type}ArraySet(s.toArray()); - } - - //endregion - - @Override - public @NotNull String className() { - return "ImmutableSorted${Type}ArraySet"; - } - - @Override - public @NotNull ${Type}CollectionFactory iterableFactory() { - return FACTORY; - } - - @Override - public @NotNull ${Type}Iterator iterator() { - return ${Type}Arrays.iterator(elements); - } - - @Override - public int size() { - return elements.length; - } - - @Override - public int knownSize() { - return size(); - } - - @Override - public @NotNull ImmutableSorted${Type}ArraySet added(${PrimitiveType} value) { - final int size = elements.length; - - if (size == 0) { - return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value}); - } - - int idx = Arrays.binarySearch(elements, value); - if (idx >= 0) { - return this; - } - idx = -idx - 1; - - ${PrimitiveType}[] newElements = new ${PrimitiveType}[size + 1]; - - if (idx == 0) { - System.arraycopy(elements, 0, newElements, 1, size); - newElements[0] = value; - return new ImmutableSorted${Type}ArraySet(newElements); - } else if (idx == size) { - System.arraycopy(elements, 0, newElements, 0, size); - newElements[size] = value; - return new ImmutableSorted${Type}ArraySet(newElements); - } else { - System.arraycopy(elements, 0, newElements, 0, idx); - System.arraycopy(elements, idx, newElements, idx + 1, size - idx); - newElements[idx] = value; - return new ImmutableSorted${Type}ArraySet(newElements); - } - } - - @Override - public @NotNull ImmutableSorted${Type}ArraySet addedAll(@NotNull ${Type}Traversable values) { - final ${Type}Iterator it = values.iterator(); - if (!it.hasNext()) { - return this; - } - - final ${PrimitiveType}[] elements = this.elements; - - if (elements.length == 0) { - return from(values); - } - - Mutable${Type}TreeSet builder = new Mutable${Type}TreeSet(); - - builder.addAll(elements); - builder.addAll(values); - if (builder.size() == elements.length) { - return this; - } - - return new ImmutableSorted${Type}ArraySet(builder.toArray()); - } - - @Override - public @NotNull ImmutableSorted${Type}ArraySet addedAll(${PrimitiveType} @NotNull [] values) { - final int arrayLength = values.length; - if (arrayLength == 0) { - return this; - } - if (arrayLength == 1) { - return added(values[0]); - } - - final int size = elements.length; - - if (size == 0) { - return from(values); - } - - Mutable${Type}TreeSet builder = new Mutable${Type}TreeSet(); - builder.addAll(elements); - builder.addAll(values); - return new ImmutableSorted${Type}ArraySet(builder.toArray()); - } - - // @Override - public ${PrimitiveType} getFirst() { - if (elements.length == 0) { - throw new NoSuchElementException(); - } - return elements[0]; - } - - // @Override - public ${PrimitiveType} getLast() { - final int size = elements.length; - if (size == 0) { - throw new NoSuchElementException(); - } - return elements[size - 1]; - } - - @Override - public @NotNull A joinTo( - @NotNull A buffer, - CharSequence separator, CharSequence prefix, CharSequence postfix - ) { - return ${Type}Arrays.joinTo(elements, buffer, separator, prefix, postfix); - } - - @Override - public void forEach(@NotNull ${Type}Consumer action) { - for (${PrimitiveType} e : elements) { - action.accept(e); - } - } - - private static final class Factory implements ${Type}CollectionFactory { - @Override - public ImmutableSorted${Type}ArraySet empty() { - return ImmutableSorted${Type}ArraySet.empty(); - } - - @Override - public Mutable${Type}TreeSet newBuilder() { - return new Mutable${Type}TreeSet(); - } - - @Override - public ImmutableSorted${Type}ArraySet build(@NotNull Mutable${Type}TreeSet builder) { - return builder.isEmpty() ? ImmutableSorted${Type}ArraySet.empty() : new ImmutableSorted${Type}ArraySet(builder.toArray()); - } - - @Override - public void addToBuilder(@NotNull Mutable${Type}TreeSet builder, ${PrimitiveType} value) { - builder.add(value); - } - - @Override - public Mutable${Type}TreeSet mergeBuilder(@NotNull Mutable${Type}TreeSet builder1, @NotNull Mutable${Type}TreeSet builder2) { - builder1.addAll(builder2); - return builder1; - } - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.immutable.primitive; + +import kala.collection.base.primitive.*; +import kala.collection.factory.primitive.${Type}CollectionFactory; +import kala.collection.mutable.primitive.*; +import kala.function.*; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.*; +import java.util.function.*; + +public final class ImmutableSorted${Type}ArraySet extends AbstractImmutable${Type}Set implements Serializable { + private static final long serialVersionUID = 0L; + + private static final ImmutableSorted${Type}ArraySet.Factory FACTORY = + new ImmutableSorted${Type}ArraySet.Factory(); + private static final ImmutableSorted${Type}ArraySet EMPTY = new ImmutableSorted${Type}ArraySet(${Type}Arrays.EMPTY); + + final ${PrimitiveType}[] elements; + + ImmutableSorted${Type}ArraySet(${PrimitiveType}[] elements) { + this.elements = elements; + } + + //region Static Factories + + public static @NotNull ${Type}CollectionFactory factory() { + return FACTORY; + } + + @Contract + public static @NotNull ImmutableSorted${Type}ArraySet empty() { + return EMPTY; + } + + public static @NotNull ImmutableSorted${Type}ArraySet of() { + return empty(); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1) { + return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1}); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2) { + int c = ${WrapperType}.compare(value1, value2); + if (c < 0) { + return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1, value2}); + } + if (c > 0) { + return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value2, value1}); + } + return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value1}); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3) { + Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); + s.add(value1); + s.add(value2); + s.add(value3); + return new ImmutableSorted${Type}ArraySet(s.toArray()); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4) { + Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); + s.add(value1); + s.add(value2); + s.add(value3); + s.add(value4); + return new ImmutableSorted${Type}ArraySet(s.toArray()); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of( + ${PrimitiveType} value1, ${PrimitiveType} value2, ${PrimitiveType} value3, ${PrimitiveType} value4, ${PrimitiveType} value5 + ) { + Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); + s.add(value1); + s.add(value2); + s.add(value3); + s.add(value4); + s.add(value5); + return new ImmutableSorted${Type}ArraySet(s.toArray()); + } + + public static @NotNull ImmutableSorted${Type}ArraySet of(${PrimitiveType}... values) { + return from(values); + } + + public static @NotNull ImmutableSorted${Type}ArraySet from(${PrimitiveType} @NotNull [] values) { + if (values.length == 0) { // implicit null check of values + return empty(); + } + Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); + s.addAll(values); + return new ImmutableSorted${Type}ArraySet(s.toArray()); + } + + public static @NotNull ImmutableSorted${Type}ArraySet from(@NotNull ${Type}Traversable values) { + return from(values.iterator()); + } + + public static @NotNull ImmutableSorted${Type}ArraySet from(@NotNull ${Type}Iterator it) { + if (!it.hasNext()) { // implicit null check of it + return empty(); + } + + Mutable${Type}TreeSet s = new Mutable${Type}TreeSet(); + while (it.hasNext()) { + s.add(it.next${Type}()); + } + return new ImmutableSorted${Type}ArraySet(s.toArray()); + } + + //endregion + + @Override + public @NotNull String className() { + return "ImmutableSorted${Type}ArraySet"; + } + + @Override + public @NotNull ${Type}CollectionFactory iterableFactory() { + return FACTORY; + } + + @Override + public @NotNull ${Type}Iterator iterator() { + return ${Type}Arrays.iterator(elements); + } + + @Override + public int size() { + return elements.length; + } + + @Override + public int knownSize() { + return size(); + } + + @Override + public @NotNull ImmutableSorted${Type}ArraySet added(${PrimitiveType} value) { + final int size = elements.length; + + if (size == 0) { + return new ImmutableSorted${Type}ArraySet(new ${PrimitiveType}[]{value}); + } + + int idx = Arrays.binarySearch(elements, value); + if (idx >= 0) { + return this; + } + idx = -idx - 1; + + ${PrimitiveType}[] newElements = new ${PrimitiveType}[size + 1]; + + if (idx == 0) { + System.arraycopy(elements, 0, newElements, 1, size); + newElements[0] = value; + return new ImmutableSorted${Type}ArraySet(newElements); + } else if (idx == size) { + System.arraycopy(elements, 0, newElements, 0, size); + newElements[size] = value; + return new ImmutableSorted${Type}ArraySet(newElements); + } else { + System.arraycopy(elements, 0, newElements, 0, idx); + System.arraycopy(elements, idx, newElements, idx + 1, size - idx); + newElements[idx] = value; + return new ImmutableSorted${Type}ArraySet(newElements); + } + } + + @Override + public @NotNull ImmutableSorted${Type}ArraySet addedAll(@NotNull ${Type}Traversable values) { + final ${Type}Iterator it = values.iterator(); + if (!it.hasNext()) { + return this; + } + + final ${PrimitiveType}[] elements = this.elements; + + if (elements.length == 0) { + return from(values); + } + + Mutable${Type}TreeSet builder = new Mutable${Type}TreeSet(); + + builder.addAll(elements); + builder.addAll(values); + if (builder.size() == elements.length) { + return this; + } + + return new ImmutableSorted${Type}ArraySet(builder.toArray()); + } + + @Override + public @NotNull ImmutableSorted${Type}ArraySet addedAll(${PrimitiveType} @NotNull [] values) { + final int arrayLength = values.length; + if (arrayLength == 0) { + return this; + } + if (arrayLength == 1) { + return added(values[0]); + } + + final int size = elements.length; + + if (size == 0) { + return from(values); + } + + Mutable${Type}TreeSet builder = new Mutable${Type}TreeSet(); + builder.addAll(elements); + builder.addAll(values); + return new ImmutableSorted${Type}ArraySet(builder.toArray()); + } + + // @Override + public ${PrimitiveType} getFirst() { + if (elements.length == 0) { + throw new NoSuchElementException(); + } + return elements[0]; + } + + // @Override + public ${PrimitiveType} getLast() { + final int size = elements.length; + if (size == 0) { + throw new NoSuchElementException(); + } + return elements[size - 1]; + } + + @Override + public @NotNull A joinTo( + @NotNull A buffer, + CharSequence separator, CharSequence prefix, CharSequence postfix + ) { + return ${Type}Arrays.joinTo(elements, buffer, separator, prefix, postfix); + } + + @Override + public void forEach(@NotNull ${Type}Consumer action) { + for (${PrimitiveType} e : elements) { + action.accept(e); + } + } + + private static final class Factory implements ${Type}CollectionFactory { + @Override + public ImmutableSorted${Type}ArraySet empty() { + return ImmutableSorted${Type}ArraySet.empty(); + } + + @Override + public Mutable${Type}TreeSet newBuilder() { + return new Mutable${Type}TreeSet(); + } + + @Override + public ImmutableSorted${Type}ArraySet build(@NotNull Mutable${Type}TreeSet builder) { + return builder.isEmpty() ? ImmutableSorted${Type}ArraySet.empty() : new ImmutableSorted${Type}ArraySet(builder.toArray()); + } + + @Override + public void addToBuilder(@NotNull Mutable${Type}TreeSet builder, ${PrimitiveType} value) { + builder.add(value); + } + + @Override + public Mutable${Type}TreeSet mergeBuilder(@NotNull Mutable${Type}TreeSet builder1, @NotNull Mutable${Type}TreeSet builder2) { + builder1.addAll(builder2); + return builder1; + } + } +} diff --git a/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetLike.java.ftl b/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetLike.java.ftl index 60bbc99f..5bd9cd8e 100644 --- a/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetLike.java.ftl +++ b/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetLike.java.ftl @@ -1,40 +1,40 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.primitive; - -import org.jetbrains.annotations.NotNull; - -import kala.function.*; -<#if IsSpecialized> - -import java.util.function.*; - - -public interface ${Type}SetLike extends PrimitiveSetLike<${WrapperType}>, ${Type}CollectionLike { - @Override - default @NotNull String className() { - return "${Type}SetLike"; - } - - @Override - @NotNull ${Type}SetView view(); - - @Override - @NotNull ${Type}SetLike filter(@NotNull ${Type}Predicate predicate); - - @Override - @NotNull ${Type}SetLike filterNot(@NotNull ${Type}Predicate predicate); -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.primitive; + +import org.jetbrains.annotations.NotNull; + +import kala.function.*; +<#if IsSpecialized> + +import java.util.function.*; + + +public interface ${Type}SetLike extends PrimitiveSetLike<${WrapperType}>, ${Type}CollectionLike { + @Override + default @NotNull String className() { + return "${Type}SetLike"; + } + + @Override + @NotNull ${Type}SetView view(); + + @Override + @NotNull ${Type}SetLike filter(@NotNull ${Type}Predicate predicate); + + @Override + @NotNull ${Type}SetLike filterNot(@NotNull ${Type}Predicate predicate); +} diff --git a/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetView.java.ftl b/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetView.java.ftl index b9120307..97c41d5b 100644 --- a/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetView.java.ftl +++ b/kala-collection-primitive/src/main/template/kala/collection/primitive/PrimitiveSetView.java.ftl @@ -1,47 +1,47 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.primitive; - -import kala.collection.primitive.internal.view.${Type}SetViews; -import kala.function.*; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; -import java.util.function.*; - -public interface ${Type}SetView extends ${Type}SetLike, ${Type}CollectionView, PrimitiveSetView<${WrapperType}> { - - @Override - default @NotNull String className() { - return "${Type}SetView"; - } - - @Override - default @NotNull ${Type}SetView view() { - return this; - } - - @Override - default @NotNull ${Type}SetView filter(@NotNull ${Type}Predicate predicate) { - Objects.requireNonNull(predicate); - return new ${Type}SetViews.Filter(this, predicate); - } - - @Override - default @NotNull ${Type}SetView filterNot(@NotNull ${Type}Predicate predicate) { - return filter(predicate.negate()); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.primitive; + +import kala.collection.primitive.internal.view.${Type}SetViews; +import kala.function.*; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.function.*; + +public interface ${Type}SetView extends ${Type}SetLike, ${Type}CollectionView, PrimitiveSetView<${WrapperType}> { + + @Override + default @NotNull String className() { + return "${Type}SetView"; + } + + @Override + default @NotNull ${Type}SetView view() { + return this; + } + + @Override + default @NotNull ${Type}SetView filter(@NotNull ${Type}Predicate predicate) { + Objects.requireNonNull(predicate); + return new ${Type}SetViews.Filter(this, predicate); + } + + @Override + default @NotNull ${Type}SetView filterNot(@NotNull ${Type}Predicate predicate) { + return filter(predicate.negate()); + } +} diff --git a/kala-collection/build.gradle.kts b/kala-collection/build.gradle.kts index 66129056..40c9cfb3 100644 --- a/kala-collection/build.gradle.kts +++ b/kala-collection/build.gradle.kts @@ -1,3 +1,19 @@ -dependencies { - api(project(":kala-base")) -} +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + api(project(":kala-base")) +} diff --git a/kala-collection/src/main/java/kala/collection/AbstractCollection.java b/kala-collection/src/main/java/kala/collection/AbstractCollection.java index 9a30a5c5..ec07459e 100644 --- a/kala-collection/src/main/java/kala/collection/AbstractCollection.java +++ b/kala-collection/src/main/java/kala/collection/AbstractCollection.java @@ -1,45 +1,45 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -import kala.annotations.Covariant; -import kala.collection.base.Iterators; - -public abstract class AbstractCollection<@Covariant E> implements Collection { - - @Override - public int hashCode() { - return Iterators.hash(iterator()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof AnyCollection) - || !(canEqual(obj)) - || !(((AnyCollection) obj).canEqual(this))) { - return false; - } - return sameElements(((Collection) obj)); - } - - @Override - public String toString() { - return joinToString(", ", className() + "[", "]"); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +import kala.annotations.Covariant; +import kala.collection.base.Iterators; + +public abstract class AbstractCollection<@Covariant E> implements Collection { + + @Override + public int hashCode() { + return Iterators.hash(iterator()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof AnyCollection) + || !(canEqual(obj)) + || !(((AnyCollection) obj).canEqual(this))) { + return false; + } + return sameElements(((Collection) obj)); + } + + @Override + public String toString() { + return joinToString(", ", className() + "[", "]"); + } +} diff --git a/kala-collection/src/main/java/kala/collection/AbstractMap.java b/kala-collection/src/main/java/kala/collection/AbstractMap.java index 607850b5..e5796989 100644 --- a/kala-collection/src/main/java/kala/collection/AbstractMap.java +++ b/kala-collection/src/main/java/kala/collection/AbstractMap.java @@ -1,50 +1,50 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -import org.jetbrains.annotations.Debug; - -@Debug.Renderer(hasChildren = "isNotEmpty()", childrenArray = "toArray()") -public abstract class AbstractMap implements Map { - - @Override - public int hashCode() { - return Map.hashCode(this); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!(obj instanceof AnyMap other)) { - return false; - } - - return this.canEqual(other) && other.canEqual(this) && Map.equals(this, other); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append(className()); - builder.append('{'); - joinTo(builder); - builder.append('}'); - return builder.toString(); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +import org.jetbrains.annotations.Debug; + +@Debug.Renderer(hasChildren = "isNotEmpty()", childrenArray = "toArray()") +public abstract class AbstractMap implements Map { + + @Override + public int hashCode() { + return Map.hashCode(this); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof AnyMap other)) { + return false; + } + + return this.canEqual(other) && other.canEqual(this) && Map.equals(this, other); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(className()); + builder.append('{'); + joinTo(builder); + builder.append('}'); + return builder.toString(); + } +} diff --git a/kala-collection/src/main/java/kala/collection/SeqLike.java b/kala-collection/src/main/java/kala/collection/SeqLike.java index c8dd1e0b..553485ae 100644 --- a/kala-collection/src/main/java/kala/collection/SeqLike.java +++ b/kala-collection/src/main/java/kala/collection/SeqLike.java @@ -1,328 +1,328 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -import kala.Conditions; -import kala.annotations.DelegateBy; -import kala.collection.base.Growable; -import kala.collection.base.OrderedTraversable; -import kala.collection.internal.SeqIterators; -import kala.collection.internal.view.SeqViews; -import kala.collection.mutable.MutableSeq; -import kala.comparator.Comparators; -import kala.control.Option; -import kala.function.IndexedBiConsumer; -import kala.function.IndexedFunction; -import kala.index.Index; -import kala.index.Indexes; -import kala.tuple.Tuple2; -import org.intellij.lang.annotations.Flow; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -public interface SeqLike extends CollectionLike, AnySeqLike, OrderedTraversable { - @Contract(value = "_ -> param1", pure = true) - @SuppressWarnings("unchecked") - static SeqLike narrow(SeqLike view) { - return (SeqLike) view; - } - - @Override - default @NotNull String className() { - return "SeqLike"; - } - - @DelegateBy("seqIterator(int)") - default @NotNull SeqIterator seqIterator() { - return seqIterator(0); - } - - default @NotNull SeqIterator seqIterator(int index) { - Conditions.checkPositionIndex(index, size()); - return new SeqIterators.DefaultSeqIterator<>(this, index); - } - - @Override - @NotNull SeqView view(); - - default @NotNull SeqView sliceView(@Index int beginIndex, @Index int endIndex) { - return view().slice(beginIndex, endIndex); - } - - //region Positional Access Operations - - @Override - default E elementAt(int index) { - if (index < 0) { - throw new IndexOutOfBoundsException(index); - } - return get(index); - } - - @Contract(pure = true) - @Flow(sourceIsContainer = true) - default E get(@Index int index) { - Iterator it = iterator(index); - if (!it.hasNext()) throw Indexes.outOfBounds(index); - - return it.next(); - } - - @Contract(pure = true) - @DelegateBy("get(int)") - default @Nullable E getOrNull(@Index int index) { - return isDefinedAt(index) ? get(index) : null; - } - - @Contract(pure = true) - @Flow(sourceIsContainer = true, targetIsContainer = true) - @DelegateBy("get(int)") - default @NotNull Option getOption(@Index int index) { - return isDefinedAt(index) ? Option.some(get(index)) : Option.none(); - } - - //endregion - - @Contract(pure = true) - @DelegateBy("binarySearch(int, int, E)") - default int binarySearch(E value) { - return binarySearch(0, ~0, value); - } - - @Contract(pure = true) - @DelegateBy("binarySearch(int, int, E, Comparator)") - default int binarySearch(E value, Comparator comparator) { - return binarySearch(0, ~0, value, comparator); - } - - @Contract(pure = true) - @DelegateBy("binarySearch(int, int, E, Comparator)") - default int binarySearch(@Index int beginIndex, @Index int endIndex, E value) { - return binarySearch(beginIndex, endIndex, value, Comparators.naturalOrder()); - } - - @Contract(pure = true) - default int binarySearch(@Index int beginIndex, @Index int endIndex, E value, Comparator comparator) { - if (comparator == null) { - comparator = Comparators.naturalOrder(); - } - - final int size = size(); - - int low = Indexes.checkBeginIndex(beginIndex, size); - int high = Indexes.checkEndIndex(low, endIndex, size) - 1; - - while (low <= high) { - final int mid = (low + high) >>> 1; - final E midVal = get(mid); - final int cmp = comparator.compare(midVal, value); - if (cmp < 0) { - low = mid + 1; - } else if (cmp > 0) { - high = mid - 1; - } else { - return mid; - } - } - return -(low + 1); - } - - @Contract(pure = true) - @NotNull SeqLike slice(@Index int beginIndex, @Index int endIndex); - - @Contract(pure = true) - @NotNull SeqLike drop(int n); - - @Contract(pure = true) - @NotNull SeqLike dropLast(int n); - - @Contract(pure = true) - @NotNull SeqLike dropWhile(@NotNull Predicate predicate); - - @Contract(pure = true) - @NotNull SeqLike take(int n); - - @NotNull SeqLike takeLast(int n); - - @Contract(pure = true) - @NotNull SeqLike takeWhile(@NotNull Predicate predicate); - - @Contract(pure = true) - @NotNull SeqLike updated(@Index int index, E newValue); - - @Contract(pure = true) - @NotNull SeqLike concat(@NotNull SeqLike other); - - @Contract(pure = true) - @NotNull SeqLike concat(@NotNull List other); - - @Contract(pure = true) - @NotNull SeqLike prepended(E value); - - @Contract(pure = true) - @SuppressWarnings("unchecked") - @NotNull SeqLike prependedAll(E... values); - - @Contract(pure = true) - @NotNull SeqLike prependedAll(@NotNull Iterable values); - - @Contract(pure = true) - @NotNull SeqLike appended(E value); - - @Contract(pure = true) - @NotNull SeqLike appendedAll(@NotNull Iterable values); - - @Contract(pure = true) - @SuppressWarnings("unchecked") - @NotNull SeqLike appendedAll(E... values); - - @Contract(pure = true) - @NotNull SeqLike inserted(@Index int index, E value); - - @Contract(pure = true) - @NotNull SeqLike removedAt(@Index int index); - - @Contract(pure = true) - @NotNull SeqLike sorted(); - - @Contract(pure = true) - @NotNull SeqLike sorted(@Nullable Comparator comparator); - - @Contract(pure = true) - @NotNull SeqLike reversed(); - - @Override - @Contract(pure = true) - @NotNull SeqLike filter(@NotNull Predicate predicate); - - @Override - @Contract(pure = true) - @NotNull SeqLike filterNot(@NotNull Predicate predicate); - - @Override - @Contract(pure = true) - @NotNull SeqLike<@NotNull E> filterNotNull(); - - @Override - @Contract(pure = true) - @NotNull SeqLike<@NotNull U> filterIsInstance(@NotNull Class clazz); - - @Override - @Contract(pure = true) - @NotNull SeqLike map(@NotNull Function mapper); - - @Contract(pure = true) - @NotNull SeqLike mapIndexed(@NotNull IndexedFunction mapper); - - @Override - @Contract(pure = true) - @NotNull SeqLike<@NotNull U> mapNotNull(@NotNull Function mapper); - - @Contract(pure = true) - @NotNull SeqLike<@NotNull U> mapIndexedNotNull( - @NotNull IndexedFunction mapper); - - @Override - @Contract(pure = true) - @NotNull SeqLike mapMulti(@NotNull BiConsumer> mapper); - - @Contract(pure = true) - @NotNull SeqLike mapIndexedMulti(@NotNull IndexedBiConsumer> mapper); - - @Override - @Contract(pure = true) - @NotNull SeqLike flatMap(@NotNull Function> mapper); - - @Contract(value = "_, _ -> param1", mutates = "param1") - default > @NotNull G mapIndexedTo( - @NotNull G destination, @NotNull IndexedFunction mapper) { - int idx = 0; - for (E e : this) { - destination.plusAssign(mapper.apply(idx++, e)); - } - return destination; - } - - default @NotNull SeqView<@NotNull Tuple2> zipView(@NotNull SeqLike other) { - return new SeqViews.Zip<>(this, other); - } - - @Override - default int copyTo(@NotNull MutableSeq dest, int destPos, int limit) { - return copyTo(0, dest, destPos, limit); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyTo(int srcPos, @NotNull MutableSeq dest) { - return copyTo(srcPos, dest, 0, Integer.MAX_VALUE); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyTo(int srcPos, @NotNull MutableSeq dest, int destPos) { - return copyTo(srcPos, dest, destPos, Integer.MAX_VALUE); - } - - @Contract(mutates = "param2") - @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) - default int copyTo(int srcPos, @NotNull MutableSeq dest, int destPos, int limit) { - if (srcPos < 0) { - throw new IllegalArgumentException("srcPos(" + srcPos + ") < 0"); - } - if (destPos < 0) { - throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); - } - - if (limit <= 0) { - return 0; - } - - final int dl = dest.size(); // implicit null check of dest - if (destPos > dl) { - return 0; - } - - final int kn = this.knownSize(); - if (kn >= 0 && srcPos >= kn) { - return 0; - } - - int end = Math.min(dl - destPos, limit) + destPos; - - Iterator it; - try { - it = this.iterator(srcPos); - } catch (IndexOutOfBoundsException ignored) { - return 0; - } - - int idx = destPos; - while (it.hasNext() && idx < end) { - dest.set(idx++, it.next()); - } - return idx - destPos; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +import kala.Conditions; +import kala.annotations.DelegateBy; +import kala.collection.base.Growable; +import kala.collection.base.OrderedTraversable; +import kala.collection.internal.SeqIterators; +import kala.collection.internal.view.SeqViews; +import kala.collection.mutable.MutableSeq; +import kala.comparator.Comparators; +import kala.control.Option; +import kala.function.IndexedBiConsumer; +import kala.function.IndexedFunction; +import kala.index.Index; +import kala.index.Indexes; +import kala.tuple.Tuple2; +import org.intellij.lang.annotations.Flow; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +public interface SeqLike extends CollectionLike, AnySeqLike, OrderedTraversable { + @Contract(value = "_ -> param1", pure = true) + @SuppressWarnings("unchecked") + static SeqLike narrow(SeqLike view) { + return (SeqLike) view; + } + + @Override + default @NotNull String className() { + return "SeqLike"; + } + + @DelegateBy("seqIterator(int)") + default @NotNull SeqIterator seqIterator() { + return seqIterator(0); + } + + default @NotNull SeqIterator seqIterator(int index) { + Conditions.checkPositionIndex(index, size()); + return new SeqIterators.DefaultSeqIterator<>(this, index); + } + + @Override + @NotNull SeqView view(); + + default @NotNull SeqView sliceView(@Index int beginIndex, @Index int endIndex) { + return view().slice(beginIndex, endIndex); + } + + //region Positional Access Operations + + @Override + default E elementAt(int index) { + if (index < 0) { + throw new IndexOutOfBoundsException(index); + } + return get(index); + } + + @Contract(pure = true) + @Flow(sourceIsContainer = true) + default E get(@Index int index) { + Iterator it = iterator(index); + if (!it.hasNext()) throw Indexes.outOfBounds(index); + + return it.next(); + } + + @Contract(pure = true) + @DelegateBy("get(int)") + default @Nullable E getOrNull(@Index int index) { + return isDefinedAt(index) ? get(index) : null; + } + + @Contract(pure = true) + @Flow(sourceIsContainer = true, targetIsContainer = true) + @DelegateBy("get(int)") + default @NotNull Option getOption(@Index int index) { + return isDefinedAt(index) ? Option.some(get(index)) : Option.none(); + } + + //endregion + + @Contract(pure = true) + @DelegateBy("binarySearch(int, int, E)") + default int binarySearch(E value) { + return binarySearch(0, ~0, value); + } + + @Contract(pure = true) + @DelegateBy("binarySearch(int, int, E, Comparator)") + default int binarySearch(E value, Comparator comparator) { + return binarySearch(0, ~0, value, comparator); + } + + @Contract(pure = true) + @DelegateBy("binarySearch(int, int, E, Comparator)") + default int binarySearch(@Index int beginIndex, @Index int endIndex, E value) { + return binarySearch(beginIndex, endIndex, value, Comparators.naturalOrder()); + } + + @Contract(pure = true) + default int binarySearch(@Index int beginIndex, @Index int endIndex, E value, Comparator comparator) { + if (comparator == null) { + comparator = Comparators.naturalOrder(); + } + + final int size = size(); + + int low = Indexes.checkBeginIndex(beginIndex, size); + int high = Indexes.checkEndIndex(low, endIndex, size) - 1; + + while (low <= high) { + final int mid = (low + high) >>> 1; + final E midVal = get(mid); + final int cmp = comparator.compare(midVal, value); + if (cmp < 0) { + low = mid + 1; + } else if (cmp > 0) { + high = mid - 1; + } else { + return mid; + } + } + return -(low + 1); + } + + @Contract(pure = true) + @NotNull SeqLike slice(@Index int beginIndex, @Index int endIndex); + + @Contract(pure = true) + @NotNull SeqLike drop(int n); + + @Contract(pure = true) + @NotNull SeqLike dropLast(int n); + + @Contract(pure = true) + @NotNull SeqLike dropWhile(@NotNull Predicate predicate); + + @Contract(pure = true) + @NotNull SeqLike take(int n); + + @NotNull SeqLike takeLast(int n); + + @Contract(pure = true) + @NotNull SeqLike takeWhile(@NotNull Predicate predicate); + + @Contract(pure = true) + @NotNull SeqLike updated(@Index int index, E newValue); + + @Contract(pure = true) + @NotNull SeqLike concat(@NotNull SeqLike other); + + @Contract(pure = true) + @NotNull SeqLike concat(@NotNull List other); + + @Contract(pure = true) + @NotNull SeqLike prepended(E value); + + @Contract(pure = true) + @SuppressWarnings("unchecked") + @NotNull SeqLike prependedAll(E... values); + + @Contract(pure = true) + @NotNull SeqLike prependedAll(@NotNull Iterable values); + + @Contract(pure = true) + @NotNull SeqLike appended(E value); + + @Contract(pure = true) + @NotNull SeqLike appendedAll(@NotNull Iterable values); + + @Contract(pure = true) + @SuppressWarnings("unchecked") + @NotNull SeqLike appendedAll(E... values); + + @Contract(pure = true) + @NotNull SeqLike inserted(@Index int index, E value); + + @Contract(pure = true) + @NotNull SeqLike removedAt(@Index int index); + + @Contract(pure = true) + @NotNull SeqLike sorted(); + + @Contract(pure = true) + @NotNull SeqLike sorted(@Nullable Comparator comparator); + + @Contract(pure = true) + @NotNull SeqLike reversed(); + + @Override + @Contract(pure = true) + @NotNull SeqLike filter(@NotNull Predicate predicate); + + @Override + @Contract(pure = true) + @NotNull SeqLike filterNot(@NotNull Predicate predicate); + + @Override + @Contract(pure = true) + @NotNull SeqLike<@NotNull E> filterNotNull(); + + @Override + @Contract(pure = true) + @NotNull SeqLike<@NotNull U> filterIsInstance(@NotNull Class clazz); + + @Override + @Contract(pure = true) + @NotNull SeqLike map(@NotNull Function mapper); + + @Contract(pure = true) + @NotNull SeqLike mapIndexed(@NotNull IndexedFunction mapper); + + @Override + @Contract(pure = true) + @NotNull SeqLike<@NotNull U> mapNotNull(@NotNull Function mapper); + + @Contract(pure = true) + @NotNull SeqLike<@NotNull U> mapIndexedNotNull( + @NotNull IndexedFunction mapper); + + @Override + @Contract(pure = true) + @NotNull SeqLike mapMulti(@NotNull BiConsumer> mapper); + + @Contract(pure = true) + @NotNull SeqLike mapIndexedMulti(@NotNull IndexedBiConsumer> mapper); + + @Override + @Contract(pure = true) + @NotNull SeqLike flatMap(@NotNull Function> mapper); + + @Contract(value = "_, _ -> param1", mutates = "param1") + default > @NotNull G mapIndexedTo( + @NotNull G destination, @NotNull IndexedFunction mapper) { + int idx = 0; + for (E e : this) { + destination.plusAssign(mapper.apply(idx++, e)); + } + return destination; + } + + default @NotNull SeqView<@NotNull Tuple2> zipView(@NotNull SeqLike other) { + return new SeqViews.Zip<>(this, other); + } + + @Override + default int copyTo(@NotNull MutableSeq dest, int destPos, int limit) { + return copyTo(0, dest, destPos, limit); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyTo(int srcPos, @NotNull MutableSeq dest) { + return copyTo(srcPos, dest, 0, Integer.MAX_VALUE); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyTo(int srcPos, @NotNull MutableSeq dest, int destPos) { + return copyTo(srcPos, dest, destPos, Integer.MAX_VALUE); + } + + @Contract(mutates = "param2") + @Flow(sourceIsContainer = true, target = "dest", targetIsContainer = true) + default int copyTo(int srcPos, @NotNull MutableSeq dest, int destPos, int limit) { + if (srcPos < 0) { + throw new IllegalArgumentException("srcPos(" + srcPos + ") < 0"); + } + if (destPos < 0) { + throw new IllegalArgumentException("destPos(" + destPos + ") < 0"); + } + + if (limit <= 0) { + return 0; + } + + final int dl = dest.size(); // implicit null check of dest + if (destPos > dl) { + return 0; + } + + final int kn = this.knownSize(); + if (kn >= 0 && srcPos >= kn) { + return 0; + } + + int end = Math.min(dl - destPos, limit) + destPos; + + Iterator it; + try { + it = this.iterator(srcPos); + } catch (IndexOutOfBoundsException ignored) { + return 0; + } + + int idx = destPos; + while (it.hasNext() && idx < end) { + dest.set(idx++, it.next()); + } + return idx - destPos; + } +} diff --git a/kala-collection/src/main/java/kala/collection/SortedSet.java b/kala-collection/src/main/java/kala/collection/SortedSet.java index c6509afc..d9630734 100644 --- a/kala-collection/src/main/java/kala/collection/SortedSet.java +++ b/kala-collection/src/main/java/kala/collection/SortedSet.java @@ -1,69 +1,69 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -import kala.annotations.Covariant; -import kala.annotations.DelegateBy; -import kala.collection.base.OrderedTraversable; -import kala.collection.internal.convert.AsJavaConvert; -import kala.comparator.Comparators; -import kala.collection.factory.CollectionFactory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Comparator; -import java.util.Iterator; - -public interface SortedSet<@Covariant E> extends Set, OrderedTraversable { - - @NotNull CollectionFactory> iterableFactory(Comparator comparator); - - @Override - default java.util.@NotNull SortedSet asJava() { - return new AsJavaConvert.SortedSetAsJava<>(this); - } - - default Comparator comparator() { - return Comparators.naturalOrder(); - } - - @Contract(pure = true) - default E getFirst() { - return iterator().next(); - } - - @Contract(pure = true) - default E getLast() { - Iterator iterator = iterator(); - E res = iterator.next(); - while (iterator.hasNext()) { - res = iterator.next(); - } - return res; - } - - @Override - @DelegateBy("getLast()") - default E max() { - return getLast(); - } - - @Override - @DelegateBy("getFirst()") - default E min() { - return getFirst(); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +import kala.annotations.Covariant; +import kala.annotations.DelegateBy; +import kala.collection.base.OrderedTraversable; +import kala.collection.internal.convert.AsJavaConvert; +import kala.comparator.Comparators; +import kala.collection.factory.CollectionFactory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; +import java.util.Iterator; + +public interface SortedSet<@Covariant E> extends Set, OrderedTraversable { + + @NotNull CollectionFactory> iterableFactory(Comparator comparator); + + @Override + default java.util.@NotNull SortedSet asJava() { + return new AsJavaConvert.SortedSetAsJava<>(this); + } + + default Comparator comparator() { + return Comparators.naturalOrder(); + } + + @Contract(pure = true) + default E getFirst() { + return iterator().next(); + } + + @Contract(pure = true) + default E getLast() { + Iterator iterator = iterator(); + E res = iterator.next(); + while (iterator.hasNext()) { + res = iterator.next(); + } + return res; + } + + @Override + @DelegateBy("getLast()") + default E max() { + return getLast(); + } + + @Override + @DelegateBy("getFirst()") + default E min() { + return getFirst(); + } +} diff --git a/kala-collection/src/main/java/kala/collection/mutable/MutableCollection.java b/kala-collection/src/main/java/kala/collection/mutable/MutableCollection.java index 9b47b5e4..cd322bfd 100644 --- a/kala-collection/src/main/java/kala/collection/mutable/MutableCollection.java +++ b/kala-collection/src/main/java/kala/collection/mutable/MutableCollection.java @@ -1,110 +1,110 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.mutable; - -import kala.collection.Collection; -import kala.collection.internal.convert.AsJavaConvert; -import kala.collection.factory.CollectionFactory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; -import java.util.stream.Stream; - -public interface MutableCollection extends Collection, MutableAnyCollection { - - //region Static Factories - - static @NotNull CollectionFactory> factory() { - return CollectionFactory.narrow(MutableSeq.factory()); - } - - static @NotNull MutableCollection of() { - return MutableSeq.of(); - } - - @Contract("_ -> new") - static @NotNull MutableCollection of(E value1) { - return MutableSeq.of(value1); - } - - @Contract("_, _ -> new") - static @NotNull MutableCollection of(E value1, E value2) { - return MutableSeq.of(value1, value2); - } - - @Contract("_, _, _ -> new") - static @NotNull MutableCollection of(E value1, E value2, E value3) { - return MutableSeq.of(value1, value2, value3); - } - - @Contract("_, _, _, _ -> new") - static @NotNull MutableCollection of(E value1, E value2, E value3, E value4) { - return MutableSeq.of(value1, value2, value3, value4); - } - - @Contract("_, _, _, _, _ -> new") - static @NotNull MutableCollection of(E value1, E value2, E value3, E value4, E value5) { - return MutableSeq.of(value1, value2, value3, value4, value5); - } - - @SafeVarargs - static @NotNull MutableCollection of(E... values) { - return from(values); - } - - static @NotNull MutableCollection from(E @NotNull [] values) { - return MutableSeq.from(values); - } - - static @NotNull MutableCollection from(@NotNull Iterable values) { - return MutableSeq.from(values); - } - - static @NotNull MutableCollection from(@NotNull Iterator it) { - return MutableSeq.from(it); - } - - static @NotNull MutableCollection from(@NotNull Stream stream) { - return MutableSeq.from(stream); - } - - static > @NotNull MutableCollectionEditor edit(@NotNull C collection) { - return new MutableCollectionEditor<>(collection); - } - - //endregion - - @Override - default @NotNull String className() { - return "MutableCollection"; - } - - @Override - default @NotNull CollectionFactory> iterableFactory() { - return factory(); - } - - @Override - default @NotNull java.util.Collection asJava() { - return new AsJavaConvert.MutableCollectionAsJava<>(this); - } - - @SuppressWarnings({"MethodDoesntCallSuperMethod"}) - default @NotNull MutableCollection clone() { - return this.iterableFactory().from(this); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.mutable; + +import kala.collection.Collection; +import kala.collection.internal.convert.AsJavaConvert; +import kala.collection.factory.CollectionFactory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.stream.Stream; + +public interface MutableCollection extends Collection, MutableAnyCollection { + + //region Static Factories + + static @NotNull CollectionFactory> factory() { + return CollectionFactory.narrow(MutableSeq.factory()); + } + + static @NotNull MutableCollection of() { + return MutableSeq.of(); + } + + @Contract("_ -> new") + static @NotNull MutableCollection of(E value1) { + return MutableSeq.of(value1); + } + + @Contract("_, _ -> new") + static @NotNull MutableCollection of(E value1, E value2) { + return MutableSeq.of(value1, value2); + } + + @Contract("_, _, _ -> new") + static @NotNull MutableCollection of(E value1, E value2, E value3) { + return MutableSeq.of(value1, value2, value3); + } + + @Contract("_, _, _, _ -> new") + static @NotNull MutableCollection of(E value1, E value2, E value3, E value4) { + return MutableSeq.of(value1, value2, value3, value4); + } + + @Contract("_, _, _, _, _ -> new") + static @NotNull MutableCollection of(E value1, E value2, E value3, E value4, E value5) { + return MutableSeq.of(value1, value2, value3, value4, value5); + } + + @SafeVarargs + static @NotNull MutableCollection of(E... values) { + return from(values); + } + + static @NotNull MutableCollection from(E @NotNull [] values) { + return MutableSeq.from(values); + } + + static @NotNull MutableCollection from(@NotNull Iterable values) { + return MutableSeq.from(values); + } + + static @NotNull MutableCollection from(@NotNull Iterator it) { + return MutableSeq.from(it); + } + + static @NotNull MutableCollection from(@NotNull Stream stream) { + return MutableSeq.from(stream); + } + + static > @NotNull MutableCollectionEditor edit(@NotNull C collection) { + return new MutableCollectionEditor<>(collection); + } + + //endregion + + @Override + default @NotNull String className() { + return "MutableCollection"; + } + + @Override + default @NotNull CollectionFactory> iterableFactory() { + return factory(); + } + + @Override + default @NotNull java.util.Collection asJava() { + return new AsJavaConvert.MutableCollectionAsJava<>(this); + } + + @SuppressWarnings({"MethodDoesntCallSuperMethod"}) + default @NotNull MutableCollection clone() { + return this.iterableFactory().from(this); + } +} diff --git a/kala-collection/src/main/java/kala/collection/mutable/MutableCollectionEditor.java b/kala-collection/src/main/java/kala/collection/mutable/MutableCollectionEditor.java index bd8c2da2..3df6732e 100644 --- a/kala-collection/src/main/java/kala/collection/mutable/MutableCollectionEditor.java +++ b/kala-collection/src/main/java/kala/collection/mutable/MutableCollectionEditor.java @@ -1,31 +1,31 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection.mutable; - -import org.jetbrains.annotations.NotNull; - -public class MutableCollectionEditor> { - - protected final @NotNull C source; - - protected MutableCollectionEditor(@NotNull C source) { - this.source = source; - } - - public @NotNull C done() { - return source; - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection.mutable; + +import org.jetbrains.annotations.NotNull; + +public class MutableCollectionEditor> { + + protected final @NotNull C source; + + protected MutableCollectionEditor(@NotNull C source) { + this.source = source; + } + + public @NotNull C done() { + return source; + } +} diff --git a/kala-common-gson/build.gradle.kts b/kala-common-gson/build.gradle.kts index bc524560..e873cf2f 100644 --- a/kala-common-gson/build.gradle.kts +++ b/kala-common-gson/build.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + dependencies { api("com.google.code.gson:gson:2.11.0") compileOnly(project(":kala-base")) diff --git a/settings.gradle.kts b/settings.gradle.kts index d563f49d..87ee14aa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,9 +1,25 @@ -rootProject.name = "kala-common" - -include( - "kala-base", - "kala-collection", - "kala-collection-primitive", - "kala-common-gson", - "benchmark" +/* + * Copyright 2025 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +rootProject.name = "kala-common" + +include( + "kala-base", + "kala-collection", + "kala-collection-primitive", + "kala-common-gson", + "benchmark" ) \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 4ccd7675..42504be6 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,21 +1,21 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -module kala.common { - requires transitive kala.base; - requires transitive kala.collection; - requires transitive kala.collection.primitive; +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module kala.common { + requires transitive kala.base; + requires transitive kala.collection; + requires transitive kala.collection.primitive; } \ No newline at end of file diff --git a/src/test/java/kala/collection/SimpleIterable.java b/src/test/java/kala/collection/SimpleIterable.java index 7ddac586..906e7b28 100644 --- a/src/test/java/kala/collection/SimpleIterable.java +++ b/src/test/java/kala/collection/SimpleIterable.java @@ -1,34 +1,34 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; - -@SuppressWarnings("unchecked") -public final class SimpleIterable implements Iterable { - private final Iterable source; - - public SimpleIterable(Iterable source) { - this.source = source; - } - - @Override - public @NotNull Iterator iterator() { - return (Iterator) source.iterator(); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; + +@SuppressWarnings("unchecked") +public final class SimpleIterable implements Iterable { + private final Iterable source; + + public SimpleIterable(Iterable source) { + this.source = source; + } + + @Override + public @NotNull Iterator iterator() { + return (Iterator) source.iterator(); + } +} diff --git a/src/test/java/kala/collection/TestData.java b/src/test/java/kala/collection/TestData.java index f16ef05f..d3ee834c 100644 --- a/src/test/java/kala/collection/TestData.java +++ b/src/test/java/kala/collection/TestData.java @@ -1,64 +1,64 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.collection; - -public final class TestData { - public static final Integer[][] data1 = new Integer[][]{ - new Integer[]{-1155484576}, - new Integer[]{-723955400, 1033096058}, - new Integer[]{-1690734402, -1557280266, 1327362106}, - new Integer[]{-1930858313, 502539523, -1728529858, -938301587}, - new Integer[]{1431162155, 1085665355, 1654374947, -1661998771, -65105105}, - new Integer[]{-73789608, -518907128, 99135751, -252332814, 755814641, 1180918287}, - new Integer[]{1344049776, 553609048, 1580443894, 629649304, -1266264776, 99807007, 5955764}, - new Integer[]{-1946737912, 39620447, -152527805, -1877116806, 448784075, 1086124775, -1609984092, 1227951724}, - new Integer[]{1764356251, 64111306, -960731419, -100082026, -39845375, -1339022546, 2092649110, -568315836, -1089884900}, - new Integer[]{-81839914, -1146103148, -1846688624, -784703072, 55004124, -691960657, 1770461755, -2032810463, -1177788003, -432352882}, - new Integer[]{-839642705, -1964694874, -696017484, 747143456, 2131257094, 861414966, -1691376784, 321888858, 97432359, -394174055, -420865190, -588028832, 517452616, 598394366, -471713575, 187893679, 107679699, 936781870, -1663711465, -1256840416, -1169018480, 1170757854, 588643520, 1049421403, -73874173, -918753724, 1629440008, -269643895, -297299950, -1567321364}, - new Integer[]{1560741965, -29065749, -2095518261, -2053840944, -1953767948, 1036846372, -2146535532, 158920197, 121112810, 1638812707, 729665866, 1069135634, 1900492655, 330346431, -1641844715, -1890370609, 1878560651, -1293774809, 630043225, 1517435384, 1027087423, 231245826, -379670011, 1004679659, -262841860}, - new Integer[]{-2077726680, 154109103, 825333336, -67182673, -995166775, -1530991048, 1925715711, 1154541817, 751183351, 1198252008, 2057124839, -1757515092, 951876894, 307461977, -1446965049, -93497934, -2036897380, -141931175, -1243282999, -1767897212, -326538861, 668383541, -1127504002, 167553297, -616285696, -2073353158, -2058035695, 1937481700, -933862644, 708712824, 1993841599, -977003131, 535082402, 558349769, 614349446, -549504738, -1996124607, -388514799, 124856604, -569344159, 1443688722, -475582010, 493303586, -1473438551, 1467339580, 780033970, 401731737, -2017917601, 369501559, -612490505, -1534083948, -1939619682, -1399819297, -828802476, 1291105071}, - new Integer[]{479145738, -36987994, -1290379585, 1154562109, 1745023580, -715432528, 1268112458, -45846638, -406955111, 776272414, -1597567175, -470535066, 81741755, 519007174, 21683276, 460542380, -2015459067}, - new Integer[]{-501375027, 2123142177, 1151101527, -1651877030, 1012552456, -17828688, -899574844, 1952546997, -1912204039, -157448937, 2117149793, -493974414, -1707144633, 637534921, -834529953, 117783042, 2070202481, -1419561962, -62703012, 322333913, 1887420486, 479228808, -496078091, 2134328438, 428891034, -1021440624, 2057626015, 1299639456, -1681538506, 1705268322, 1209482167, 1774890481, -1574471152, -1110077924, -526743850, -1509162344, 272389819, -610000595, 335206250, -671304871, -437490656, 41198324, -895294334, 1424048344, -1652361106, -1391481689, -217545496, 662838551, -1047496370, 568433270, 1404791156, 1497921853, -1749262245, -1990944529, 133474463, -147608679, 983112401, -1644976988, -749015210, -609193499, -24878973, -2016714742, 1889037072, -148139058, 1607007762, 476570531, -224607966, -691164749, 1238797915, -786633633, 1127655249, -1956246611, 1270273841, 272108607, -1873415768, 510078159, 1009761612, 429048124, -50321012, 1211557550}, - new Integer[]{234133094, 1762591245, -1371965149, -126596815, -1995197617, 1819360638, 673595983, -22742010, 839155113, 1562105927, 1201763039, 560279772, -1009831635, 459443448, -83475824, 550344701, 971805118, 2085356962, -922654475, -139591535, 1691950030, 501698146, -162275721, 1351819091, 872437504, -1276289731, 1444030877, 1121291400, 1647849231, -195902669, 2134162574, -2100941523}, - new Integer[]{-967130969, 1318180826, -1123767596, 2106368231, 798451794, -1548801192, 1352720895, 1714546679, 1320663412, 1921488062, -478995291, -1999099902, -233776895, 698788740, -412187519, 2052243888, -1353597633, 1446579369, 1751274636, 1823444428, -1548695384, -221239866, 205211774, 1525936254, -1096962284, 2117016927, -428998508, -1816433729, -641070825, -2087883652, 1052597652, -569875192, 1369258407, -1888420489, 222042382, 191828556, -615609854, 1007346712, -1785127453, -1060257239, 875208654, 1528759006, -1631951605, -1035668647, -1774734975, 724578719, -1448977774, 55897966, -474079998, -1355826861, -271053085, -131212098, 1534149776, 1955084587, 105560136, 882539419, -1404119581, 1883850984, -1171437392, -960691513, 420011920, -759534485, 298785715, 593022758, 1496406193, 1173433479, -2008874797, 232446645}, - new Integer[]{-2038524203, 1522198427, 712098161, -680489546, 1049032788, -303501149, -1369047575, 1216317703, 729038159, -43714227, 976600499, -443993940, 1150199393, -1437716590, 673645934, -2001560272, -1831476958, -1565747409, -447382395, -109961246, 157102540, -1454891918, 916449645, 704791496, 2064519969, 861765716, -449139157, -1890620972, -1659211636, -458395188, 1397688601, 698774613, 1314250374, -850171807, -1320739352, 1306408368, -1656785605, -1651043327, 669190888, 337417807, -1493421716, -1815841263, -1171026298, -839670312, -216268906, 339998661, 425394454, -928904286, 1359074644, -1779625552, 1522378451, 1560644196, 107576577, -1725736802}, - new Integer[]{1283820335, -921962591, -1728642143, -1837699554, 1143399325, 571316481, 2004828009, 176716113, 609831754, 1995391516, -1825185063, -1480140610, 539112579, -1418830401, 260135126, 1568432935, -1605370819, -1470790800, -1877814431, -1636703093, 43754825, -1225137012, -1299440665, 119785968, 676238020, -1639979089, -2059299625, 137872739, 1734669779, 1992529495, 2049065077, -321245635, -612572528, -697843509, 1528357101, 358261159, -2073214913, -94831559, 1591117227, -304896161, -966850364}, - new Integer[]{187177449, -215916869, 502696793, -1188028438, 1241368713, 707229678, -1983797637, -1348961821, 1097091364, 1990655369, -738513627, 1800502344, -1172477342, -1276595643, -1945965760, -1155029062, 1569090955, -896989441, -789775015, -971014697, -682621090, -134288125, -1249742956, 1333290792, 192223777, 1447495820, -583510048, -849505476, -2112193287, 1890649995, 1212276587}, - new Integer[]{-355244933, 1583685799, 506785624, -1965503039, -60079998, -1072431483, -1711246161, -898941108, -418438334, -324822200, 846098325, 693375445, 1237190045, 617599067, 1465598396, 1010239742, -225936203, 1742577261, -261165028, -1583753335, 1218294977, 1475113405, 2109492194, 1029949247, -793983708, -480188777, -931842392, 1658157843, -721505861, 1184420381, 1763866087, -1455935609, 2082385270, -1781492918, -1396651607, -1583997617, -131370454, -954339276, 705444482, -2067537357, 2135277988, 400884624, 1868419776, 1125979193, 1211982848, 1550843515, -686868767, -1865129214, 1189033788, 60473975}, - new Integer[]{-1395004556, 509355015, 1477416883, -1259961052, -1419730535, 258608095, 1285718926, 210902209, 439743686, 943522906, 774701918, -553523489, 1655509503, -1886882878, 858009452, -177129612, 2098292889, -1365450009, -1673557437, -1847607396, 1655330081, -357525455}, - new Integer[]{-613945136, 1469322876, -408006668, 1451416301, 1471930199, 860909903, -926505464, -483349021, 745101308, 1882432928, 1370883223, 1292664365, 526195968, 351836861, -1468388296, -252859589, 958955090, -1156487844, 1062185277, 1030445972, -1274298115, -1510503421, -1551840696, 1525969365, 1811614177, 1443999146, 873786404, 839077370, 620412837, 1660579486, -452448559, -587866404, -1047816213, -11612249, 1302390752, -996751366, 1772995525, 32002925, 66676225, 65838971, -544870552, -3566057, 975821274, 1974503539, -131725025, 491404084, 1273460761, -1138905755, -1062796414, 511268318, 1529555148, 786390792, 283117287, -1535398116, -1060939793, 1794890574, -1327839721, -769814904, 1205451590, 301334689, 1005316676, 187033905, 1387209069, 1749053807, 1062324794, -1837950270, -530801107, 197192680, -777330475, 1086819555, 1217046544, 30071302, -541542734, -609292066, -2013005002, 1021599181, 1895510825, 256569222, 1628657001, 1444502996, 788236410, 828404564, -369598609, 802444803, -203608251, -1645416238, -1951311968, 963440797, 859743551}, - new Integer[]{-518237769, -15160448, -891624669, 2079744867, 1665933292, 166333867, 2046279141, -2020018476, -1189463743, 55521537, -1497585875, -989199047, -960483044, -817322932, -1437564669, -1995862528, 64525333, 1553852803, -11241274, -1492580294, 63979025, 1122309199, -46326430, -805531964, -1412530801, -1350087477, 1433019585, -808441172, 179017793, 1698970251, 267424897, 1845288908, -1057848098, -1185768480, 85082600, 256860091, 157543990, 375164249, -1332159212, -341014810, -1153576058, -193313397, 486144886, -927070215, -1611900403, -1103738603, -1735600767, 1681123715, -1828871201, 1641175774, -160322659, -1544701480, -1770274824}, - new Integer[]{-2108291486, -98001607, 476907411, -1353116758, 960513538, 1308465714, -1586725700, 932857313, -1388301051, -414332861, -1991180764, 1642291975, -1920363972, -17808190, 1190356020, -904245697, -1420245521, 1926238719, -795813020, 1528273872, 2102474328, -404339544, 1816661964, 1502156585, 1242034005, 736043887, 17104378, 292037924, -295399080, -1543562007, 1763212550, -922909042, -2136097887, -523847751, 838194660, 335560423, 750085551, 1143136493, -1050543111, -1779063963, -1813193741, -320258905, -653968656, 13948478, -1267772474, -1808376576, -821465651, 1951412775, 126700189, -1572994264, -897838271, -414488041, -900586373, -964964655, -1244867776, -1876074160}, - new Integer[]{-986382387, 238438864, 774438815, 2015028125, -937284107, -177722588, 92833249, -791484088, 1277303629, 10949865, 2008753865, -1308243343, 541394021, -821583650, -2053314591, 84906611, -711847167, -324039510, -1418916146, 1102248496, 1625216764, 2086734569, 1382522583, -521637560, -1825904280, 1749127559, 1077586600, -1846016378, -546300422, -401688239, -1327989166, 1046799262, -1191582043, 1124664009, 531883413, -1637330923, -1587753596, 805671993, -1299967390, -1457164416, -615438084, -1013627638, -41818214, 413019888, 641887777, -1136620971, -1075270628, -855304788, 127321432, 1153243322, -878679554, 1284435232, 13157694, 486231920, -1667727847, 1470264342, -827885624, 37142685, 129833930, 1819513123, -55636565, 890661608, -1227175689, -1275414429, -374414338, 144603211, -93383088, -1273989016, -417873892, 1853789741, 1955993559}, - new Integer[]{-1667799601, -899335505, -1523031647, 1113965012, -329978966, -676238522, -678064931, -749218105, 2071163317, -798893943, 142838037, -1609398208, -457761201, 314139467, 1132150196, 1940111663, -1031633584, 1509842668, -1626390585}, - new Integer[]{-668934803, -281336596, 1743888391, 302728990, 45328352, -2042901056, 1752831255, -288296387, 1986047560, 1651385064, 1374553609, -1713108419, 2127002317, -872014271, -1595918042, -704109116, 1083420295, 1360693911, 1863723758, -408290580, 930339360, 496146814, 1337807197, 749476662, -1508721481, 1224114785, -560279697, -458294595, 1328221447, 264404699, 746872038, -1586121042, 1705783496, -671303611, -1021745590, 724324087, 543721045, -1010566513, -207640271, 1332430654, 439100558, -1449770925, 1767297216, 253747988, 463811839, 510356519, 717936241, 1581216106, -143307711, -223231182, -1758442, 1268734787, 1146447008, 234814721, 2147019805, 112388523, 1672240893, -14549861, 1275504916, 529200871} - }; - - public static final String[][] data1s; - - static { - data1s = new String[data1.length][]; - for (int i = 0; i < data1.length; i++) { - Integer[] data = data1[i]; - String[] t = new String[data.length]; - for (int j = 0; j < data.length; j++) { - t[j] = data[j].toString(); - } - data1s[i] = t; - } - } - -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.collection; + +public final class TestData { + public static final Integer[][] data1 = new Integer[][]{ + new Integer[]{-1155484576}, + new Integer[]{-723955400, 1033096058}, + new Integer[]{-1690734402, -1557280266, 1327362106}, + new Integer[]{-1930858313, 502539523, -1728529858, -938301587}, + new Integer[]{1431162155, 1085665355, 1654374947, -1661998771, -65105105}, + new Integer[]{-73789608, -518907128, 99135751, -252332814, 755814641, 1180918287}, + new Integer[]{1344049776, 553609048, 1580443894, 629649304, -1266264776, 99807007, 5955764}, + new Integer[]{-1946737912, 39620447, -152527805, -1877116806, 448784075, 1086124775, -1609984092, 1227951724}, + new Integer[]{1764356251, 64111306, -960731419, -100082026, -39845375, -1339022546, 2092649110, -568315836, -1089884900}, + new Integer[]{-81839914, -1146103148, -1846688624, -784703072, 55004124, -691960657, 1770461755, -2032810463, -1177788003, -432352882}, + new Integer[]{-839642705, -1964694874, -696017484, 747143456, 2131257094, 861414966, -1691376784, 321888858, 97432359, -394174055, -420865190, -588028832, 517452616, 598394366, -471713575, 187893679, 107679699, 936781870, -1663711465, -1256840416, -1169018480, 1170757854, 588643520, 1049421403, -73874173, -918753724, 1629440008, -269643895, -297299950, -1567321364}, + new Integer[]{1560741965, -29065749, -2095518261, -2053840944, -1953767948, 1036846372, -2146535532, 158920197, 121112810, 1638812707, 729665866, 1069135634, 1900492655, 330346431, -1641844715, -1890370609, 1878560651, -1293774809, 630043225, 1517435384, 1027087423, 231245826, -379670011, 1004679659, -262841860}, + new Integer[]{-2077726680, 154109103, 825333336, -67182673, -995166775, -1530991048, 1925715711, 1154541817, 751183351, 1198252008, 2057124839, -1757515092, 951876894, 307461977, -1446965049, -93497934, -2036897380, -141931175, -1243282999, -1767897212, -326538861, 668383541, -1127504002, 167553297, -616285696, -2073353158, -2058035695, 1937481700, -933862644, 708712824, 1993841599, -977003131, 535082402, 558349769, 614349446, -549504738, -1996124607, -388514799, 124856604, -569344159, 1443688722, -475582010, 493303586, -1473438551, 1467339580, 780033970, 401731737, -2017917601, 369501559, -612490505, -1534083948, -1939619682, -1399819297, -828802476, 1291105071}, + new Integer[]{479145738, -36987994, -1290379585, 1154562109, 1745023580, -715432528, 1268112458, -45846638, -406955111, 776272414, -1597567175, -470535066, 81741755, 519007174, 21683276, 460542380, -2015459067}, + new Integer[]{-501375027, 2123142177, 1151101527, -1651877030, 1012552456, -17828688, -899574844, 1952546997, -1912204039, -157448937, 2117149793, -493974414, -1707144633, 637534921, -834529953, 117783042, 2070202481, -1419561962, -62703012, 322333913, 1887420486, 479228808, -496078091, 2134328438, 428891034, -1021440624, 2057626015, 1299639456, -1681538506, 1705268322, 1209482167, 1774890481, -1574471152, -1110077924, -526743850, -1509162344, 272389819, -610000595, 335206250, -671304871, -437490656, 41198324, -895294334, 1424048344, -1652361106, -1391481689, -217545496, 662838551, -1047496370, 568433270, 1404791156, 1497921853, -1749262245, -1990944529, 133474463, -147608679, 983112401, -1644976988, -749015210, -609193499, -24878973, -2016714742, 1889037072, -148139058, 1607007762, 476570531, -224607966, -691164749, 1238797915, -786633633, 1127655249, -1956246611, 1270273841, 272108607, -1873415768, 510078159, 1009761612, 429048124, -50321012, 1211557550}, + new Integer[]{234133094, 1762591245, -1371965149, -126596815, -1995197617, 1819360638, 673595983, -22742010, 839155113, 1562105927, 1201763039, 560279772, -1009831635, 459443448, -83475824, 550344701, 971805118, 2085356962, -922654475, -139591535, 1691950030, 501698146, -162275721, 1351819091, 872437504, -1276289731, 1444030877, 1121291400, 1647849231, -195902669, 2134162574, -2100941523}, + new Integer[]{-967130969, 1318180826, -1123767596, 2106368231, 798451794, -1548801192, 1352720895, 1714546679, 1320663412, 1921488062, -478995291, -1999099902, -233776895, 698788740, -412187519, 2052243888, -1353597633, 1446579369, 1751274636, 1823444428, -1548695384, -221239866, 205211774, 1525936254, -1096962284, 2117016927, -428998508, -1816433729, -641070825, -2087883652, 1052597652, -569875192, 1369258407, -1888420489, 222042382, 191828556, -615609854, 1007346712, -1785127453, -1060257239, 875208654, 1528759006, -1631951605, -1035668647, -1774734975, 724578719, -1448977774, 55897966, -474079998, -1355826861, -271053085, -131212098, 1534149776, 1955084587, 105560136, 882539419, -1404119581, 1883850984, -1171437392, -960691513, 420011920, -759534485, 298785715, 593022758, 1496406193, 1173433479, -2008874797, 232446645}, + new Integer[]{-2038524203, 1522198427, 712098161, -680489546, 1049032788, -303501149, -1369047575, 1216317703, 729038159, -43714227, 976600499, -443993940, 1150199393, -1437716590, 673645934, -2001560272, -1831476958, -1565747409, -447382395, -109961246, 157102540, -1454891918, 916449645, 704791496, 2064519969, 861765716, -449139157, -1890620972, -1659211636, -458395188, 1397688601, 698774613, 1314250374, -850171807, -1320739352, 1306408368, -1656785605, -1651043327, 669190888, 337417807, -1493421716, -1815841263, -1171026298, -839670312, -216268906, 339998661, 425394454, -928904286, 1359074644, -1779625552, 1522378451, 1560644196, 107576577, -1725736802}, + new Integer[]{1283820335, -921962591, -1728642143, -1837699554, 1143399325, 571316481, 2004828009, 176716113, 609831754, 1995391516, -1825185063, -1480140610, 539112579, -1418830401, 260135126, 1568432935, -1605370819, -1470790800, -1877814431, -1636703093, 43754825, -1225137012, -1299440665, 119785968, 676238020, -1639979089, -2059299625, 137872739, 1734669779, 1992529495, 2049065077, -321245635, -612572528, -697843509, 1528357101, 358261159, -2073214913, -94831559, 1591117227, -304896161, -966850364}, + new Integer[]{187177449, -215916869, 502696793, -1188028438, 1241368713, 707229678, -1983797637, -1348961821, 1097091364, 1990655369, -738513627, 1800502344, -1172477342, -1276595643, -1945965760, -1155029062, 1569090955, -896989441, -789775015, -971014697, -682621090, -134288125, -1249742956, 1333290792, 192223777, 1447495820, -583510048, -849505476, -2112193287, 1890649995, 1212276587}, + new Integer[]{-355244933, 1583685799, 506785624, -1965503039, -60079998, -1072431483, -1711246161, -898941108, -418438334, -324822200, 846098325, 693375445, 1237190045, 617599067, 1465598396, 1010239742, -225936203, 1742577261, -261165028, -1583753335, 1218294977, 1475113405, 2109492194, 1029949247, -793983708, -480188777, -931842392, 1658157843, -721505861, 1184420381, 1763866087, -1455935609, 2082385270, -1781492918, -1396651607, -1583997617, -131370454, -954339276, 705444482, -2067537357, 2135277988, 400884624, 1868419776, 1125979193, 1211982848, 1550843515, -686868767, -1865129214, 1189033788, 60473975}, + new Integer[]{-1395004556, 509355015, 1477416883, -1259961052, -1419730535, 258608095, 1285718926, 210902209, 439743686, 943522906, 774701918, -553523489, 1655509503, -1886882878, 858009452, -177129612, 2098292889, -1365450009, -1673557437, -1847607396, 1655330081, -357525455}, + new Integer[]{-613945136, 1469322876, -408006668, 1451416301, 1471930199, 860909903, -926505464, -483349021, 745101308, 1882432928, 1370883223, 1292664365, 526195968, 351836861, -1468388296, -252859589, 958955090, -1156487844, 1062185277, 1030445972, -1274298115, -1510503421, -1551840696, 1525969365, 1811614177, 1443999146, 873786404, 839077370, 620412837, 1660579486, -452448559, -587866404, -1047816213, -11612249, 1302390752, -996751366, 1772995525, 32002925, 66676225, 65838971, -544870552, -3566057, 975821274, 1974503539, -131725025, 491404084, 1273460761, -1138905755, -1062796414, 511268318, 1529555148, 786390792, 283117287, -1535398116, -1060939793, 1794890574, -1327839721, -769814904, 1205451590, 301334689, 1005316676, 187033905, 1387209069, 1749053807, 1062324794, -1837950270, -530801107, 197192680, -777330475, 1086819555, 1217046544, 30071302, -541542734, -609292066, -2013005002, 1021599181, 1895510825, 256569222, 1628657001, 1444502996, 788236410, 828404564, -369598609, 802444803, -203608251, -1645416238, -1951311968, 963440797, 859743551}, + new Integer[]{-518237769, -15160448, -891624669, 2079744867, 1665933292, 166333867, 2046279141, -2020018476, -1189463743, 55521537, -1497585875, -989199047, -960483044, -817322932, -1437564669, -1995862528, 64525333, 1553852803, -11241274, -1492580294, 63979025, 1122309199, -46326430, -805531964, -1412530801, -1350087477, 1433019585, -808441172, 179017793, 1698970251, 267424897, 1845288908, -1057848098, -1185768480, 85082600, 256860091, 157543990, 375164249, -1332159212, -341014810, -1153576058, -193313397, 486144886, -927070215, -1611900403, -1103738603, -1735600767, 1681123715, -1828871201, 1641175774, -160322659, -1544701480, -1770274824}, + new Integer[]{-2108291486, -98001607, 476907411, -1353116758, 960513538, 1308465714, -1586725700, 932857313, -1388301051, -414332861, -1991180764, 1642291975, -1920363972, -17808190, 1190356020, -904245697, -1420245521, 1926238719, -795813020, 1528273872, 2102474328, -404339544, 1816661964, 1502156585, 1242034005, 736043887, 17104378, 292037924, -295399080, -1543562007, 1763212550, -922909042, -2136097887, -523847751, 838194660, 335560423, 750085551, 1143136493, -1050543111, -1779063963, -1813193741, -320258905, -653968656, 13948478, -1267772474, -1808376576, -821465651, 1951412775, 126700189, -1572994264, -897838271, -414488041, -900586373, -964964655, -1244867776, -1876074160}, + new Integer[]{-986382387, 238438864, 774438815, 2015028125, -937284107, -177722588, 92833249, -791484088, 1277303629, 10949865, 2008753865, -1308243343, 541394021, -821583650, -2053314591, 84906611, -711847167, -324039510, -1418916146, 1102248496, 1625216764, 2086734569, 1382522583, -521637560, -1825904280, 1749127559, 1077586600, -1846016378, -546300422, -401688239, -1327989166, 1046799262, -1191582043, 1124664009, 531883413, -1637330923, -1587753596, 805671993, -1299967390, -1457164416, -615438084, -1013627638, -41818214, 413019888, 641887777, -1136620971, -1075270628, -855304788, 127321432, 1153243322, -878679554, 1284435232, 13157694, 486231920, -1667727847, 1470264342, -827885624, 37142685, 129833930, 1819513123, -55636565, 890661608, -1227175689, -1275414429, -374414338, 144603211, -93383088, -1273989016, -417873892, 1853789741, 1955993559}, + new Integer[]{-1667799601, -899335505, -1523031647, 1113965012, -329978966, -676238522, -678064931, -749218105, 2071163317, -798893943, 142838037, -1609398208, -457761201, 314139467, 1132150196, 1940111663, -1031633584, 1509842668, -1626390585}, + new Integer[]{-668934803, -281336596, 1743888391, 302728990, 45328352, -2042901056, 1752831255, -288296387, 1986047560, 1651385064, 1374553609, -1713108419, 2127002317, -872014271, -1595918042, -704109116, 1083420295, 1360693911, 1863723758, -408290580, 930339360, 496146814, 1337807197, 749476662, -1508721481, 1224114785, -560279697, -458294595, 1328221447, 264404699, 746872038, -1586121042, 1705783496, -671303611, -1021745590, 724324087, 543721045, -1010566513, -207640271, 1332430654, 439100558, -1449770925, 1767297216, 253747988, 463811839, 510356519, 717936241, 1581216106, -143307711, -223231182, -1758442, 1268734787, 1146447008, 234814721, 2147019805, 112388523, 1672240893, -14549861, 1275504916, 529200871} + }; + + public static final String[][] data1s; + + static { + data1s = new String[data1.length][]; + for (int i = 0; i < data1.length; i++) { + Integer[] data = data1[i]; + String[] t = new String[data.length]; + for (int j = 0; j < data.length; j++) { + t[j] = data[j].toString(); + } + data1s[i] = t; + } + } + +} diff --git a/src/test/java/kala/control/OptionTest.java b/src/test/java/kala/control/OptionTest.java index 28d0742f..77308d0c 100644 --- a/src/test/java/kala/control/OptionTest.java +++ b/src/test/java/kala/control/OptionTest.java @@ -1,48 +1,48 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control; - -import org.junit.jupiter.api.*; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.*; - -public class OptionTest { - Option[] opts = new Option[]{ - Option.none(), - Option.some("foo"), - Option.some(10), - Option.some(Arrays.asList("A", "B", "C")), - Option.some(null) - }; - - @Test - public void serializationTest() { - assertAll(Arrays.stream(opts).map(opt -> () -> { - ByteArrayOutputStream out = new ByteArrayOutputStream(512); - new ObjectOutputStream(out).writeObject(opt); - byte[] buffer = out.toByteArray(); - ByteArrayInputStream in = new ByteArrayInputStream(buffer); - Object obj = new ObjectInputStream(in).readObject(); - assertEquals(opt, obj); - })); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control; + +import org.junit.jupiter.api.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +public class OptionTest { + Option[] opts = new Option[]{ + Option.none(), + Option.some("foo"), + Option.some(10), + Option.some(Arrays.asList("A", "B", "C")), + Option.some(null) + }; + + @Test + public void serializationTest() { + assertAll(Arrays.stream(opts).map(opt -> () -> { + ByteArrayOutputStream out = new ByteArrayOutputStream(512); + new ObjectOutputStream(out).writeObject(opt); + byte[] buffer = out.toByteArray(); + ByteArrayInputStream in = new ByteArrayInputStream(buffer); + Object obj = new ObjectInputStream(in).readObject(); + assertEquals(opt, obj); + })); + } +} diff --git a/src/test/java/kala/control/primitive/BooleanOptionTest.java b/src/test/java/kala/control/primitive/BooleanOptionTest.java index b6012769..b5d42709 100644 --- a/src/test/java/kala/control/primitive/BooleanOptionTest.java +++ b/src/test/java/kala/control/primitive/BooleanOptionTest.java @@ -1,40 +1,40 @@ -/* - * Copyright 2024 Glavo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package kala.control.primitive; - -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; - -public class BooleanOptionTest { - @Test - public void serializationTest() { - assertAll(Stream.of(BooleanOption.True, BooleanOption.False, BooleanOption.None).map(opt -> () -> { - ByteArrayOutputStream out = new ByteArrayOutputStream(512); - new ObjectOutputStream(out).writeObject(opt); - byte[] buffer = out.toByteArray(); - ByteArrayInputStream in = new ByteArrayInputStream(buffer); - Object obj = new ObjectInputStream(in).readObject(); - assertSame(opt, obj); - })); - } -} +/* + * Copyright 2024 Glavo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package kala.control.primitive; + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +public class BooleanOptionTest { + @Test + public void serializationTest() { + assertAll(Stream.of(BooleanOption.True, BooleanOption.False, BooleanOption.None).map(opt -> () -> { + ByteArrayOutputStream out = new ByteArrayOutputStream(512); + new ObjectOutputStream(out).writeObject(opt); + byte[] buffer = out.toByteArray(); + ByteArrayInputStream in = new ByteArrayInputStream(buffer); + Object obj = new ObjectInputStream(in).readObject(); + assertSame(opt, obj); + })); + } +}