import java.util.*;
import java.lang.reflect.*;
import java.lang.ref.*;
-import edu.berkeley.sbp.util.*;
import edu.berkeley.sbp.*;
+import edu.berkeley.sbp.util.*;
/** implementation of <tt>Topology</tt> for any class for which there is a mapping to the <tt>int</tt>s */
-public class IntegerTopology<V extends IntegerTopology.IntegerMappable> implements Topology<V> {
+public class IntegerTopology<V> implements Topology<V> {
+
private final Range.Set rs;
-
- public Range.Set getRanges() { return new Range.Set(rs); }
+ private final Functor<V,Integer> f;
- public IntegerTopology() { this(new Range.Set()); }
- public IntegerTopology(V v) { this(v.toInt()); }
- public IntegerTopology(V a, V b) { this(a.toInt(), b.toInt()); }
- public IntegerTopology(int a) { this(a, a); }
- public IntegerTopology(int a, int b) { this(new Range(a, b)); }
- public IntegerTopology(Range r) { this(new Range.Set(r)); }
- public IntegerTopology(Range.Set rs) { this.rs = rs; }
+ private int toInt(V v) { return f==null?((IntegerMappable)v).toInt():f.invoke(v); }
- public Topology<V> fresh() { return new IntegerTopology<V>(); }
- public Topology<V> dup() { return new IntegerTopology<V>(this.rs); }
- public Topology<V> dup(Range.Set rs) { return new IntegerTopology<V>(rs); }
+ public Range.Set getRanges() { return new Range.Set(rs); }
+ public Functor<V,Integer> functor() { return f; }
+
+ public IntegerTopology(Functor<V,Integer> f) { this(f, new Range.Set()); }
+ public IntegerTopology(Functor<V,Integer> f, V a) { this(f, f==null?((IntegerMappable)a).toInt():f.invoke(a)); }
+ public IntegerTopology(Functor<V,Integer> f, V a, V b) { this(f, f==null?((IntegerMappable)a).toInt():f.invoke(a),
+ f==null?((IntegerMappable)b).toInt():f.invoke(b)); }
+ public IntegerTopology(Functor<V,Integer> f, int a) { this(f, a, a); }
+ public IntegerTopology(Functor<V,Integer> f, int a, int b) { this(f, new Range(a, b)); }
+ public IntegerTopology(Functor<V,Integer> f, Range r) { this(f, new Range.Set(r)); }
+ public IntegerTopology(Functor<V,Integer> f, Range.Set rs) {
+ this.rs = rs;
+ this.f = f==null?(this instanceof Functor ? (Functor)this : null):f;
+ }
+
+ public Topology<V> empty() { return new IntegerTopology<V>(f); }
- public void add(Topology<V> t) { rs.add(((IntegerTopology<V>)t).rs); }
- public void remove(Topology<V> t) { rs.remove(((IntegerTopology<V>)t).rs); }
- public void add(V v) { rs.add(v.toInt()); }
- public void remove(V v) { rs.remove(v.toInt()); }
- public boolean contains(V v) { return rs.contains(v.toInt()); }
+ public boolean contains(V v) { return rs.contains(toInt(v)); }
- public Topology<V> complement() { return dup(rs.complement()); }
- public Topology<V> intersect(Topology<V> t) { return dup(rs.intersect(((IntegerTopology<V>)t).rs)); }
- public Topology<V> minus(Topology<V> t) { return dup(rs.intersect(((IntegerTopology<V>)t).rs.complement())); }
- public Topology<V> union(Topology<V> t) { return dup(rs.union(((IntegerTopology<V>)t).rs)); }
- public boolean disjoint(Topology<V> t) { return rs.intersect(((IntegerTopology<V>)t).rs).size()==0; }
- public boolean containsAll(Topology<V> t) { return rs.intersect(((IntegerTopology<V>)t).rs).equals(((IntegerTopology<V>)t).rs); }
+ public Topology<V> complement() { return new IntegerTopology<V>(f, rs.complement()); }
+ public Topology<V> intersect(Topology<V> t) { return new IntegerTopology<V>(f, rs.intersect(((IntegerTopology<V>)t.unwrap()).rs)); }
+ public Topology<V> minus(Topology<V> t) { return new IntegerTopology<V>(f, rs.intersect(((IntegerTopology<V>)t.unwrap()).rs.complement())); }
+ public Topology<V> union(Topology<V> t) { return new IntegerTopology<V>(f, rs.union(((IntegerTopology<V>)t.unwrap()).rs)); }
+ public boolean disjoint(Topology<V> t) { return rs.intersect(((IntegerTopology<V>)t.unwrap()).rs).size()==0; }
+ public boolean containsAll(Topology<V> t) { return rs.containsAll(((IntegerTopology<V>)t.unwrap()).rs); }
+ public Topology<V> unwrap() { return this; }
public int hashCode() { return rs.hashCode(); }
public boolean equals(Object o) { return o!=null && o instanceof IntegerTopology && ((IntegerTopology<V>)o).rs.equals(rs); }
- // FIXME: this is currently char-range specific
- /*
- public String toString() {
- String classname = this.getClass().getName().replace('$', '.');
- if (rs==null) return "new " + classname + "()";
- StringBuffer sb = new StringBuffer();
- sb.append("new ");
- sb.append(classname);
- sb.append("(new Range.Set(new Range[] { ");
- for(Range r : rs) {
- sb.append("new Range(");
- if (r.isMinNegInf() && r.isMaxPosInf()) {
- sb.append("true, true");
- } else if (r.isMinNegInf()) {
- sb.append("true, ");
- sb.append(r.getMax());
- } else if (r.isMaxPosInf()) {
- sb.append(r.getMin());
- sb.append(", true");
- } else {
- sb.append(r.getMin());
- sb.append(", ");
- sb.append(r.getMax());
- }
- sb.append(")");
- }
- sb.append("new Range() }))");
- return sb.toString();
- }
- */
- public static interface IntegerMappable {
- public int toInt();
- }
}