Skip to content

Commit

Permalink
Add support for case-insensitive parsing to ConfigurableDoubleParser.
Browse files Browse the repository at this point in the history
wrandelshofer committed Oct 15, 2024
1 parent 227fe15 commit e692134
Showing 12 changed files with 382 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -22,24 +22,24 @@ abstract class AbstractConfigurableFloatingPointBitsFromCharArray extends Abstra
private final CharSet exponentSeparatorChar;
private final CharTrie exponentSeparatorTrie;

public AbstractConfigurableFloatingPointBitsFromCharArray(NumberFormatSymbols symbols) {
this.decimalSeparator = CharSet.copyOf(symbols.decimalSeparator());
this.groupingSeparator = CharSet.copyOf(symbols.groupingSeparator());
public AbstractConfigurableFloatingPointBitsFromCharArray(NumberFormatSymbols symbols, boolean ignoreCase) {
this.decimalSeparator = CharSet.copyOf(symbols.decimalSeparator(), ignoreCase);
this.groupingSeparator = CharSet.copyOf(symbols.groupingSeparator(), ignoreCase);
this.zeroChar = symbols.zeroDigit();
this.minusSignChar = CharSet.copyOf(symbols.minusSign());
this.exponentSeparatorChar = CharSet.copyOfFirstChar(symbols.exponentSeparator());
this.exponentSeparatorTrie = CharTrie.of(symbols.exponentSeparator());
this.plusSignChar = CharSet.copyOf(symbols.plusSign());
this.nanTrie = CharTrie.of(symbols.nan());
this.infinityTrie = CharTrie.of(symbols.infinity());
this.minusSignChar = CharSet.copyOf(symbols.minusSign(), ignoreCase);
this.exponentSeparatorChar = CharSet.copyOfFirstChar(symbols.exponentSeparator(), ignoreCase);
this.exponentSeparatorTrie = CharTrie.of(symbols.exponentSeparator(), ignoreCase);
this.plusSignChar = CharSet.copyOf(symbols.plusSign(), ignoreCase);
this.nanTrie = CharTrie.of(symbols.nan(), ignoreCase);
this.infinityTrie = CharTrie.of(symbols.infinity(), ignoreCase);
Set<Character> nanOrInfinitySet = new LinkedHashSet<>();
for (String s : symbols.nan()) {
nanOrInfinitySet.add(s.charAt(0));
}
for (String s : symbols.infinity()) {
nanOrInfinitySet.add(s.charAt(0));
}
nanOrInfinityChar = CharSet.copyOf(nanOrInfinitySet);
nanOrInfinityChar = CharSet.copyOf(nanOrInfinitySet, ignoreCase);
}

/**
@@ -224,21 +224,63 @@ private boolean isPlusSign(char c) {


protected CharSequence filterInputString(char[] str, int startIndex, int endIndex) {
StringBuilder b = new StringBuilder(endIndex - startIndex);
for (int i = startIndex; i < endIndex; i++) {
char ch = str[i];
StringBuilder buf = new StringBuilder(endIndex - startIndex);

// Filter leading format characters
// -------------------
int index = skipFormatCharacters(str, startIndex, endIndex);
char ch = str[index];

// Filter optional sign
// -------------------
final boolean isNegative = isMinusSign(ch);
if (isNegative) buf.append('-');
if (isNegative || isPlusSign(ch)) {
++index;
}

// We do not need to parse NaN or Infinity, this case has already been processed

// Parse significand
for (; index < endIndex; index++) {
ch = str[index];
int digit = (char) (ch - zeroChar);
if (digit < 10) {
b.append((char) (digit + '0'));
} else if (isMinusSign(ch)) {
b.append('-');
buf.append((char) (digit + '0'));
} else if (isDecimalSeparator(ch)) {
b.append('.');
} else if (isExponentSeparator(ch)) {
b.append('e');
buf.append('.');
} else if (!isGroupingSeparator(ch)) {
break;
}

}
return b;

// Parse exponent number
// ---------------------
int count = exponentSeparatorTrie.match(str, index, endIndex);
if (count > 0) {
buf.append('e');
index += count;
index = skipFormatCharacters(str, index, endIndex);
ch = charAt(str, index, endIndex);
boolean isExponentNegative = isMinusSign(ch);
if (isExponentNegative) {
buf.append('-');
}
if (isExponentNegative || isPlusSign(ch)) {
++index;
}
ch = str[index];
int digit = (char) (ch - zeroChar);
do {
buf.append((char) (digit + '0'));
ch = charAt(str, ++index, endIndex);
digit = (char) (ch - zeroChar);
} while (digit < 10);
}


return buf;
}

/**
Original file line number Diff line number Diff line change
@@ -22,24 +22,24 @@ abstract class AbstractConfigurableFloatingPointBitsFromCharSequence extends Abs
private final CharSet exponentSeparatorChar;
private final CharTrie exponentSeparatorTrie;

public AbstractConfigurableFloatingPointBitsFromCharSequence(NumberFormatSymbols symbols) {
this.decimalSeparator = CharSet.copyOf(symbols.decimalSeparator());
this.groupingSeparator = CharSet.copyOf(symbols.groupingSeparator());
public AbstractConfigurableFloatingPointBitsFromCharSequence(NumberFormatSymbols symbols, boolean ignoreCase) {
this.decimalSeparator = CharSet.copyOf(symbols.decimalSeparator(), ignoreCase);
this.groupingSeparator = CharSet.copyOf(symbols.groupingSeparator(), ignoreCase);
this.zeroChar = symbols.zeroDigit();
this.minusSignChar = CharSet.copyOf(symbols.minusSign());
this.exponentSeparatorChar = CharSet.copyOfFirstChar(symbols.exponentSeparator());
this.exponentSeparatorTrie = CharTrie.of(symbols.exponentSeparator());
this.plusSignChar = CharSet.copyOf(symbols.plusSign());
this.nanTrie = CharTrie.of(symbols.nan());
this.infinityTrie = CharTrie.of(symbols.infinity());
this.minusSignChar = CharSet.copyOf(symbols.minusSign(), ignoreCase);
this.exponentSeparatorChar = CharSet.copyOfFirstChar(symbols.exponentSeparator(), ignoreCase);
this.exponentSeparatorTrie = CharTrie.of(symbols.exponentSeparator(), ignoreCase);
this.plusSignChar = CharSet.copyOf(symbols.plusSign(), ignoreCase);
this.nanTrie = CharTrie.of(symbols.nan(), ignoreCase);
this.infinityTrie = CharTrie.of(symbols.infinity(), ignoreCase);
Set<Character> nanOrInfinitySet = new LinkedHashSet<>();
for (String s : symbols.nan()) {
nanOrInfinitySet.add(s.charAt(0));
}
for (String s : symbols.infinity()) {
nanOrInfinitySet.add(s.charAt(0));
}
nanOrInfinityChar = CharSet.copyOf(nanOrInfinitySet);
nanOrInfinityChar = CharSet.copyOf(nanOrInfinitySet, ignoreCase);
}

/**
@@ -224,21 +224,63 @@ private boolean isPlusSign(char c) {


protected CharSequence filterInputString(CharSequence str, int startIndex, int endIndex) {
StringBuilder b = new StringBuilder(endIndex - startIndex);
for (int i = startIndex; i < endIndex; i++) {
char ch = str.charAt(i);
StringBuilder buf = new StringBuilder(endIndex - startIndex);

// Filter leading format characters
// -------------------
int index = skipFormatCharacters(str, startIndex, endIndex);
char ch = str.charAt(index);

// Filter optional sign
// -------------------
final boolean isNegative = isMinusSign(ch);
if (isNegative) buf.append('-');
if (isNegative || isPlusSign(ch)) {
++index;
}

// We do not need to parse NaN or Infinity, this case has already been processed

// Parse significand
for (; index < endIndex; index++) {
ch = str.charAt(index);
int digit = (char) (ch - zeroChar);
if (digit < 10) {
b.append((char) (digit + '0'));
} else if (isMinusSign(ch)) {
b.append('-');
buf.append((char) (digit + '0'));
} else if (isDecimalSeparator(ch)) {
b.append('.');
} else if (isExponentSeparator(ch)) {
b.append('e');
buf.append('.');
} else if (!isGroupingSeparator(ch)) {
break;
}

}

// Parse exponent number
// ---------------------
int count = exponentSeparatorTrie.match(str, index, endIndex);
if (count > 0) {
buf.append('e');
index += count;
index = skipFormatCharacters(str, index, endIndex);
ch = charAt(str, index, endIndex);
boolean isExponentNegative = isMinusSign(ch);
if (isExponentNegative) {
buf.append('-');
}
if (isExponentNegative || isPlusSign(ch)) {
++index;
}
ch = str.charAt(index);
int digit = (char) (ch - zeroChar);
do {
buf.append((char) (digit + '0'));
ch = charAt(str, ++index, endIndex);
digit = (char) (ch - zeroChar);
} while (digit < 10);
}
return b;


return buf;
}

/**
@@ -255,6 +297,7 @@ private static int skipFormatCharacters(CharSequence str, int index, int endInde
}
return index;
}

private long parseNaNOrInfinity(CharSequence str, int index, int endIndex, boolean isNegative) {
int nanMatch = nanTrie.match(str, index, endIndex);
if (nanMatch > 0) {
Original file line number Diff line number Diff line change
@@ -10,7 +10,8 @@
interface CharSet {
boolean contains(char ch);

public static CharSet copyOf(Set<Character> set) {
public static CharSet copyOf(Set<Character> set, boolean ignoreCase) {
set = applyIgnoreCase(set, ignoreCase);
switch (set.size()) {
case 0:
return new CharSetOfNone();
@@ -21,11 +22,28 @@ public static CharSet copyOf(Set<Character> set) {
}
}

public static CharSet copyOfFirstChar(Set<String> strSet) {
private static Set<Character> applyIgnoreCase(Set<Character> set, boolean ignoreCase) {
if (ignoreCase) {
var convertedSet = new LinkedHashSet<Character>();
for (var ch : set) {
convertedSet.add(ch);
char lc = Character.toLowerCase(ch);
char uc = Character.toUpperCase(ch);
char uclc = Character.toLowerCase(uc);
convertedSet.add(lc);
convertedSet.add(uc);
convertedSet.add(uclc);
}
set = convertedSet;
}
return set;
}

public static CharSet copyOfFirstChar(Set<String> strSet, boolean ignoreCase) {
LinkedHashSet<Character> set = new LinkedHashSet<Character>();
for (String str : strSet) {
set.add(str.charAt(0));
}
return copyOf(set);
return copyOf(set, ignoreCase);
}
}
Original file line number Diff line number Diff line change
@@ -52,14 +52,14 @@ default int match(char[] str) {
*/
int match(char[] str, int startIndex, int endIndex);

public static CharTrie of(Set<String> set) {
public static CharTrie of(Set<String> set, boolean ignoreCase) {
switch (set.size()) {
case 0:
return new CharTrieOfNone();
case 1:
return new CharTrieOfOne(set);
return ignoreCase ? new CharTrieOfOneIgnoreCase(set) : new CharTrieOfOne(set);
default:
return new CharTrieOfMany(set);
return ignoreCase ? new CharTrieOfManyIgnoreCase(set) : new CharTrieOfMany(set);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* @(#)CharTrieOfMany.java
* Copyright © 2024 Werner Randelshofer, Switzerland. MIT License.
*/
package ch.randelshofer.fastdoubleparser;

import java.util.Set;

/**
* A trie for testing if a String is contained in a set of Strings.
*/
class CharTrieOfManyIgnoreCase implements CharTrie {
private TrieNode root = new TrieNode();

public CharTrieOfManyIgnoreCase(Set<String> set) {
for (String str : set) {
if (!str.isEmpty()) {
add(str);
}
}
}

private void add(String str) {
TrieNode node = root;
for (int i = 0; i < str.length(); i++) {
node = node.insert(convert(str.charAt(i)));
}
node.setEnd();
}

private char convert(char c) {
return Character.toLowerCase(Character.toUpperCase(c));
}

@Override
public int match(CharSequence str, int startIndex, int endIndex) {
TrieNode node = root;
int longestMatch = startIndex;
for (int i = startIndex; i < endIndex; i++) {
node = node.get(convert(str.charAt(i)));
longestMatch = node.isEnd() ? i + 1 : longestMatch;
}
return longestMatch - startIndex;
}

@Override
public int match(char[] str, int startIndex, int endIndex) {
TrieNode node = root;
int longestMatch = startIndex;
for (int i = startIndex; i < endIndex; i++) {
node = node.get(convert(str[i]));
longestMatch = node.isEnd() ? i + 1 : longestMatch;
}
return longestMatch - startIndex;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* @(#)CharTrieOfOne.java
* Copyright © 2024 Werner Randelshofer, Switzerland. MIT License.
*/
package ch.randelshofer.fastdoubleparser;

import java.util.Set;

class CharTrieOfOneIgnoreCase implements CharTrie {
private final char[] chars;

public CharTrieOfOneIgnoreCase(Set<String> set) {
this(set.iterator().next().toCharArray());
if (set.size() != 1) throw new IllegalArgumentException("set size must be 1, size=" + set.size());
}

public CharTrieOfOneIgnoreCase(char[] chars) {
this.chars = chars;
for (int i = 0; i < chars.length; i++) {
chars[i] = convert(chars[i]);
}
}

@Override
public int match(CharSequence str) {
return match(str, 0, str.length());
}

@Override
public int match(CharSequence str, int startIndex, int endIndex) {
int i = 0;
int limit = Math.min(endIndex - startIndex, chars.length);
while (i < limit && convert(str.charAt(i + startIndex)) == chars[i]) {
i++;
}
return i == chars.length ? chars.length : 0;
}

private char convert(char c) {
return Character.toLowerCase(Character.toUpperCase(c));
}

@Override
public int match(char[] str) {
return match(str, 0, str.length);
}

@Override
public int match(char[] str, int startIndex, int endIndex) {
int i = 0;
int limit = Math.min(endIndex - startIndex, chars.length);
while (i < limit && convert(str[i + startIndex]) == chars[i]) {
i++;
}
return i == chars.length ? chars.length : 0;
}
}
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ final class ConfigurableDoubleBitsFromCharArray extends AbstractConfigurableFloa
/**
* Creates a new instance.
*/
public ConfigurableDoubleBitsFromCharArray(NumberFormatSymbols symbols) {
super(symbols);
public ConfigurableDoubleBitsFromCharArray(NumberFormatSymbols symbols, boolean ignoreCase) {
super(symbols, ignoreCase);
}

@Override
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ final class ConfigurableDoubleBitsFromCharSequence extends AbstractConfigurableF
/**
* Creates a new instance.
*/
public ConfigurableDoubleBitsFromCharSequence(NumberFormatSymbols symbols) {
super(symbols);
public ConfigurableDoubleBitsFromCharSequence(NumberFormatSymbols symbols, boolean ignoreCase) {
super(symbols, ignoreCase);
}

@Override
Original file line number Diff line number Diff line change
@@ -109,44 +109,75 @@ public class ConfigurableDoubleParser {
private final NumberFormatSymbols symbols;
private ConfigurableDoubleBitsFromCharSequence charSequenceParser;
private ConfigurableDoubleBitsFromCharArray charArrayParser;
private final boolean ignoreCase;

/**
* Creates a new instance with the specified number format symbols.
* <p>
* The parser does not ignore case.
*
* @param symbols the number format symbols
*/
public ConfigurableDoubleParser(NumberFormatSymbols symbols) {
this.symbols = symbols;
this(symbols, false);
}

/**
* Creates a new instance with number format symbols derived
* from the specified symbols by calling
* {@link NumberFormatSymbols#fromDecimalFormatSymbols(DecimalFormatSymbols)}.
* <p>
* The parser does not ignore case.
*
* @param symbols the decimal format symbols
*/
public ConfigurableDoubleParser(DecimalFormatSymbols symbols) {
this(NumberFormatSymbols.fromDecimalFormatSymbols(symbols));
this(symbols, false);
}

/**
* Creates a new instance with the specified number format symbols and case sensitivity.
*
* @param symbols the number format symbols
* @param ignoreCase whether case should be ignored by the parser
*/
public ConfigurableDoubleParser(NumberFormatSymbols symbols, boolean ignoreCase) {
this.symbols = symbols;
this.ignoreCase = ignoreCase;
}

/**
* Creates a new instance with decimal format symbols and case sensitivity.
* <p>
* The number format symbols are derived
* from the specified decimal format symbols by calling
* {@link NumberFormatSymbols#fromDecimalFormatSymbols(DecimalFormatSymbols)}.
*
* @param symbols the decimal format symbols
* @param ignoreCase whether case should be ignored by the parser
*/
public ConfigurableDoubleParser(DecimalFormatSymbols symbols, boolean ignoreCase) {
this(NumberFormatSymbols.fromDecimalFormatSymbols(symbols), ignoreCase);
}

/**
* Creates a new instance with {@link NumberFormatSymbols#fromDefault()}.
* Creates a new instance with {@link NumberFormatSymbols#fromDefault()}
* which does not ignore case.
*/
public ConfigurableDoubleParser() {
this(NumberFormatSymbols.fromDefault());
this(NumberFormatSymbols.fromDefault(), false);
}

private ConfigurableDoubleBitsFromCharArray getCharArrayParser() {
if (charArrayParser == null) {
this.charArrayParser = new ConfigurableDoubleBitsFromCharArray(symbols);
this.charArrayParser = new ConfigurableDoubleBitsFromCharArray(symbols, ignoreCase);
}
return charArrayParser;
}

private ConfigurableDoubleBitsFromCharSequence getCharSequenceParser() {
if (charSequenceParser == null) {
this.charSequenceParser = new ConfigurableDoubleBitsFromCharSequence(symbols);
this.charSequenceParser = new ConfigurableDoubleBitsFromCharSequence(symbols, ignoreCase);
}
return charSequenceParser;
}
Original file line number Diff line number Diff line change
@@ -101,8 +101,8 @@ public List<DynamicNode> dynamicTests_parseDouble_Localized() {


public void performTestDecimalFormatSymbols(NumberTestData u, DecimalFormatSymbols decimalFormatSymbols) {
test(u, d -> new ConfigurableDoubleParser(decimalFormatSymbols).parseDouble(d.input()));
test(u, d -> new ConfigurableDoubleParser(decimalFormatSymbols).parseDouble(d.input().toString().toCharArray()));
test(u, d -> new ConfigurableDoubleParser(decimalFormatSymbols, u.ignoreCase()).parseDouble(d.input()));
test(u, d -> new ConfigurableDoubleParser(decimalFormatSymbols, u.ignoreCase()).parseDouble(d.input().toString().toCharArray()));
}

@TestFactory
@@ -123,8 +123,8 @@ public List<DynamicNode> dynamicTests_parseDouble_NumberFormatSymbols() {


public void performTestNumberFormatSymbols(NumberTestData u) {
test(u, d -> new ConfigurableDoubleParser(u.symbols()).parseDouble(d.input()));
test(u, d -> new ConfigurableDoubleParser(u.symbols()).parseDouble(d.input().toString().toCharArray()));
test(u, d -> new ConfigurableDoubleParser(u.symbols(), u.ignoreCase()).parseDouble(d.input()));
test(u, d -> new ConfigurableDoubleParser(u.symbols(), u.ignoreCase()).parseDouble(d.input().toString().toCharArray()));
}


Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@ public static List<NumberTestData> createLocalizedTestData(Locale locale) {

public static List<NumberTestData> createNumberFormatSymbolsTestData() {
List<NumberTestData> list = new ArrayList<>();
list.addAll(createIgnoreCaseNumberFormatSymbolsTestData());
list.addAll(createArabianNumberFormatSymbolsTestData());
list.addAll(createEstonianNumberFormatSymbolsTestData());
return list;
@@ -59,14 +60,47 @@ public static List<NumberTestData> createEstonianNumberFormatSymbolsTestData() {
dfs.getZeroDigit()
);
list.addAll(List.of(
new NumberTestData("Estonian locale with Estonian minus", dfs.getLocale(), symbols, dfs.getMinusSign() + "13,35", -13.35),
new NumberTestData("Estonian locale with Estonian minus", dfs.getLocale(), symbols, "\u221213,35", -13.35),
new NumberTestData("Estonian locale with ordinary minus", dfs.getLocale(), symbols, "-13,35", -13.35),
new NumberTestData("Estonian locale with full-width plus", dfs.getLocale(), symbols, "\uff0b13,35", 13.35),
new NumberTestData("Estonian locale with ordinary plus", dfs.getLocale(), symbols, "+13,35", 13.35)
new NumberTestData("Estonian locale with ordinary plus", dfs.getLocale(), symbols, "+13,35", 13.35),
new NumberTestData("Estonian locale with Estonian minus exponent", dfs.getLocale(), symbols, "13,35×10^\u22124", 13.35e-4),
new NumberTestData("Estonian locale with ordinary minus exponent", dfs.getLocale(), symbols, "13,35×10^-4", 13.35e-4),
new NumberTestData("Estonian locale with full-width plus exponent", dfs.getLocale(), symbols, "13,35×10^\uff0b4", 13.35e4),
new NumberTestData("Estonian locale with ordinary plus exponent", dfs.getLocale(), symbols, "13,35×10^+4", 13.35e4),
new NumberTestData("Estonian locale, Outside Clinger fast path, mantissa overflows in semi-fast path, 7.2057594037927933e+16",
dfs.getLocale(), symbols, "7,2057594037927933×10^16", 7.2057594037927933e+16d)
));
return list;
}

public static List<NumberTestData> createIgnoreCaseNumberFormatSymbolsTestData() {
List<NumberTestData> list = new ArrayList<>();
Locale englishLocale = Locale.ENGLISH;
var dfs = DecimalFormatSymbols.getInstance(englishLocale);
dfs.setInfinity("Infinity");
dfs.setExponentSeparator("Exp");
dfs.setNaN("NaN");
var symbols = new NumberFormatSymbols(
Set.of(dfs.getDecimalSeparator()),
Set.of(dfs.getGroupingSeparator()),
Set.of(dfs.getExponentSeparator()),
Set.of(dfs.getMinusSign()),
Set.of('+'),
Set.of(dfs.getInfinity()),
Set.of(dfs.getNaN()),
dfs.getZeroDigit()
);
DecimalFormat fmt = new DecimalFormat("#00.0####E0", dfs);
for (var n : new double[]{3e-9, -7e8, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}) {
list.add(new NumberTestData("ignoreCase: " + fmt.format(n), englishLocale, symbols, true, fmt.format(n), n));
list.add(new NumberTestData("ignoreCase: lower-case " + fmt.format(n).toLowerCase(englishLocale), englishLocale, symbols, true, fmt.format(n).toLowerCase(englishLocale), n));
list.add(new NumberTestData("ignoreCase: upper-case " + fmt.format(n).toUpperCase(englishLocale), englishLocale, symbols, true, fmt.format(n).toUpperCase(englishLocale), n));
}

return list;
}

public static List<NumberTestData> createArabianNumberFormatSymbolsTestData() {
List<NumberTestData> list = new ArrayList<>();
Locale arabianLocale = new Locale("ar");
Original file line number Diff line number Diff line change
@@ -15,86 +15,108 @@ public record NumberTestData(String title,
int radix, Number expectedValue,
String expectedErrorMessage,
Class<? extends Throwable> expectedThrowableClass,
java.util.Locale locale, NumberFormatSymbols symbols) {

java.util.Locale locale, NumberFormatSymbols symbols, boolean ignoreCase) {
public NumberTestData(String title,
CharSequence input,
int charOffset, int charLength,
int byteOffset, int byteLength,
int radix, Number expectedValue,
String expectedErrorMessage,
Class<? extends Throwable> expectedThrowableClass,
java.util.Locale locale, NumberFormatSymbols symbols) {
this(title,
input,
charOffset, charLength,
byteOffset, byteLength,
radix, expectedValue,
expectedErrorMessage,
expectedThrowableClass,
locale, symbols, false);
}
public NumberTestData(CharSequence input, Number expectedValue) {
this(input.toString(), input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, Locale.ENGLISH, null);
null, Locale.ENGLISH, null, false);
}

public NumberTestData(Locale locale, CharSequence input, Number expectedValue) {
this(input.toString(), input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, locale, null);
null, locale, null, false);
}

public NumberTestData(String title, Locale locale, CharSequence input, Number expectedValue) {
this(title, input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, locale, null);
null, locale, null, false);
}

public NumberTestData(String title, Locale locale, NumberFormatSymbols symbols, CharSequence input, Number expectedValue) {
this(title, input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, locale, symbols);
null, locale, symbols, false);
}

public NumberTestData(String title, Locale locale, NumberFormatSymbols symbols, boolean ignoreCase, CharSequence input, Number expectedValue) {
this(title, input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, locale, symbols, ignoreCase);
}

public NumberTestData(CharSequence input, int radix, Number expectedValue) {
this(input.toString(), input, 0, input.length(), 0, input.length(),
radix, expectedValue, null,
null, Locale.ENGLISH, null);
null, Locale.ENGLISH, null, false);
}

public NumberTestData(String title, CharSequence input, int radix, Number expectedValue) {
this(title, input, 0, input.length(), 0, input.length(),
radix, expectedValue, null,
null, Locale.ENGLISH, null);
null, Locale.ENGLISH, null, false);
}

public NumberTestData(CharSequence input, Number expectedValue, int offset, int length) {
this(input.toString(), input, offset, length, offset, length,
10, expectedValue, null, null, Locale.ENGLISH, null);
10, expectedValue, null, null, Locale.ENGLISH, null, false);
}

public NumberTestData(String title, CharSequence input, int radix, String expectedErrorMessage, Class<? extends Throwable> expectedThrowableClass) {
this(title, input, 0, input.length(), 0, input.length(),
radix, null, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}

public NumberTestData(CharSequence input, int radix, String expectedErrorMessage, Class<? extends Throwable> expectedThrowableClass) {
this(input.toString(), input, 0, input.length(), 0, input.length(),
radix, null, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}

public NumberTestData(CharSequence input, Number expectedValue, int offset, int length, String expectedErrorMessage, Class<? extends Throwable> expectedThrowableClass) {
this(input.toString(), input, offset, length, offset, length,
10, expectedValue, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}


public NumberTestData(String title, CharSequence input, int offset, int length, int bOffset, int bLength, String expectedErrorMessage,
Class<? extends Throwable> expectedThrowableClass) {
this(title, input, offset, length, bOffset, bLength,
10, null, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}

public NumberTestData(String title, CharSequence input, int offset, int length, int bOffset, int bLength, Number expectedValue) {
this(title, input, offset, length, bOffset, bLength,
10, expectedValue, null,
null, Locale.ENGLISH, null);
null, Locale.ENGLISH, null, false);
}

public NumberTestData(String title, CharSequence input, Number expectedValue) {
this(title,
input, 0, input.length(), 0, input.length(),
10, expectedValue, null,
null, Locale.ENGLISH, null);
null, Locale.ENGLISH, null, false);
}

public NumberTestData(String title, CharSequence input, Function<String, Number> constructor) {
@@ -119,13 +141,13 @@ public NumberTestData(String title, CharSequence input, String expectedErrorMess
this(title,
input, 0, input.length(), 0, input.length(),
10, null, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}

public NumberTestData(CharSequence input, String expectedErrorMessage, Class<? extends Throwable> expectedThrowableClass) {
this(input.toString(),
input, 0, input.length(), 0, input.length(),
10, null, expectedErrorMessage,
expectedThrowableClass, Locale.ENGLISH, null);
expectedThrowableClass, Locale.ENGLISH, null, false);
}
}

0 comments on commit e692134

Please sign in to comment.