source: trunk/src/xmlpatterns/functions/qsequencefns_p.h@ 618

Last change on this file since 618 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 12.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//
43// W A R N I N G
44// -------------
45//
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.
49//
50// We mean it.
51
52#ifndef Patternist_SequenceFNs_H
53#define Patternist_SequenceFNs_H
54
55#include "qatomiccomparator_p.h"
56#include "qcomparisonplatform_p.h"
57#include "qliteral_p.h"
58#include "qfunctioncall_p.h"
59
60/**
61 * @file
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>.
65 *
66 * @todo document that some functions have both eval funcs implented.
67 *
68 * @ingroup Patternist_functions
69 */
70
71QT_BEGIN_HEADER
72
73QT_BEGIN_NAMESPACE
74
75namespace QPatternist
76{
77 /**
78 * @short Implements the function <tt>fn:boolean()</tt>.
79 *
80 * @see EBVExtractor
81 * @ingroup Patternist_functions
82 * @author Frans Englich <[email protected]>
83 */
84 class BooleanFN : public FunctionCall
85 {
86 public:
87 virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
88
89 /**
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>.
93 */
94 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
95 const SequenceType::Ptr &reqType);
96 };
97
98 /**
99 * @short Implements the function <tt>fn:index-of()</tt>.
100 *
101 * @ingroup Patternist_functions
102 * @author Frans Englich <[email protected]>
103 */
104 class IndexOfFN : public FunctionCall,
105 public ComparisonPlatform<IndexOfFN, false>
106 {
107 public:
108 inline IndexOfFN() : ComparisonPlatform<IndexOfFN, false>()
109 {
110 }
111
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);
115
116 inline AtomicComparator::Operator operatorID() const
117 {
118 return AtomicComparator::OperatorEqual;
119 }
120 };
121
122 /**
123 * @short Implements the functions <tt>fn:exists()</tt> and <tt>fn:empty()</tt>.
124 *
125 * Existence is a template value class. Appropriate implementations are achieved
126 * by instantiating it with either IDExistsFN or IDEmptyFN.
127 *
128 * @ingroup Patternist_functions
129 * @author Frans Englich <[email protected]>
130 */
131 template<const Expression::ID Id>
132 class Existence : public FunctionCall
133 {
134 public:
135 virtual bool evaluateEBV(const DynamicContext::Ptr &context) const
136 {
137 if(Id == IDExistsFN)
138 return !m_operands.first()->evaluateSequence(context)->isEmpty();
139 else
140 return m_operands.first()->evaluateSequence(context)->isEmpty();
141 }
142
143 /**
144 * Attempts to rewrite to @c false or @c true by looking at the static
145 * cardinality of its operand.
146 */
147 virtual Expression::Ptr compress(const StaticContext::Ptr &context)
148 {
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);
152
153 const Expression::Ptr me(FunctionCall::compress(context));
154
155 if(me != this)
156 return me;
157
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());
162
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);
168 }
169 else
170 {
171 /* Is it even possible to hit? */
172 if(myCard.canMatch(card))
173 {
174 return me;
175 }
176 else
177 { /* We can never hit. */
178 return wrapLiteral(CommonValues::BooleanFalse, context, this);
179 }
180 }
181 }
182 };
183
184 /**
185 * @short Implements the function <tt>fn:distinct-values()</tt>.
186 *
187 * @ingroup Patternist_functions
188 * @author Frans Englich <[email protected]>
189 */
190 class DistinctValuesFN : public FunctionCall,
191 public ComparisonPlatform<IndexOfFN, false>
192 {
193 public:
194 inline DistinctValuesFN() : ComparisonPlatform<IndexOfFN, false>()
195 {
196 }
197
198 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
199 /**
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
202 * or exactly-one.
203 */
204 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
205 const SequenceType::Ptr &reqType);
206 /**
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
211 * source sequence.
212 */
213 virtual SequenceType::Ptr staticType() const;
214
215 protected:
216 inline AtomicComparator::Operator operatorID() const
217 {
218 return AtomicComparator::OperatorEqual;
219 }
220 };
221
222 /**
223 * @short Implements the function <tt>fn:insert-before()</tt>.
224 *
225 * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented
226 *
227 * @ingroup Patternist_functions
228 * @author Frans Englich <[email protected]>
229 */
230 class InsertBeforeFN : public FunctionCall
231 {
232 public:
233 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
234 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
235
236 /**
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+.
241 *
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>
244 */
245 virtual SequenceType::Ptr staticType() const;
246 };
247
248 /**
249 * @short Implements the function <tt>fn:remove()</tt>.
250 *
251 * @ingroup Patternist_functions
252 * @author Frans Englich <[email protected]>
253 */
254 class RemoveFN : public FunctionCall
255 {
256 public:
257 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
258 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
259
260 /**
261 * Implements the static enferences rules, "Since one item may be removed
262 * from the sequence, the resulting type is made optional:"
263 *
264 * <tt>statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)?</tt>
265 *
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.
268 *
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>
271 */
272 virtual SequenceType::Ptr staticType() const;
273 };
274
275 /**
276 * @short Implements the function <tt>fn:reverse()</tt>.
277 *
278 * @ingroup Patternist_functions
279 * @author Frans Englich <[email protected]>
280 */
281 class ReverseFN : public FunctionCall
282 {
283 public:
284
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);
288
289 /**
290 * Formally speaking, the type inference is:
291 *
292@verbatim
293statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type)
294@endverbatim
295 *
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.
299 */
300 virtual SequenceType::Ptr staticType() const;
301 };
302
303 /**
304 * @short Implements the function <tt>fn:subsequence()</tt>.
305 *
306 * @ingroup Patternist_functions
307 * @author Frans Englich <[email protected]>
308 * @todo Type inference can be made stronger for this function
309 */
310 class SubsequenceFN : public FunctionCall
311 {
312 public:
313 SubsequenceFN();
314 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
315 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
316
317 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
318 const SequenceType::Ptr &reqType);
319
320 /**
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.
324 */
325 virtual Expression::Ptr compress(const StaticContext::Ptr &context);
326
327 /**
328 * Partially implements the static type inference rules.
329 *
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>
332 */
333 virtual SequenceType::Ptr staticType() const;
334
335 private:
336 bool m_hasTypeChecked;
337 };
338}
339
340QT_END_NAMESPACE
341
342QT_END_HEADER
343
344#endif
Note: See TracBrowser for help on using the repository browser.