package openmods.utils;
public abstract class OptionalInt {
private static final int CACHE_RANGE = 16;
private static class Present extends OptionalInt {
private final int value;
public Present(int value) {
this.value = value;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public int get() {
return value;
}
@Override
public int or(int defaultValue) {
return value;
}
@Override
public boolean compareIfPresent(int value) {
return value == this.value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + value;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Present) {
final Present other = (Present)obj;
return this.value == other.value;
}
return false;
}
@Override
public String toString() {
return "present: " + value;
}
@Override
public OptionalInt map(IntFunction function) {
return new Present(function.apply(value));
}
}
private static class Absent extends OptionalInt {
@Override
public boolean isPresent() {
return false;
}
@Override
public int get() {
throw new IllegalStateException("No value");
}
@Override
public int or(int defaultValue) {
return defaultValue;
}
@Override
public boolean compareIfPresent(int value) {
return true;
}
@Override
public String toString() {
return "absent";
}
@Override
public OptionalInt map(IntFunction function) {
return this;
}
}
private OptionalInt() {}
public abstract boolean isPresent();
public abstract int get();
public abstract int or(int defaultValue);
public abstract boolean compareIfPresent(int value);
public interface IntFunction {
public int apply(int value);
}
public abstract OptionalInt map(IntFunction function);
private static final OptionalInt[] cache = new OptionalInt[CACHE_RANGE * 2 + 1];
public static final OptionalInt ABSENT = new Absent();
static {
for (int i = 0; i < CACHE_RANGE * 2 + 1; i++)
cache[i] = new Present(i - CACHE_RANGE);
}
public static final OptionalInt ZERO = of(0);
public static final OptionalInt ONE = of(1);
public static final OptionalInt TWO = of(2);
public static OptionalInt of(int value) {
if (Math.abs(value) <= CACHE_RANGE) return cache[value + CACHE_RANGE];
return new Present(value);
}
public static OptionalInt fromNullable(Integer value) {
if (value == null) return ABSENT;
return of(value.intValue());
}
public static OptionalInt absent() {
return ABSENT;
}
}