soot.toolkits.scalar.AbstractFlowSet Maven / Gradle / Ivy
package soot.toolkits.scalar;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2002 Florian Loitsch
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.Iterator;
import java.util.List;
/**
* provides functional code for most of the methods. Subclasses are invited to provide a more efficient version. Most often
* this will be done in the following way:
*
*
* public void yyy(FlowSet dest) {
* if (dest instanceof xxx) {
* blahblah;
* } else
* super.yyy(dest)
* }
*
*/
public abstract class AbstractFlowSet implements FlowSet {
public abstract AbstractFlowSet clone();
/**
* implemented, but inefficient.
*/
public FlowSet emptySet() {
FlowSet t = clone();
t.clear();
return t;
}
public void copy(FlowSet dest) {
if (this == dest) {
return;
}
dest.clear();
for (T t : this) {
dest.add(t);
}
}
/**
* implemented, but *very* inefficient.
*/
public void clear() {
for (T t : this) {
remove(t);
}
}
public void union(FlowSet other) {
if (this == other) {
return;
}
union(other, this);
}
public void union(FlowSet other, FlowSet dest) {
if (dest != this && dest != other) {
dest.clear();
}
if (dest != null && dest != this) {
for (T t : this) {
dest.add(t);
}
}
if (other != null && dest != other) {
for (T t : other) {
dest.add(t);
}
}
}
public void intersection(FlowSet other) {
if (this == other) {
return;
}
intersection(other, this);
}
public void intersection(FlowSet other, FlowSet dest) {
if (dest == this && dest == other) {
return;
}
FlowSet elements = null;
FlowSet flowSet = null;
if (dest == this) {
/*
* makes automaticly a copy of this
, as it will be cleared
*/
elements = this;
flowSet = other;
} else {
/* makes a copy o other
, as it might be cleared */
elements = other;
flowSet = this;
}
dest.clear();
for (T t : elements) {
if (flowSet.contains(t)) {
dest.add(t);
}
}
}
public void difference(FlowSet other) {
difference(other, this);
}
public void difference(FlowSet other, FlowSet dest) {
if (dest == this && dest == other) {
dest.clear();
return;
}
FlowSet flowSet = (other == dest) ? other.clone() : other;
dest.clear(); // now safe, since we have copies of this & other
for (T t : this) {
if (!flowSet.contains(t)) {
dest.add(t);
}
}
}
public abstract boolean isEmpty();
public abstract int size();
public abstract void add(T obj);
public void add(T obj, FlowSet dest) {
if (dest != this) {
copy(dest);
}
dest.add(obj);
}
public abstract void remove(T obj);
public void remove(T obj, FlowSet dest) {
if (dest != this) {
copy(dest);
}
dest.remove(obj);
}
@Override
public boolean isSubSet(FlowSet other) {
if (other == this) {
return true;
}
for (T t : other) {
if (!contains(t)) {
return false;
}
}
return true;
}
public abstract boolean contains(T obj);
public abstract Iterator iterator();
public abstract List toList();
@SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (!(o instanceof FlowSet)) {
return false;
}
FlowSet other = (FlowSet) o;
if (size() != other.size()) {
return false;
}
for (T t : this) {
if (!other.contains(t)) {
return false;
}
}
return true;
}
public int hashCode() {
int result = 1;
for (T t : this) {
result += t.hashCode();
}
return result;
}
public String toString() {
StringBuffer buffer = new StringBuffer("{");
boolean isFirst = true;
for (T t : this) {
if (!isFirst) {
buffer.append(", ");
}
isFirst = false;
buffer.append(t);
}
buffer.append("}");
return buffer.toString();
}
}