Skip to content

Commit c343276

Browse files
committed
GROOVY-11636: Create a SGM#next method which also takes an integer increment value
1 parent a57357e commit c343276

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,50 @@ public static String next(final CharSequence self) {
19811981
return buffer.toString();
19821982
}
19831983

1984+
/**
1985+
* A variant of next with an integer count parameter; equivalent to calling next() count times.
1986+
* <pre class="groovyTestCase">
1987+
* assert 'a'.next(1) == 'a'.next()
1988+
* assert 'a'.next(4) == 'e'
1989+
* assert 'a'.next(0) == 'a'
1990+
* assert 'a'.next(25) == 'z'
1991+
* assert 'A'.next(32) == 'a'
1992+
* assert (0..4).collect('a'::next) == 'a'..'e'
1993+
* assert 'car'.next(2) == 'cat'
1994+
* </pre>
1995+
*
1996+
* @param self a CharSequence
1997+
* @param n how many times to increment
1998+
* @see #next(CharSequence)
1999+
* @return a value obtained by incrementing the toString() of the CharSequence n times
2000+
*
2001+
* @since 5.0.0
2002+
*/
2003+
public static String next(final CharSequence self, int n) {
2004+
if (n < 0) {
2005+
throw new IllegalArgumentException("A negative value for n is not supported");
2006+
}
2007+
if (n == 0) {
2008+
return self.toString();
2009+
}
2010+
StringBuilder buffer = new StringBuilder(self);
2011+
if (buffer.length() == 0) {
2012+
buffer.append(Character.MIN_VALUE);
2013+
} else {
2014+
char last = buffer.charAt(buffer.length() - 1);
2015+
for (; n > 0; n--) {
2016+
if (last == Character.MAX_VALUE) {
2017+
buffer.append(Character.MIN_VALUE);
2018+
last = Character.MIN_VALUE;
2019+
} else {
2020+
last++;
2021+
}
2022+
}
2023+
buffer.setCharAt(buffer.length() - 1, last);
2024+
}
2025+
return buffer.toString();
2026+
}
2027+
19842028
/**
19852029
* Returns a String with linefeeds and carriage returns normalized to linefeeds.
19862030
*
@@ -2228,6 +2272,54 @@ public static String previous(final CharSequence self) {
22282272
return buffer.toString();
22292273
}
22302274

2275+
/**
2276+
* A variant of previous with an integer count parameter; equivalent to calling previous() count times.
2277+
* <pre class="groovyTestCase">
2278+
* assert 'b'.previous(1) == 'b'.previous()
2279+
* assert 'e'.previous(4) == 'a'
2280+
* assert 'a'.previous(0) == 'a'
2281+
* assert 'z'.previous(25) == 'a'
2282+
* assert 'a'.previous(32) == 'A'
2283+
* assert (0..4).collect('z'::previous) == 'z'..'v'
2284+
* assert 'cat'.previous(2) == 'car'
2285+
* </pre>
2286+
*
2287+
* @param self a CharSequence
2288+
* @param n how many times to decrement
2289+
* @see #previous(CharSequence)
2290+
* @return a value obtained by decrementing the toString() of the CharSequence n times
2291+
*
2292+
* @since 5.0.0
2293+
*/
2294+
public static String previous(final CharSequence self, int n) {
2295+
if (n < 0) {
2296+
throw new IllegalArgumentException("A negative value for n is not supported");
2297+
}
2298+
if (n == 0) {
2299+
return self.toString();
2300+
}
2301+
StringBuilder buffer = new StringBuilder(self);
2302+
if (buffer.length() == 0) throw new IllegalArgumentException("the string is empty");
2303+
char last = buffer.charAt(buffer.length() - 1);
2304+
boolean empty = false;
2305+
for (; n > 0; n--) {
2306+
if (empty) throw new IllegalArgumentException("the string became empty while decrementing");
2307+
if (last == Character.MIN_VALUE) {
2308+
buffer.deleteCharAt(buffer.length() - 1);
2309+
empty = buffer.length() == 0;
2310+
if (!empty) {
2311+
last = buffer.charAt(buffer.length() - 1);
2312+
}
2313+
} else {
2314+
last--;
2315+
}
2316+
}
2317+
if (!empty) {
2318+
buffer.setCharAt(buffer.length() - 1, last);
2319+
}
2320+
return buffer.toString();
2321+
}
2322+
22312323
/**
22322324
* Supports the range subscript operator for StringBuffer.
22332325
*

0 commit comments

Comments
 (0)