// Java class go.structs.S is a proxy for talking to a Go program.
//   gobind -lang=java structs
//
// File is generated by gobind. Do not edit.
package go.structs;

import go.Seq;

public final class S implements Seq.Proxy {
    static { Structs.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    S(Seq.Ref ref) { this.ref = ref; }
    
    public final native double getX();
    public final native void setX(double v);
    
    public final native double getY();
    public final native void setY(double v);
    
    public native S identity() throws Exception;
    public native double sum();
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof S)) {
            return false;
        }
        S that = (S)o;
        double thisX = getX();
        double thatX = that.getX();
        if (thisX != thatX) {
            return false;
        }
        double thisY = getY();
        double thatY = that.getY();
        if (thisY != thatY) {
            return false;
        }
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {getX(), getY()});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("S").append("{");
        b.append("X:").append(getX()).append(",");
        b.append("Y:").append(getY()).append(",");
        return b.append("}").toString();
    }
}

// Java class go.structs.S2 is a proxy for talking to a Go program.
//   gobind -lang=java structs
//
// File is generated by gobind. Do not edit.
package go.structs;

import go.Seq;

public final class S2 implements Seq.Proxy, I {
    static { Structs.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    S2(Seq.Ref ref) { this.ref = ref; }
    
    public native void m();
    public native String string();
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof S2)) {
            return false;
        }
        S2 that = (S2)o;
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {});
    }
    
    @Override public String toString() {
        return string();
    }
}

// Java class go.structs.I is a proxy for talking to a Go program.
//   gobind -lang=java structs
//
// File is generated by gobind. Do not edit.
package go.structs;

import go.Seq;

public interface I {
    public void m();
    
}

// Java class go.structs.Structs is a proxy for talking to a Go program.
//   gobind -lang=java structs
//
// File is generated by gobind. Do not edit.
package go.structs;

import go.Seq;

public abstract class Structs {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Structs() {} // uninstantiable
    
    // touch is called from other bound packages to initialize this package
    public static void touch() {}
    
    private static native void _init();
    
    private static final class proxyI implements Seq.Proxy, I {
        private final Seq.Ref ref;
        
        @Override public final int incRefnum() {
              int refnum = ref.refnum;
              Seq.incGoRef(refnum);
              return refnum;
        }
        
        proxyI(Seq.Ref ref) { this.ref = ref; }
        
        public native void m();
    }
    
    
    public static native S identity(S s);
    public static native S identityWithError(S s) throws Exception;
}
