From 33f145a83ab49a6efffb9a28b3634a82069459fd Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 7 Jan 2012 21:27:20 +0200 Subject: [PATCH] KT-930 upto/downto for numbers --- .../codegen/intrinsics/IntrinsicMethods.java | 7 +- .../intrinsics/{RangeTo.java => UpTo.java} | 13 +- compiler/frontend/src/jet/Numbers.jet | 118 +++- .../testData/codegen/regressions/kt930.kt | 100 ++++ .../jet/codegen/PrimitiveTypesTest.java | 4 + stdlib/src/jet/ByteRange.java | 4 +- stdlib/src/jet/CharRange.java | 4 +- stdlib/src/jet/IntRange.java | 4 +- stdlib/src/jet/LongRange.java | 4 +- stdlib/src/jet/ShortRange.java | 4 +- stdlib/src/jet/runtime/Ranges.java | 557 ++++++++++++++---- 11 files changed, 693 insertions(+), 126 deletions(-) rename compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/{RangeTo.java => UpTo.java} (75%) create mode 100644 compiler/testData/codegen/regressions/kt930.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 2939e4ba879..b57ecfe31cb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -29,7 +29,8 @@ public class IntrinsicMethods { private static final IntrinsicMethod INV = new Inv(); private static final IntrinsicMethod TYPEINFO = new TypeInfo(); private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo(); - private static final IntrinsicMethod RANGE_TO = new RangeTo(); + private static final IntrinsicMethod UP_TO = new UpTo(true); + private static final IntrinsicMethod DOWN_TO = new UpTo(false); private static final IntrinsicMethod INC = new Increment(1); private static final IntrinsicMethod DEC = new Increment(-1); @@ -59,7 +60,9 @@ public class IntrinsicMethods { declareIntrinsicFunction(type, "plus", 0, UNARY_PLUS); declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS); declareIntrinsicFunction(type, "inv", 0, INV); - declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO); + declareIntrinsicFunction(type, "rangeTo", 1, UP_TO); + declareIntrinsicFunction(type, "upto", 1, UP_TO); + declareIntrinsicFunction(type, "downto", 1, DOWN_TO); declareIntrinsicFunction(type, "inc", 0, INC); declareIntrinsicFunction(type, "dec", 0, DEC); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UpTo.java similarity index 75% rename from compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java rename to compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UpTo.java index 3dc18b19361..2b50130eb74 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UpTo.java @@ -14,8 +14,15 @@ import java.util.List; /** * @author yole + * @author alex.tkachman */ -public class RangeTo implements IntrinsicMethod { +public class UpTo implements IntrinsicMethod { + private boolean forward; + + public UpTo(boolean forward) { + this.forward = forward; + } + @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { if(arguments.size()==1) { @@ -23,7 +30,7 @@ public class RangeTo implements IntrinsicMethod { final Type rightType = codegen.expressionType(arguments.get(0)); receiver.put(Type.INT_TYPE, v); codegen.gen(arguments.get(0), rightType); - v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); + v.invokestatic("jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); } else { @@ -33,7 +40,7 @@ public class RangeTo implements IntrinsicMethod { // if (JetTypeMapper.isIntPrimitive(leftType)) { codegen.gen(expression.getLeft(), leftType); codegen.gen(expression.getRight(), rightType); - v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); + v.invokestatic("jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); // } // else { diff --git a/compiler/frontend/src/jet/Numbers.jet b/compiler/frontend/src/jet/Numbers.jet index 21e7265bd66..719bcf2ea52 100644 --- a/compiler/frontend/src/jet/Numbers.jet +++ b/compiler/frontend/src/jet/Numbers.jet @@ -73,6 +73,22 @@ class Double : Number, Comparable { fun rangeTo(other : Byte) : DoubleRange fun rangeTo(other : Char) : DoubleRange + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : DoubleRange + fun upto(other : Long) : DoubleRange + fun upto(other : Int) : DoubleRange + fun upto(other : Short) : DoubleRange + fun upto(other : Byte) : DoubleRange + fun upto(other : Char) : DoubleRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : DoubleRange + fun downto(other : Long) : DoubleRange + fun downto(other : Int) : DoubleRange + fun downto(other : Short) : DoubleRange + fun downto(other : Byte) : DoubleRange + fun downto(other : Char) : DoubleRange + fun inc() : Double fun dec() : Double fun plus() : Double @@ -131,11 +147,27 @@ class Float : Number, Comparable { fun rangeTo(other : Double) : DoubleRange fun rangeTo(other : Float) : FloatRange fun rangeTo(other : Long) : DoubleRange - fun rangeTo(other : Int) : DoubleRange + fun rangeTo(other : Int) : FloatRange fun rangeTo(other : Short) : FloatRange fun rangeTo(other : Byte) : FloatRange fun rangeTo(other : Char) : FloatRange + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : DoubleRange + fun upto(other : Int) : FloatRange + fun upto(other : Short) : FloatRange + fun upto(other : Byte) : FloatRange + fun upto(other : Char) : FloatRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : DoubleRange + fun downto(other : Int) : FloatRange + fun downto(other : Short) : FloatRange + fun downto(other : Byte) : FloatRange + fun downto(other : Char) : FloatRange + fun inc() : Float fun dec() : Float fun plus() : Float @@ -199,6 +231,22 @@ class Long : Number, Comparable { fun rangeTo(other : Byte) : LongRange fun rangeTo(other : Char) : LongRange + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : LongRange + fun upto(other : Int) : LongRange + fun upto(other : Short) : LongRange + fun upto(other : Byte) : LongRange + fun upto(other : Char) : LongRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : LongRange + fun downto(other : Int) : LongRange + fun downto(other : Short) : LongRange + fun downto(other : Byte) : LongRange + fun downto(other : Char) : LongRange + fun inc() : Long fun dec() : Long fun plus() : Long @@ -270,6 +318,22 @@ class Int : Number, Comparable { fun rangeTo(other : Byte) : IntRange fun rangeTo(other : Char) : IntRange + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : LongRange + fun upto(other : Int) : IntRange + fun upto(other : Short) : IntRange + fun upto(other : Byte) : IntRange + fun upto(other : Char) : IntRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : LongRange + fun downto(other : Int) : IntRange + fun downto(other : Short) : IntRange + fun downto(other : Byte) : IntRange + fun downto(other : Char) : IntRange + fun inc() : Int fun dec() : Int fun plus() : Int @@ -341,6 +405,22 @@ class Char : Number, Comparable { fun rangeTo(other : Byte) : CharRange fun rangeTo(other : Char) : CharRange + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : LongRange + fun upto(other : Int) : IntRange + fun upto(other : Short) : ShortRange + fun upto(other : Byte) : CharRange + fun upto(other : Char) : CharRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : LongRange + fun downto(other : Int) : IntRange + fun downto(other : Short) : ShortRange + fun downto(other : Byte) : CharRange + fun downto(other : Char) : CharRange + fun inc() : Char fun dec() : Char fun plus() : Int @@ -402,7 +482,23 @@ class Short : Number, Comparable { fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange fun rangeTo(other : Byte) : ShortRange - fun rangeTo(other : Char) : IntRange + fun rangeTo(other : Char) : ShortRange + + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : LongRange + fun upto(other : Int) : IntRange + fun upto(other : Short) : ShortRange + fun upto(other : Byte) : ShortRange + fun upto(other : Char) : ShortRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : LongRange + fun downto(other : Int) : IntRange + fun downto(other : Short) : ShortRange + fun downto(other : Byte) : ShortRange + fun downto(other : Char) : ShortRange fun inc() : Short fun dec() : Short @@ -465,7 +561,23 @@ class Byte : Number, Comparable { fun rangeTo(other : Int) : IntRange fun rangeTo(other : Short) : ShortRange fun rangeTo(other : Byte) : ByteRange - fun rangeTo(other : Char) : IntRange + fun rangeTo(other : Char) : CharRange + + fun upto(other : Double) : DoubleRange + fun upto(other : Float) : FloatRange + fun upto(other : Long) : LongRange + fun upto(other : Int) : IntRange + fun upto(other : Short) : ShortRange + fun upto(other : Byte) : ByteRange + fun upto(other : Char) : CharRange + + fun downto(other : Double) : DoubleRange + fun downto(other : Float) : FloatRange + fun downto(other : Long) : LongRange + fun downto(other : Int) : IntRange + fun downto(other : Short) : ShortRange + fun downto(other : Byte) : ByteRange + fun downto(other : Char) : CharRange fun inc() : Byte fun dec() : Byte diff --git a/compiler/testData/codegen/regressions/kt930.kt b/compiler/testData/codegen/regressions/kt930.kt new file mode 100644 index 00000000000..e175b3fb5cf --- /dev/null +++ b/compiler/testData/codegen/regressions/kt930.kt @@ -0,0 +1,100 @@ +fun testInt () : String { + val r1 = 1 upto 4 + if(r1.end != 4 || r1.isReversed || r1.size != 4) return "int upto fail" + + val r2 = 4 upto 1 + if(r2.start != 0 || r2.size != 0) return "int negative upto fail" + + val r3 = 5 downto 0 + if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "int downto fail" + + val r4 = 5 downto 6 + if(r4.start != 0 || r4.end != 0 || !r3.isReversed || r4.size != 0) return "int negative downto fail" + + return "OK" +} + +fun testByte () : String { + val r1 = 1.byt upto 4.byt + if(r1.end != 4.byt || r1.isReversed || r1.size != 4) return "byte upto fail" + + val r2 = 4.byt upto 1.byt + if(r2.start != 0.byt || r2.size != 0) return "byte negative upto fail" + + val r3 = 5.byt downto 0.byt + if(r3.start != 5.byt || r3.end != 0.byt || !r3.isReversed || r3.size != 6) return "byte downto fail" + + val r4 = 5.byt downto 6.byt + if(r4.start != 0.byt || r4.end != 0.byt || !r3.isReversed || r4.size != 0) return "byte negative downto fail" + + return "OK" +} + +fun testShort () : String { + + val r1 = 1.sht upto 4.sht + if(r1.end != 4.sht || r1.isReversed || r1.size != 4) return "short upto fail" + + val r2 = 4.sht upto 1.sht + if(r2.start != 0.sht || r2.size != 0) return "short negative upto fail" + + val r3 = 5.sht downto 0.sht + if(r3.start != 5.sht || r3.end != 0.sht || !r3.isReversed || r3.size != 6) return "short downto fail" + + val r4 = 5.sht downto 6.sht + if(r4.start != 0.sht || r4.end != 0.sht || !r3.isReversed || r4.size != 0) return "short negative downto fail" + + return "OK" +} + +fun testLong () : String { + + val r1 = 1.lng upto 4.lng + if(r1.end != 4.lng || r1.isReversed || r1.size != 4.lng) return "long upto fail" + + val r2 = 4.lng upto 1.lng + if(r2.start != 0.lng || r2.size != 0.lng) return "short negative long fail" + + val r3 = 5.lng downto 0.lng + if(r3.start != 5.lng || r3.end != 0.lng || !r3.isReversed || r3.size != 6.lng) return "long downto fail" + + val r4 = 5.lng downto 6.lng + if(r4.start != 0.lng || r4.end != 0.lng || !r3.isReversed || r4.size != 0.lng) return "long negative downto fail" + + return "OK" +} + +fun testChar () : String { + + val r1 = 'a' upto 'd' + if(r1.end != 'd' || r1.isReversed || r1.size != 4) return "char upto fail" + + val r2 = 'd' upto 'a' + if(r2.start != 0.chr || r2.size != 0) return "char negative long fail" + + val r3 = 'd' downto 'a' + if(r3.start != 'd' || r3.end != 'a' || !r3.isReversed || r3.size != 4) return "char downto fail" + + val r4 = 'a' downto 'd' + if(r4.start != 0.chr || r4.end != 0.chr || !r3.isReversed || r4.size != 0) return "char negative downto fail" + + return "OK" +} + +fun box() : String { + var r : String + + r = testInt() + if(r != "OK") return r + + r = testByte() + if(r != "OK") return r + + r = testShort() + if(r != "OK") return r + + r = testLong() + if(r != "OK") return r + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index 261e4450425..0863a06d713 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -375,4 +375,8 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testKt765 () { blackBoxFile("regressions/kt765.kt"); } + + public void testKt930 () { + blackBoxFile("regressions/kt930.kt"); + } } diff --git a/stdlib/src/jet/ByteRange.java b/stdlib/src/jet/ByteRange.java index bb81716170e..454691a69e2 100644 --- a/stdlib/src/jet/ByteRange.java +++ b/stdlib/src/jet/ByteRange.java @@ -6,6 +6,8 @@ public final class ByteRange implements Range, ByteIterable, JetObject { private final byte start; private final int count; + public static final ByteRange empty = new ByteRange((byte) 0,0); + public ByteRange(byte startValue, int count) { this.start = startValue; this.count = count; @@ -29,7 +31,7 @@ public final class ByteRange implements Range, ByteIterable, JetObject { } public byte getEnd() { - return (byte) (count < 0 ? start + count + 1: start+count-1); + return (byte) (count < 0 ? start + count + 1: count == 0 ? 0 : start+count-1); } public int getSize() { diff --git a/stdlib/src/jet/CharRange.java b/stdlib/src/jet/CharRange.java index f7721fb9140..4c6ed5d46f6 100644 --- a/stdlib/src/jet/CharRange.java +++ b/stdlib/src/jet/CharRange.java @@ -6,6 +6,8 @@ public final class CharRange implements Range, CharIterable, JetObjec private final char start; private final int count; + public static final CharRange empty = new CharRange((char) 0,0); + public CharRange(char startValue, int count) { this.start = startValue; this.count = count; @@ -29,7 +31,7 @@ public final class CharRange implements Range, CharIterable, JetObjec } public char getEnd() { - return (char) (count < 0 ? start + count + 1: start+count-1); + return (char) (count < 0 ? start + count + 1: count == 0 ? 0 : start+count-1); } public int getSize() { diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 68d127ded00..fbc671d39c4 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -6,6 +6,8 @@ public final class IntRange implements Range, IntIterable, JetObject { private final int start; private final int count; + public static final IntRange empty = new IntRange(0,0); + public IntRange(int startValue, int count) { this.start = startValue; this.count = count; @@ -36,7 +38,7 @@ public final class IntRange implements Range, IntIterable, JetObject { } public int getEnd() { - return count < 0 ? start + count + 1: start+count-1; + return count < 0 ? start + count + 1: count == 0 ? 0 : start+count-1; } public int getSize() { diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index 50cf408d53f..2494241dc95 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -6,6 +6,8 @@ public final class LongRange implements Range, LongIterable, JetObject { private final long start; private final long count; + public static final LongRange empty = new LongRange(0L,0L); + public LongRange(long startValue, long count) { this.start = startValue; this.count = count; @@ -36,7 +38,7 @@ public final class LongRange implements Range, LongIterable, JetObject { } public long getEnd() { - return start+count-1; + return count < 0 ? start + count + 1: count == 0 ? 0 : start+count-1; } public long getSize() { diff --git a/stdlib/src/jet/ShortRange.java b/stdlib/src/jet/ShortRange.java index b00fab53562..dcddf605be1 100644 --- a/stdlib/src/jet/ShortRange.java +++ b/stdlib/src/jet/ShortRange.java @@ -6,6 +6,8 @@ public final class ShortRange implements Range, ShortIterable, JetObject private final short start; private final int count; + public static final ShortRange empty = new ShortRange((short) 0,0); + public ShortRange(short startValue, int count) { this.start = startValue; this.count = count; @@ -36,7 +38,7 @@ public final class ShortRange implements Range, ShortIterable, JetObject } public short getEnd() { - return (short) (count < 0 ? start + count + 1: start+count-1); + return (short) (count < 0 ? start + count + 1: count == 0 ? 0 : start+count-1); } public int getSize() { diff --git a/stdlib/src/jet/runtime/Ranges.java b/stdlib/src/jet/runtime/Ranges.java index ff5952afe03..6121ea90a84 100644 --- a/stdlib/src/jet/runtime/Ranges.java +++ b/stdlib/src/jet/runtime/Ranges.java @@ -12,327 +12,647 @@ public class Ranges { private Ranges() { } - public static ByteRange rangeTo(byte from, byte to) { + public static ByteRange upTo(byte from, byte to) { if(from > to) { - return new ByteRange(from, to-from-1); + return ByteRange.empty; } else { return new ByteRange(from, to-from+1); } } - public static ShortRange rangeTo(byte from, short to) { + public static ByteRange downTo(byte from, byte to) { if(from > to) { - return new ShortRange(from, to-from-1); + return new ByteRange(from, to-from-1); + } + else { + return ByteRange.empty; + } + } + + public static ShortRange upTo(byte from, short to) { + if(from > to) { + return ShortRange.empty; } else { return new ShortRange(from, to-from+1); } } - public static IntRange rangeTo(byte from, int to) { + public static ShortRange downTo(byte from, short to) { if(from > to) { - return new IntRange(from, to-from-1); + return new ShortRange(from, to-from-1); + } + else { + return ShortRange.empty; + } + } + + public static IntRange upTo(byte from, int to) { + if(from > to) { + return IntRange.empty; } else { return new IntRange(from, to-from+1); } } - public static LongRange rangeTo(byte from, long to) { + public static IntRange downTo(byte from, int to) { if(from > to) { - return new LongRange(from, to-from-1); + return new IntRange(from, to-from-1); + } + else { + return IntRange.empty; + } + } + + public static LongRange upTo(byte from, long to) { + if(from > to) { + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(byte from, float to) { + public static LongRange downTo(byte from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(byte from, float to) { return new FloatRange(from, to-from); } - public static DoubleRange rangeTo(byte from, double to) { + public static FloatRange downTo(byte from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(byte from, double to) { return new DoubleRange(from, to-from); } - public static CharRange rangeTo(byte from, char to) { + public static DoubleRange downTo(byte from, double to) { + return new DoubleRange(from, to-from); + } + + public static CharRange upTo(byte from, char to) { if(from > to) { - return new CharRange((char) from, to-from-1); + return CharRange.empty; } else { return new CharRange((char) from, to-from+1); } } - public static ShortRange rangeTo(short from, byte to) { + public static CharRange downTo(byte from, char to) { if(from > to) { - return new ShortRange(from, to-from-1); + return new CharRange((char) from, to-from-1); + } + else { + return CharRange.empty; + } + } + + public static ShortRange upTo(short from, byte to) { + if(from > to) { + return ShortRange.empty; } else { return new ShortRange(from, to-from+1); } } - public static ShortRange rangeTo(short from, short to) { + public static ShortRange downTo(short from, byte to) { if(from > to) { return new ShortRange(from, to-from-1); } + else { + return ShortRange.empty; + } + } + + public static ShortRange upTo(short from, short to) { + if(from > to) { + return ShortRange.empty; + } else { return new ShortRange(from, to-from+1); } } - public static IntRange rangeTo(short from, int to) { + public static ShortRange downTo(short from, short to) { if(from > to) { - return new IntRange(from, to-from-1); + return new ShortRange(from, to-from-1); + } + else { + return ShortRange.empty; + } + } + + public static IntRange upTo(short from, int to) { + if(from > to) { + return IntRange.empty; } else { return new IntRange(from, to-from+1); } } - public static LongRange rangeTo(short from, long to) { + public static IntRange downTo(short from, int to) { if(from > to) { - return new LongRange(from, to-from-1); + return new IntRange(from, to-from-1); + } + else { + return IntRange.empty; + } + } + + public static LongRange upTo(short from, long to) { + if(from > to) { + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(short from, float to) { + public static LongRange downTo(short from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(short from, float to) { return new FloatRange(from, to-from); } - public static DoubleRange rangeTo(short from, double to) { + public static FloatRange downTo(short from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(short from, double to) { return new DoubleRange(from, to-from); } - public static ShortRange rangeTo(short from, char to) { + public static DoubleRange downTo(short from, double to) { + return new DoubleRange(from, to-from); + } + + public static ShortRange upTo(short from, char to) { if(from > to) { - return new ShortRange(from, to-from-1); + return ShortRange.empty; } else { return new ShortRange(from, to-from+1); } } - public static IntRange rangeTo(int from, byte to) { + public static ShortRange downTo(short from, char to) { if(from > to) { - return new IntRange(from, to-from-1); + return new ShortRange(from, to-from-1); + } + else { + return ShortRange.empty; + } + } + + public static IntRange upTo(int from, byte to) { + if(from > to) { + return IntRange.empty; } else { return new IntRange(from, to-from+1); } } - public static IntRange rangeTo(int from, short to) { + public static IntRange downTo(int from, byte to) { if(from > to) { return new IntRange(from, to-from-1); } + else { + return IntRange.empty; + } + } + + public static IntRange upTo(int from, short to) { + if(from > to) { + return IntRange.empty; + } else { return new IntRange(from, to-from+1); } } - public static IntRange rangeTo(int from, int to) { + public static IntRange downTo(int from, short to) { if(from > to) { return new IntRange(from, to-from-1); } + else { + return IntRange.empty; + } + } + + public static IntRange upTo(int from, int to) { + if(from > to) { + return IntRange.empty; + } else { return new IntRange(from, to-from+1); } } - public static LongRange rangeTo(int from, long to) { + public static IntRange downTo(int from, int to) { if(from > to) { - return new LongRange(from, to-from-1); + return new IntRange(from, to-from-1); + } + else { + return IntRange.empty; + } + } + + public static LongRange upTo(int from, long to) { + if(from > to) { + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(int from, float to) { + public static LongRange downTo(int from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(int from, float to) { return new FloatRange(from, to-from); } - public static DoubleRange rangeTo(int from, double to) { + public static FloatRange downTo(int from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(int from, double to) { return new DoubleRange(from, to-from); } - public static IntRange rangeTo(int from, char to) { + public static DoubleRange downTo(int from, double to) { + return new DoubleRange(from, to-from); + } + + public static IntRange upTo(int from, char to) { if(from > to) { - return new IntRange(from, to-from-1); + return IntRange.empty; } else { return new IntRange(from, to-from+1); } } - public static LongRange rangeTo(long from, byte to) { + public static IntRange downTo(int from, char to) { if(from > to) { - return new LongRange(from, to-from-1); + return new IntRange(from, to-from-1); + } + else { + return IntRange.empty; + } + } + + public static LongRange upTo(long from, byte to) { + if(from > to) { + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static LongRange rangeTo(long from, short to) { + public static LongRange downTo(long from, byte to) { if(from > to) { return new LongRange(from, to-from-1); } + else { + return LongRange.empty; + } + } + + public static LongRange upTo(long from, short to) { + if(from > to) { + return LongRange.empty; + } else { return new LongRange(from, to-from+1); } } - public static LongRange rangeTo(long from, int to) { + public static LongRange downTo(long from, short to) { if(from > to) { return new LongRange(from, to-from-1); } + else { + return LongRange.empty; + } + } + + public static LongRange upTo(long from, int to) { + if(from > to) { + return LongRange.empty; + } else { return new LongRange(from, to-from+1); } } - public static LongRange rangeTo(long from, long to) { + public static LongRange downTo(long from, int to) { if(from > to) { return new LongRange(from, to-from-1); } + else { + return LongRange.empty; + } + } + + public static LongRange upTo(long from, long to) { + if(from > to) { + return LongRange.empty; + } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(long from, float to) { + public static LongRange downTo(long from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(long from, float to) { return new FloatRange(from, to-from); } - public static DoubleRange rangeTo(long from, double to) { + public static FloatRange downTo(long from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(long from, double to) { return new DoubleRange(from, to-from); } - public static LongRange rangeTo(long from, char to) { + public static DoubleRange downTo(long from, double to) { + return new DoubleRange(from, to-from); + } + + public static LongRange upTo(long from, char to) { if(from > to) { - return new LongRange(from, to-from-1); + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(float from, byte to) { - return new FloatRange(from, to-from); - } - - public static FloatRange rangeTo(float from, short to) { - return new FloatRange(from, to-from); - } - - public static FloatRange rangeTo(float from, int to) { - return new FloatRange(from, to-from); - } - - public static FloatRange rangeTo(float from, long to) { - return new FloatRange(from, to-from); - } - - public static FloatRange rangeTo(float from, float to) { - return new FloatRange(from, to-from); - } - - public static DoubleRange rangeTo(float from, double to) { - return new DoubleRange(from, to-from); - } - - public static FloatRange rangeTo(float from, char to) { - return new FloatRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, byte to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, short to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, int to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, long to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, float to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, double to) { - return new DoubleRange(from, to-from); - } - - public static DoubleRange rangeTo(double from, char to) { - return new DoubleRange(from, to-from); - } - - public static CharRange rangeTo(char from, byte to) { + public static LongRange downTo(long from, char to) { if(from > to) { - return new CharRange(from, to-from-1); + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(float from, byte to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, byte to) { + return new FloatRange(from, to-from); + } + + public static FloatRange upTo(float from, short to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, short to) { + return new FloatRange(from, to-from); + } + + public static FloatRange upTo(float from, int to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, int to) { + return new FloatRange(from, to-from); + } + + public static FloatRange upTo(float from, long to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, long to) { + return new FloatRange(from, to-from); + } + + public static FloatRange upTo(float from, float to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(float from, double to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(float from, double to) { + return new DoubleRange(from, to-from); + } + + public static FloatRange upTo(float from, char to) { + return new FloatRange(from, to-from); + } + + public static FloatRange downTo(float from, char to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(double from, byte to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, byte to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, short to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, short to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, int to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, int to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, long to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, long to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, float to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, float to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, double to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, double to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange upTo(double from, char to) { + return new DoubleRange(from, to-from); + } + + public static DoubleRange downTo(double from, char to) { + return new DoubleRange(from, to-from); + } + + public static CharRange upTo(char from, byte to) { + if(from > to) { + return CharRange.empty; } else { return new CharRange(from, to-from+1); } } - public static ShortRange rangeTo(char from, short to) { + public static CharRange downTo(char from, byte to) { if(from > to) { - return new ShortRange((short) from, to-from-1); + return new CharRange(from, to-from-1); + } + else { + return CharRange.empty; + } + } + + public static ShortRange upTo(char from, short to) { + if(from > to) { + return ShortRange.empty; } else { return new ShortRange((short) from, to-from+1); } } - public static IntRange rangeTo(char from, int to) { + public static ShortRange downTo(char from, short to) { if(from > to) { - return new IntRange(from, to-from-1); + return new ShortRange((short) from, to-from-1); + } + else { + return ShortRange.empty; + } + } + + public static IntRange upTo(char from, int to) { + if(from > to) { + return IntRange.empty; } else { return new IntRange(from, to-from+1); } } - public static LongRange rangeTo(char from, long to) { + public static IntRange downTo(char from, int to) { if(from > to) { - return new LongRange(from, to-from-1); + return new IntRange(from, to-from-1); + } + else { + return IntRange.empty; + } + } + + public static LongRange upTo(char from, long to) { + if(from > to) { + return LongRange.empty; } else { return new LongRange(from, to-from+1); } } - public static FloatRange rangeTo(char from, float to) { + public static LongRange downTo(char from, long to) { + if(from > to) { + return new LongRange(from, to-from-1); + } + else { + return LongRange.empty; + } + } + + public static FloatRange upTo(char from, float to) { return new FloatRange(from, to-from); } - public static DoubleRange rangeTo(char from, double to) { + public static FloatRange downTo(char from, float to) { + return new FloatRange(from, to-from); + } + + public static DoubleRange upTo(char from, double to) { return new DoubleRange(from, to-from); } - public static CharRange rangeTo(char from, char to) { + public static DoubleRange downTo(char from, double to) { + return new DoubleRange(from, to-from); + } + + public static CharRange upTo(char from, char to) { if(from > to) { - return new CharRange(from, to-from-1); + return CharRange.empty; } else { return new CharRange(from, to-from+1); } } + public static CharRange downTo(char from, char to) { + if(from > to) { + return new CharRange(from, to-from-1); + } + else { + return CharRange.empty; + } + } public static void main(String[] args) { List strings = Arrays.asList("byte", "short", "int", "long", "float", "double", "char"); for(String t1 : strings) @@ -361,17 +681,28 @@ public class Ranges { } if(resType.equals("FloatRange") || resType.equals("DoubleRange")) { - System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {\n" + + System.out.println("\npublic static " + resType + " upTo(" + t1 + " from, " + t2 + " to) {\n" + + " return new " + resType + "(from, to-from);\n" + + "}"); + System.out.println("\npublic static " + resType + " downTo(" + t1 + " from, " + t2 + " to) {\n" + " return new " + resType + "(from, to-from);\n" + "}"); } else { - System.out.println("\npublic static " + resType + " rangeTo(" + t1 + " from, " + t2 + " to) {" + + System.out.println("\npublic static " + resType + " upTo(" + t1 + " from, " + t2 + " to) {" + + "\n if(from > to) {\n" + + " return " + resType + ".empty;\n" + + " }\n" + + " else {\n" + + " return new " + resType + "(from, to-from+1);\n" + + " }\n" + + "}"); + System.out.println("\npublic static " + resType + " downTo(" + t1 + " from, " + t2 + " to) {" + "\n if(from > to) {\n" + " return new " + resType + "(from, to-from-1);\n" + " }\n" + " else {\n" + - " return new " + resType + "(from, to-from+1);\n" + + " return " + resType + ".empty;\n" + " }\n" + "}"); }