1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 // This file is not part of the Qt API. It exists purely as an
47 // implementation detail. This header file may change from version to
48 // version without notice, or even be removed.
52 #ifndef Patternist_SequenceFNs_H
53 #define Patternist_SequenceFNs_H
55 #include <private/qatomiccomparator_p.h>
56 #include <private/qcomparisonplatform_p.h>
57 #include <private/qliteral_p.h>
58 #include <private/qfunctioncall_p.h>
62 * @short Contains classes implementing the functions found in
63 * <a href="http://www.w3.org/TR/xpath-functions/#general-seq-funcs">XQuery 1.0 and
64 * XPath 2.0 Functions and Operators, 15.1 General Functions and Operators on Sequences</a>.
66 * @todo document that some functions have both eval funcs implented.
68 * @ingroup Patternist_functions
78 * @short Implements the function <tt>fn:boolean()</tt>.
81 * @ingroup Patternist_functions
82 * @author Frans Englich <frans.englich@nokia.com>
84 class BooleanFN : public FunctionCall
87 virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
90 * If @p reqType is CommonSequenceTypes::EBV, the type check of
91 * the operand is returned. Hence, this removes redundant calls
92 * to <tt>fn:boolean()</tt>.
94 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
95 const SequenceType::Ptr &reqType);
99 * @short Implements the function <tt>fn:index-of()</tt>.
101 * @ingroup Patternist_functions
102 * @author Frans Englich <frans.englich@nokia.com>
104 class IndexOfFN : public FunctionCall,
105 public ComparisonPlatform<IndexOfFN, false>
108 inline IndexOfFN() : ComparisonPlatform<IndexOfFN, false>()
112 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
113 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
114 const SequenceType::Ptr &reqType);
116 inline AtomicComparator::Operator operatorID() const
118 return AtomicComparator::OperatorEqual;
123 * @short Implements the functions <tt>fn:exists()</tt> and <tt>fn:empty()</tt>.
125 * Existence is a template value class. Appropriate implementations are achieved
126 * by instantiating it with either IDExistsFN or IDEmptyFN.
128 * @ingroup Patternist_functions
129 * @author Frans Englich <frans.englich@nokia.com>
131 template<const Expression::ID Id>
132 class Existence : public FunctionCall
135 virtual bool evaluateEBV(const DynamicContext::Ptr &context) const
138 return !m_operands.first()->evaluateSequence(context)->isEmpty();
140 return m_operands.first()->evaluateSequence(context)->isEmpty();
144 * Attempts to rewrite to @c false or @c true by looking at the static
145 * cardinality of its operand.
147 virtual Expression::Ptr compress(const StaticContext::Ptr &context)
149 // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is
150 // passed directly into another constructor.
151 Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN);
153 const Expression::Ptr me(FunctionCall::compress(context));
158 // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is
159 // passed directly into another constructor.
160 Expression::ID tempId = Id;
161 const Cardinality myCard((tempId == IDExistsFN) ? Cardinality::oneOrMore() : Cardinality::empty());
163 const Cardinality card(m_operands.first()->staticType()->cardinality());
164 if(myCard.isMatch(card))
165 { /* Since the dynamic type always is narrower than the static type or equal, and that the
166 static type is in scope, it means we will always be true. */
167 return wrapLiteral(CommonValues::BooleanTrue, context, this);
171 /* Is it even possible to hit? */
172 if(myCard.canMatch(card))
177 { /* We can never hit. */
178 return wrapLiteral(CommonValues::BooleanFalse, context, this);
185 * @short Implements the function <tt>fn:distinct-values()</tt>.
187 * @ingroup Patternist_functions
188 * @author Frans Englich <frans.englich@nokia.com>
190 class DistinctValuesFN : public FunctionCall,
191 public ComparisonPlatform<IndexOfFN, false>
194 inline DistinctValuesFN() : ComparisonPlatform<IndexOfFN, false>()
198 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
200 * Performs necessary type checks, but also implements the optimization
201 * of rewriting to its operand if the operand's cardinality is zero-or-one
204 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
205 const SequenceType::Ptr &reqType);
207 * @returns a type whose item type is the type of the first operand, and
208 * a cardinality which is non-empty if the first operand's type is non-empty
209 * and allows exactly-one. The latter is needed for operands which has the
210 * cardinality 2+, since distinct-values possibly removes items from the
213 virtual SequenceType::Ptr staticType() const;
216 inline AtomicComparator::Operator operatorID() const
218 return AtomicComparator::OperatorEqual;
223 * @short Implements the function <tt>fn:insert-before()</tt>.
225 * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented
227 * @ingroup Patternist_functions
228 * @author Frans Englich <frans.englich@nokia.com>
230 class InsertBeforeFN : public FunctionCall
233 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
234 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
237 * Implements the static enferences rules. The function's static item type
238 * is the union type of the first and third argument, and the cardinality is
239 * the cardinalities of the two operands added together. For example,
240 * insert-before((1, "str"), 1, xs:double(0)) has the static type xs:anyAtomicType+.
242 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_insert_before">XQuery 1.0
243 * and XPath 2.0 Formal Semantics, 7.2.15 The fn:insert-before function</a>
245 virtual SequenceType::Ptr staticType() const;
249 * @short Implements the function <tt>fn:remove()</tt>.
251 * @ingroup Patternist_functions
252 * @author Frans Englich <frans.englich@nokia.com>
254 class RemoveFN : public FunctionCall
257 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
258 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
261 * Implements the static enferences rules, "Since one item may be removed
262 * from the sequence, the resulting type is made optional:"
264 * <tt>statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)?</tt>
266 * However, because Patternist's type system is more fine grained than Formal Semantics,
267 * the sequence isn't made optional. Instead its minimum length is reduced with one.
269 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_remove">XQuery 1.0
270 * and XPath 2.0 Formal Semantics, 7.2.11 The fn:remove function</a>
272 virtual SequenceType::Ptr staticType() const;
276 * @short Implements the function <tt>fn:reverse()</tt>.
278 * @ingroup Patternist_functions
279 * @author Frans Englich <frans.englich@nokia.com>
281 class ReverseFN : public FunctionCall
285 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
286 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
287 const SequenceType::Ptr &reqType);
290 * Formally speaking, the type inference is:
293 statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type)
296 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0
297 * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a>
298 * @returns the static type of the function's first argument.
300 virtual SequenceType::Ptr staticType() const;
304 * @short Implements the function <tt>fn:subsequence()</tt>.
306 * @ingroup Patternist_functions
307 * @author Frans Englich <frans.englich@nokia.com>
308 * @todo Type inference can be made stronger for this function
310 class SubsequenceFN : public FunctionCall
314 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
315 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
317 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
318 const SequenceType::Ptr &reqType);
321 * This function implements rewrites the SubsequenceFN instance into an
322 * empty sequence if its third argument, the sequence length argument, is
323 * evaluated and is effectively equal or less than zero.
325 virtual Expression::Ptr compress(const StaticContext::Ptr &context);
328 * Partially implements the static type inference rules.
330 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_subsequence">XQuery 1.0
331 * and XPath 2.0 Formal Semantics, 7.2.13 The fn:subsequence function</a>
333 virtual SequenceType::Ptr staticType() const;
336 bool m_hasTypeChecked;