You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2021/04/12 09:23:22 UTC

[groovy] 05/25: GROOVY-9649: Started implementing left- and full-open range support for NumberRange.

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit f571a25c0117247af7bfb96072e69a049af25dc3
Author: Iiro Kiviluoma <ii...@outlook.com>
AuthorDate: Sat Apr 3 15:34:28 2021 +0300

    GROOVY-9649: Started implementing left- and full-open range support for NumberRange.
---
 src/main/java/groovy/lang/NumberRange.java         | 64 +++++++++++++++++++---
 .../groovy/runtime/ScriptBytecodeAdapter.java      |  2 +-
 2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/src/main/java/groovy/lang/NumberRange.java b/src/main/java/groovy/lang/NumberRange.java
index 11f2ab3..eb41699 100644
--- a/src/main/java/groovy/lang/NumberRange.java
+++ b/src/main/java/groovy/lang/NumberRange.java
@@ -91,6 +91,16 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
     private final boolean inclusive;
 
     /**
+     * <code>true</code> if the range includes the lower bound.
+     */
+    private final boolean inclusiveLeft;
+
+    /**
+     * <code>true</code> if the range includes the upper bound.
+     */
+    private final boolean inclusiveRight;
+
+    /**
      * Creates an inclusive {@link NumberRange} with step size 1.
      * Creates a reversed range if <code>from</code> &lt; <code>to</code>.
      *
@@ -99,7 +109,7 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
      */
     public <T extends Number & Comparable, U extends Number & Comparable>
     NumberRange(T from, U to) {
-        this(from, to, null, true);
+        this(from, to, null, true, true);
     }
 
     /**
@@ -112,7 +122,7 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
      */
     public <T extends Number & Comparable, U extends Number & Comparable>
     NumberRange(T from, U to, boolean inclusive) {
-        this(from, to, null, inclusive);
+        this(from, to, null, true, inclusive);
     }
 
     /**
@@ -126,7 +136,7 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
     public <T extends Number & Comparable, U extends Number & Comparable, V extends
             Number & Comparable<? super Number>>
     NumberRange(T from, U to, V stepSize) {
-        this(from, to, stepSize, true);
+        this(from, to, stepSize, true, true);
     }
 
     /**
@@ -136,11 +146,42 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
      * @param from start of the range
      * @param to   end of the range
      * @param stepSize the gap between discrete elements in the range
-     * @param inclusive whether the range is inclusive
+     * @param inclusive whether the range is inclusive (upper bound)
      */
     public <T extends Number & Comparable, U extends Number & Comparable, V extends
             Number & Comparable>
     NumberRange(T from, U to, V stepSize, boolean inclusive) {
+        this(from, to, stepSize, true, inclusive);
+    }
+
+    /**
+     * Creates a {@link NumberRange}.
+     * Creates a reversed range if <code>from</code> &lt; <code>to</code>.
+     *
+     * @param from start of the range
+     * @param to   end of the range
+     * @param inclusiveLeft whether the range is includes the lower bound
+     * @param inclusiveRight whether the range is includes the upper bound
+     */
+    public <T extends Number & Comparable, U extends Number & Comparable, V extends
+            Number & Comparable>
+    NumberRange(T from, U to, boolean inclusiveLeft, boolean inclusiveRight) {
+        this(from, to, null, inclusiveLeft, inclusiveRight);
+    }
+
+    /**
+     * Creates a {@link NumberRange}.
+     * Creates a reversed range if <code>from</code> &lt; <code>to</code>.
+     *
+     * @param from start of the range
+     * @param to   end of the range
+     * @param stepSize the gap between discrete elements in the range
+     * @param inclusiveLeft whether the range is includes the lower bound
+     * @param inclusiveRight whether the range is includes the upper bound
+     */
+    public <T extends Number & Comparable, U extends Number & Comparable, V extends
+            Number & Comparable>
+    NumberRange(T from, U to, V stepSize, boolean inclusiveLeft, boolean inclusiveRight) {
         if (from == null) {
             throw new IllegalArgumentException("Must specify a non-null value for the 'from' index in a Range");
         }
@@ -177,7 +218,9 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
         this.from = (Comparable) tempFrom;
         this.to = (Comparable) tempTo;
         this.stepSize = stepSize == null ? 1 : stepSize;
-        this.inclusive = inclusive;
+        this.inclusive = inclusiveRight;
+        this.inclusiveLeft = inclusiveLeft;
+        this.inclusiveRight = inclusiveRight;
     }
 
     /**
@@ -409,6 +452,7 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
         return size;
     }
 
+    // TODO: Update to work with inclusiveLeft! (GROOVY-9649)
     void calcSize(Comparable from, Comparable to, Number stepSize) {
         int tempsize = 0;
         boolean shortcut = false;
@@ -504,7 +548,8 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
     }
 
     private String getToString(String toText, String fromText) {
-        String sep = inclusive ? ".." : "..<";
+        String sepLeft = inclusiveLeft ? ".." : "<..";
+        String sep = inclusiveRight ? sepLeft : sepLeft + "<";
         String base = reverse ? "" + toText + sep + fromText : "" + fromText + sep + toText;
         return Integer.valueOf(1).equals(stepSize) ? base : base + ".by(" + stepSize + ")";
     }
@@ -580,8 +625,8 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
         public boolean hasNext() {
             fetchNextIfNeeded();
             return (next != null) && (isAscending
-                    ? (range.inclusive ? compareLessThanEqual(next, range.getTo()) : compareLessThan(next, range.getTo()))
-                    : (range.inclusive ? compareGreaterThanEqual(next, range.getFrom()) : compareGreaterThan(next, range.getFrom())));
+                    ? (range.inclusiveRight ? compareLessThanEqual(next, range.getTo()) : compareLessThan(next, range.getTo()))
+                    : (range.inclusiveRight ? compareGreaterThanEqual(next, range.getFrom()) : compareGreaterThan(next, range.getFrom())));
         }
 
         @Override
@@ -602,6 +647,9 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
                 if (next == null) {
                     // make the first fetch lazy too
                     next = isAscending ? range.getFrom() : range.getTo();
+                    if (!range.inclusiveLeft) {
+                        next = next();
+                    }
                 } else {
                     next = isAscending ? increment(next, step) : decrement(next, step);
                 }
diff --git a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
index a273c61..5041862 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
@@ -648,7 +648,7 @@ public class ScriptBytecodeAdapter {
             return new EmptyRange((Comparable) from);
         }
         if (from instanceof Number && to instanceof Number) {
-            return new NumberRange(comparableNumber((Number) from), comparableNumber((Number) to), inclusive);
+            return new NumberRange(comparableNumber((Number) from), comparableNumber((Number) to), !exclusiveLeft, !exclusiveRight);
         }
         if (!inclusive) {
             if (compareGreaterThan(from, to)) {