Skip to content

Instantly share code, notes, and snippets.

@gloryofrobots
Last active March 24, 2019 08:05
Show Gist options
  • Save gloryofrobots/5063d4f52b4a263d9704b8b777e61ef4 to your computer and use it in GitHub Desktop.
Save gloryofrobots/5063d4f52b4a263d9704b8b777e61ef4 to your computer and use it in GitHub Desktop.
package draft;
public class GenericValue {
enum Type {INT, DOUBLE};
interface Val {
public String str();
public Type type();
Operations ops();
}
interface Operations<T extends Val> {
T add(T one, T two);
}
////////////////////////////////////////////////////////////////////
class IntOperations implements Operations<IntVal> {
public IntVal add(IntVal one, IntVal two) {
return new IntVal(one.value + two.value);
}
}
class DoubleOperations implements Operations<DoubleVal> {
public DoubleVal add(DoubleVal one, DoubleVal two) {
return new DoubleVal(one.value + two.value);
}
}
////////////////////////////////////////////////////////////////////
class IntVal implements Val{
public int value;
IntVal(int value) {
this.value = value;
}
public String str() {
return Integer.toString(value);
}
public Type type() {
return Type.INT;
}
@Override
public Operations ops() {
return new IntOperations();
}
}
class DoubleVal implements Val {
public double value;
DoubleVal(double value) {
this.value = value;
}
public String str() {
return Double.toString(value);
}
public Type type() {
return Type.DOUBLE;
}
@Override
public Operations ops() {
return new DoubleOperations();
}
}
////////////////////////////////////////////////////////////////////
class Converter{
<T extends Base<T>>T arg1(Base<T> v1, Base<T> v2) {
Type type1 = v1.type();
Type type2 = v2.type();
if (type1 == type2 || type1 == Type.DOUBLE) {
return (T)v1;
}
if (type1 == Type.INT && type2 == Type.DOUBLE) {
IntVal val = (IntVal) v1.getValue();
Val res = new DoubleVal(val.value);
return v1.createValue(res);
} else {
throw new RuntimeException("Invalid types" + v1.type() + " " + v2.type());
}
}
<T extends Base<T>>T arg2(Base<T> v1, Base<T> v2) {
Type type1 = v1.type();
Type type2 = v2.type();
if (type1 == type2 || type2 == Type.DOUBLE) {
return (T) v2;
}
if (type1 == Type.DOUBLE && type2 == Type.INT) {
IntVal val = (IntVal) v2.getValue();
Val res = new DoubleVal(val.value);
return v2.createValue(res);
} else {
throw new RuntimeException("Invalid types" + v1.type() + " " + v2.type());
}
}
}
////////////////////////////////////////////////////////////////////
abstract class Base<T extends Base<T>> {
Val val;
Converter conv = new Converter();
// Operations ops;
public Type type() {
return val.type();
}
Val getValue() {
return val;
}
public void setValue(Val v) {
val = v;
// ops = v.ops();
// Type type = val.type();
// if (type == Type.INT) {
// ops = new IntOperations();
// } else if(type == Type.DOUBLE) {
// ops = new DoubleOperations();
// }
}
abstract T createValue(Val v);
boolean isSameType(T other) {
return type() == other.type();
}
public T add(T other) {
if (!isSameType(other)) {
T A = conv.arg1(this, other);
T B = conv.arg2(this, other);
return A.add(B);
}
Val v = val.ops().add(val, other.val);
return createValue(v);
}
public String toString() {
return val.str();
}
}
////////////////////////////////////////////////////////////////////
class Value extends Base<Value> {
Value(Val v) {
setValue(v);
}
Value createValue(Val v) {
return new Value(v);
}
}
class Value2 extends Base<Value2> {
Value2(Val v) {
setValue(v);
}
Value2 createValue(Val v) {
return new Value2(v);
}
}
////////////////////////////////////////////////////////////////////
public Value doubleValue(double v) {
return new Value(new DoubleVal(v));
}
public Value intValue(int v) {
return new Value(new IntVal(v));
}
public Value2 intValue2(int v) {
return new Value2(new IntVal(v));
}
////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
GenericValue test = new GenericValue();
Value v1 = test.doubleValue(8.056);
Value vi1 = test.intValue(10);
System.out.println(vi1.add(v1));
System.out.println(v1.add(vi1));
System.out.println(vi1.add(vi1));
Value v2 = test.doubleValue(10.2);
Value v3 = v1.add(v2);
System.out.println(v3);
Value2 vi2 = test.intValue2(50);
Value2 vi3 = vi2.add(vi2);
System.out.println(vi3);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment