Skip to content

Commit

Permalink
Improve generic types for TypedFunctions (deephaven#4463)
Browse files Browse the repository at this point in the history
  • Loading branch information
devinrsmith committed Sep 11, 2023
1 parent 58783c0 commit 0caa2c7
Show file tree
Hide file tree
Showing 22 changed files with 569 additions and 237 deletions.
2 changes: 2 additions & 0 deletions extensions/protobuf/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dependencies {

Classpaths.inheritImmutables(project)

compileOnly depAnnotations

Classpaths.inheritJUnitPlatform(project)
Classpaths.inheritAssertJ(project)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,31 @@
*/
package io.deephaven.functions;

import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class BooleanFunctions {

static <T> ToBooleanFunction<T> cast() {
return cast(PrimitiveBoolean.INSTANCE);
}

static <T> ToBooleanFunction<T> cast(ToBooleanFunction<? super T> f) {
// noinspection unchecked
return (ToBooleanFunction<T>) PrimitiveBoolean.INSTANCE;
return (ToBooleanFunction<T>) f;
}

static <T> ToBooleanFunction<T> of(Predicate<T> predicate) {
return predicate instanceof ToBooleanFunction ? (ToBooleanFunction<T>) predicate : predicate::test;
static <T> ToBooleanFunction<T> of(Predicate<? super T> predicate) {
return predicate instanceof ToBooleanFunction
? cast((ToBooleanFunction<? super T>) predicate)
: predicate::test;
}

public static <T> ToBooleanFunction<T> ofTrue() {
Expand All @@ -30,15 +40,19 @@ public static <T> ToBooleanFunction<T> ofFalse() {
return (ToBooleanFunction<T>) OfFalse.INSTANCE;
}

static <T, R> ToBooleanFunction<T> map(Function<T, R> f, Predicate<R> g) {
static <T, R> ToBooleanFunction<T> map(
Function<? super T, ? extends R> f,
Predicate<? super R> g) {
return new BooleanMap<>(f, g);
}

static <T> ToBooleanFunction<T> not(ToBooleanFunction<T> f) {
return f instanceof BooleanNot ? of(((BooleanNot<T>) f).function()) : new BooleanNot<>(f);
static <T> ToBooleanFunction<T> not(Predicate<? super T> f) {
return f instanceof BooleanNot
? cast(((BooleanNot<? super T>) f).negate())
: new BooleanNot<>(f);
}

static <T> ToBooleanFunction<T> or(Collection<Predicate<T>> functions) {
static <T> ToBooleanFunction<T> or(Collection<Predicate<? super T>> functions) {
if (functions.isEmpty()) {
return ofFalse();
}
Expand All @@ -48,7 +62,7 @@ static <T> ToBooleanFunction<T> or(Collection<Predicate<T>> functions) {
return new BooleanOr<>(functions);
}

static <T> ToBooleanFunction<T> and(Collection<Predicate<T>> functions) {
static <T> ToBooleanFunction<T> and(Collection<Predicate<? super T>> functions) {
if (functions.isEmpty()) {
return ofTrue();
}
Expand All @@ -65,6 +79,26 @@ private enum OfTrue implements ToBooleanFunction<Object> {
public boolean test(Object value) {
return true;
}

@Override
@NotNull
public ToBooleanFunction<Object> negate() {
return ofFalse();
}

@Override
@NotNull
public ToBooleanFunction<Object> and(@NotNull Predicate<? super Object> other) {
// always other
return of(other);
}

@Override
@NotNull
public ToBooleanFunction<Object> or(@NotNull Predicate<? super Object> other) {
// always true
return this;
}
}

private enum OfFalse implements ToBooleanFunction<Object> {
Expand All @@ -74,6 +108,26 @@ private enum OfFalse implements ToBooleanFunction<Object> {
public boolean test(Object value) {
return false;
}

@Override
@NotNull
public ToBooleanFunction<Object> negate() {
return ofTrue();
}

@Override
@NotNull
public ToBooleanFunction<Object> and(@NotNull Predicate<? super Object> other) {
// always false
return this;
}

@Override
@NotNull
public ToBooleanFunction<Object> or(@NotNull Predicate<? super Object> other) {
// always other
return of(other);
}
}

private enum PrimitiveBoolean implements ToBooleanFunction<Object> {
Expand All @@ -86,10 +140,10 @@ public boolean test(Object value) {
}

private static class BooleanMap<T, R> implements ToBooleanFunction<T> {
private final Function<T, R> f;
private final Predicate<R> g;
private final Function<? super T, ? extends R> f;
private final Predicate<? super R> g;

public BooleanMap(Function<T, R> f, Predicate<R> g) {
public BooleanMap(Function<? super T, ? extends R> f, Predicate<? super R> g) {
this.f = Objects.requireNonNull(f);
this.g = Objects.requireNonNull(g);
}
Expand All @@ -98,58 +152,92 @@ public BooleanMap(Function<T, R> f, Predicate<R> g) {
public boolean test(T value) {
return g.test(f.apply(value));
}

@Override
@NotNull
public ToBooleanFunction<T> negate() {
return new BooleanMap<>(f, g.negate());
}
}

private static class BooleanNot<T> implements ToBooleanFunction<T> {
private final Predicate<T> function;
private final Predicate<? super T> function;

public BooleanNot(ToBooleanFunction<T> function) {
public BooleanNot(Predicate<? super T> function) {
this.function = Objects.requireNonNull(function);
}

public Predicate<T> function() {
return function;
}

@Override
public boolean test(T value) {
return !function.test(value);
}

@Override
@NotNull
public ToBooleanFunction<T> negate() {
return of(function);
}
}

private static class BooleanAnd<T> implements ToBooleanFunction<T> {
private final Collection<Predicate<T>> functions;
private final Collection<Predicate<? super T>> functions;

public BooleanAnd(Collection<Predicate<T>> functions) {
public BooleanAnd(Collection<Predicate<? super T>> functions) {
this.functions = List.copyOf(functions);
}

@Override
public boolean test(T value) {
for (Predicate<T> function : functions) {
for (Predicate<? super T> function : functions) {
if (!function.test(value)) {
return false;
}
}
return true;
}

@Override
@NotNull
public ToBooleanFunction<T> negate() {
return new BooleanOr<>(functions.stream().map(Predicate::negate).collect(Collectors.toList()));
}

@Override
@NotNull
public ToBooleanFunction<T> and(@NotNull Predicate<? super T> other) {
// noinspection Convert2Diamond
return new BooleanAnd<T>(Stream.concat(functions.stream(), Stream.of(other)).collect(Collectors.toList()));
}
}

private static class BooleanOr<T> implements ToBooleanFunction<T> {
private final Collection<Predicate<T>> functions;
private final Collection<Predicate<? super T>> functions;

public BooleanOr(Collection<Predicate<T>> functions) {
public BooleanOr(Collection<Predicate<? super T>> functions) {
this.functions = List.copyOf(functions);
}

@Override
public boolean test(T value) {
for (Predicate<T> function : functions) {
for (Predicate<? super T> function : functions) {
if (function.test(value)) {
return true;
}
}
return false;
}

@Override
@NotNull
public ToBooleanFunction<T> negate() {
return new BooleanAnd<>(functions.stream().map(Predicate::negate).collect(Collectors.toList()));
}

@Override
@NotNull
public ToBooleanFunction<T> or(@NotNull Predicate<? super T> other) {
// noinspection Convert2Diamond
return new BooleanOr<T>(Stream.concat(functions.stream(), Stream.of(other)).collect(Collectors.toList()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

class ByteFunctions {
static <T> ToByteFunction<T> cast() {
return cast(PrimitiveByte.INSTANCE);
}

static <T> ToByteFunction<T> cast(ToByteFunction<? super T> f) {
// noinspection unchecked
return (ToByteFunction<T>) PrimitiveByte.INSTANCE;
return (ToByteFunction<T>) f;
}

static <T, R> ToByteFunction<T> map(Function<T, R> f, ToByteFunction<R> g) {
static <T, R> ToByteFunction<T> map(
Function<? super T, ? extends R> f,
ToByteFunction<? super R> g) {
return new ByteMap<>(f, g);
}

Expand All @@ -26,10 +32,10 @@ public byte applyAsByte(Object value) {
}

private static class ByteMap<T, R> implements ToByteFunction<T> {
private final Function<T, R> f;
private final ToByteFunction<R> g;
private final Function<? super T, ? extends R> f;
private final ToByteFunction<? super R> g;

public ByteMap(Function<T, R> f, ToByteFunction<R> g) {
public ByteMap(Function<? super T, ? extends R> f, ToByteFunction<? super R> g) {
this.f = Objects.requireNonNull(f);
this.g = Objects.requireNonNull(g);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

class CharFunctions {
static <T> ToCharFunction<T> cast() {
return cast(PrimitiveChar.INSTANCE);
}

static <T> ToCharFunction<T> cast(ToCharFunction<? super T> f) {
// noinspection unchecked
return (ToCharFunction<T>) PrimitiveChar.INSTANCE;
return (ToCharFunction<T>) f;
}

static <T, R> ToCharFunction<T> map(Function<T, R> f, ToCharFunction<R> g) {
static <T, R> ToCharFunction<T> map(
Function<? super T, ? extends R> f,
ToCharFunction<? super R> g) {
return new CharMap<>(f, g);
}

Expand All @@ -26,10 +32,10 @@ public char applyAsChar(Object value) {
}

private static class CharMap<T, R> implements ToCharFunction<T> {
private final Function<T, R> f;
private final ToCharFunction<R> g;
private final Function<? super T, ? extends R> f;
private final ToCharFunction<? super R> g;

public CharMap(Function<T, R> f, ToCharFunction<R> g) {
public CharMap(Function<? super T, ? extends R> f, ToCharFunction<? super R> g) {
this.f = Objects.requireNonNull(f);
this.g = Objects.requireNonNull(g);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,23 @@
class DoubleFunctions {

static <T> ToDoubleFunction<T> cast() {
return cast(PrimitiveDouble.INSTANCE);
}

static <T> ToDoubleFunction<T> cast(ToDoubleFunction<? super T> f) {
// noinspection unchecked
return (ToDoubleFunction<T>) PrimitiveDouble.INSTANCE;
return (ToDoubleFunction<T>) f;
}

static <T> ToDoubleFunction<T> of(java.util.function.ToDoubleFunction<T> f) {
return f instanceof ToDoubleFunction ? (ToDoubleFunction<T>) f : f::applyAsDouble;
static <T> ToDoubleFunction<T> of(java.util.function.ToDoubleFunction<? super T> f) {
return f instanceof ToDoubleFunction
? cast((ToDoubleFunction<? super T>) f)
: f::applyAsDouble;
}

static <T, R> ToDoubleFunction<T> map(Function<T, R> f, java.util.function.ToDoubleFunction<R> g) {
static <T, R> ToDoubleFunction<T> map(
Function<? super T, ? extends R> f,
java.util.function.ToDoubleFunction<? super R> g) {
return new DoubleFunctionMap<>(f, g);
}

Expand All @@ -31,10 +39,10 @@ public double applyAsDouble(Object value) {
}

private static class DoubleFunctionMap<T, R> implements ToDoubleFunction<T> {
private final Function<T, R> f;
private final java.util.function.ToDoubleFunction<R> g;
private final Function<? super T, ? extends R> f;
private final java.util.function.ToDoubleFunction<? super R> g;

public DoubleFunctionMap(Function<T, R> f, java.util.function.ToDoubleFunction<R> g) {
public DoubleFunctionMap(Function<? super T, ? extends R> f, java.util.function.ToDoubleFunction<? super R> g) {
this.f = Objects.requireNonNull(f);
this.g = Objects.requireNonNull(g);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

class FloatFunctions {
static <T> ToFloatFunction<T> cast() {
return cast(PrimitiveFloat.INSTANCE);
}

static <T> ToFloatFunction<T> cast(ToFloatFunction<? super T> f) {
// noinspection unchecked
return (ToFloatFunction<T>) PrimitiveFloat.INSTANCE;
return (ToFloatFunction<T>) f;
}

static <T, R> ToFloatFunction<T> map(Function<T, R> f, ToFloatFunction<R> g) {
static <T, R> ToFloatFunction<T> map(
Function<? super T, ? extends R> f,
ToFloatFunction<? super R> g) {
return new FloatMap<>(f, g);
}

Expand All @@ -26,10 +32,10 @@ public float applyAsFloat(Object value) {
}

private static class FloatMap<T, R> implements ToFloatFunction<T> {
private final Function<T, R> f;
private final ToFloatFunction<R> g;
private final Function<? super T, ? extends R> f;
private final ToFloatFunction<? super R> g;

public FloatMap(Function<T, R> f, ToFloatFunction<R> g) {
public FloatMap(Function<? super T, ? extends R> f, ToFloatFunction<? super R> g) {
this.f = Objects.requireNonNull(f);
this.g = Objects.requireNonNull(g);
}
Expand Down
Loading

0 comments on commit 0caa2c7

Please sign in to comment.