package client.net.sf.saxon.ce.expr;
import client.net.sf.saxon.ce.om.Item;
import client.net.sf.saxon.ce.om.SequenceIterator;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.value.AtomicValue;
import client.net.sf.saxon.ce.value.SequenceExtent;
import client.net.sf.saxon.ce.value.Value;
/**
* A NumericPromoter performs numeric promotion on each item in a supplied sequence.
* There are two subclasses, to handle promotion to double and promotion to float
*/
public abstract class NumericPromoter extends UnaryExpression {
public NumericPromoter(Expression exp) {
super(exp);
}
/**
* Simplify an expression
* @param visitor an expression visitor
*/
public Expression simplify(ExpressionVisitor visitor) throws XPathException {
operand = visitor.simplify(operand);
if (operand instanceof Literal) {
if (((Literal)operand).getValue() instanceof AtomicValue) {
return Literal.makeLiteral(
promote(((AtomicValue)((Literal)operand).getValue())));
} else {
return Literal.makeLiteral(
((Value)SequenceExtent.makeSequenceExtent(
iterate(visitor.getStaticContext().makeEarlyEvaluationContext()))).reduce());
}
}
return this;
}
/**
* Iterate over the sequence of values
*/
public SequenceIterator iterate(final XPathContext context) throws XPathException {
SequenceIterator base = operand.iterate(context);
ItemMappingFunction promoter = new ItemMappingFunction() {
public Item mapItem(Item item) throws XPathException {
return promote(((AtomicValue)item));
}
};
return new ItemMappingIterator(base, promoter, true);
}
/**
* Evaluate as an Item. This should only be called if the expression has cardinality zero-or-one
*/
public Item evaluateItem(XPathContext context) throws XPathException {
Item item = operand.evaluateItem(context);
if (item==null) return null;
return promote(((AtomicValue)item));
}
/**
* Perform the promotion
* @param value the numeric or untyped atomic value to be promoted
* @return the value that results from the promotion
*/
protected abstract AtomicValue promote(AtomicValue value) throws XPathException;
}
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.