diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java index e5bf058b9e0..0ffa0a99dd2 100644 --- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java +++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java @@ -2022,6 +2022,56 @@ public void remove() { } } + //-------------------------------------------------------------------------- + // clamp + + /** + * Constrains a Comparable value to lie within the inclusive range + * [lower, upper]. Returns lower if self + * is less than lower, upper if self is + * greater than upper, otherwise self. + *
+     * assert 10.clamp(1, 15) == 10
+     * assert 10.clamp(1, 5) == 5
+     * assert 10.clamp(12, 20) == 12
+     * assert 'a'.clamp('b', 'z') == 'b'
+     * 
+ * + * @param self a Comparable value + * @param lower the inclusive lower bound + * @param upper the inclusive upper bound + * @return the clamped value + * @throws IllegalArgumentException if lower is greater than upper + * @since 6.0.0 + */ + public static > T clamp(T self, T lower, T upper) { + if (ScriptBytecodeAdapter.compareGreaterThan(lower, upper)) { + throw new IllegalArgumentException("lower bound (" + lower + ") must not be greater than upper bound (" + upper + ")"); + } + if (ScriptBytecodeAdapter.compareLessThan(self, lower)) return lower; + if (ScriptBytecodeAdapter.compareGreaterThan(self, upper)) return upper; + return self; + } + + /** + * Constrains a Comparable value to lie within the given Range. + *
+     * assert 10.clamp(12..20) == 12
+     * assert 10.clamp(1..5) == 5
+     * 
+ * + * @param self a Comparable value + * @param range a Range defining the inclusive bounds + * @return the clamped value + * @since 6.0.0 + */ + @SuppressWarnings("unchecked") + public static > T clamp(T self, Range range) { + T lower = range.isReverse() ? (T) range.getTo() : (T) range.getFrom(); + T upper = range.isReverse() ? (T) range.getFrom() : (T) range.getTo(); + return clamp(self, lower, upper); + } + //-------------------------------------------------------------------------- // collate