/*******************************************************************************
* Copyright (c) 2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
* * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package org.rascalmpl.value.impl;
import org.rascalmpl.value.ISet;
import org.rascalmpl.value.ISetRelation;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.IValueFactory;
import org.rascalmpl.value.exceptions.IllegalOperationException;
import org.rascalmpl.value.impl.func.SetFunctions;
import org.rascalmpl.value.type.Type;
import org.rascalmpl.value.type.TypeFactory;
import org.rascalmpl.value.visitors.IValueVisitor;
public abstract class AbstractSet extends AbstractValue implements ISet {
public AbstractSet() {
super();
}
protected static TypeFactory getTypeFactory() {
return TypeFactory.getInstance();
}
protected static Type inferSetOrRelType(final Type elementType, final Iterable<IValue> content) {
return inferSetOrRelType(elementType, content.iterator().hasNext() == false);
}
/*
* TODO: get rid of code duplication (@see AbstractList.inferListOrRelType)
*/
protected static Type inferSetOrRelType(final Type elementType, final boolean isEmpty) {
final Type inferredElementType;
final Type inferredCollectionType;
// is collection empty?
if (isEmpty) {
inferredElementType = getTypeFactory().voidType();
} else {
inferredElementType = elementType;
}
// consists collection out of tuples?
if (inferredElementType.isFixedWidth()) {
inferredCollectionType = getTypeFactory().relTypeFromTuple(inferredElementType);
} else {
inferredCollectionType = getTypeFactory().setType(inferredElementType);
}
return inferredCollectionType;
}
protected abstract IValueFactory getValueFactory();
@Override
public Type getElementType() {
return getType().getElementType();
}
@Override
public ISet insert(IValue e) {
return SetFunctions.insert(getValueFactory(), this, e);
}
@Override
public ISet union(ISet that) {
return SetFunctions.union(getValueFactory(), this, that);
}
@Override
public ISet intersect(ISet that) {
return SetFunctions.intersect(getValueFactory(), this, that);
}
@Override
public ISet subtract(ISet that) {
return SetFunctions.subtract(getValueFactory(), this, that);
}
@Override
public ISet delete(IValue e) {
return SetFunctions.delete(getValueFactory(), this, e);
}
@Override
public ISet product(ISet that) {
return SetFunctions.product(getValueFactory(), this, that);
}
@Override
public boolean isSubsetOf(ISet that) {
return SetFunctions.isSubsetOf(getValueFactory(), this, that);
}
@Override
public <T, E extends Throwable> T accept(IValueVisitor<T, E> v) throws E {
return v.visitSet(this);
}
@Override
public boolean isRelation() {
return getType().isRelation();
}
@Override
public ISetRelation<ISet> asRelation() {
if (!isRelation())
throw new IllegalOperationException(
"Cannot be viewed as a relation.", getType());
return new DefaultRelationViewOnSet(getValueFactory(), this);
}
}