blob: 96a126cdfa9180fccb7168fe2215ac4df08d962f [file] [log] [blame]
/*
* Copyright (C) 2017 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.escapevelocity;
import java.util.AbstractSet;
import java.util.BitSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* An immutable set of ASCII characters.
*
* @author emcmanus@google.com (Éamonn McManus)
*/
class ImmutableAsciiSet extends AbstractSet<Integer> {
private final BitSet bits;
ImmutableAsciiSet(BitSet bits) {
this.bits = bits;
}
static ImmutableAsciiSet of(char c) {
return ofRange(c, c);
}
static ImmutableAsciiSet ofRange(char from, char to) {
if (from > to) {
throw new IllegalArgumentException("from > to");
}
if (to >= 128) {
throw new IllegalArgumentException("Not ASCII");
}
BitSet bits = new BitSet();
bits.set(from, to + 1);
return new ImmutableAsciiSet(bits);
}
ImmutableAsciiSet union(ImmutableAsciiSet that) {
BitSet union = (BitSet) bits.clone();
union.or(that.bits);
return new ImmutableAsciiSet(union);
}
@Override
public boolean contains(Object o) {
int i = -1;
if (o instanceof Character) {
i = (Character) o;
} else if (o instanceof Integer) {
i = (Integer) o;
}
return contains(i);
}
boolean contains(int i) {
if (i < 0) {
return false;
} else {
return bits.get(i);
}
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int index;
@Override
public boolean hasNext() {
return bits.nextSetBit(index) >= 0;
}
@Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int next = bits.nextSetBit(index);
index = next + 1;
return next;
}
};
}
@Override
public int size() {
return bits.cardinality();
}
}