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

Last change on this file since 117 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 12.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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 Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN);
150 const Expression::Ptr me(FunctionCall::compress(context));
151
152 if(me != this)
153 return me;
154
155 const Cardinality myCard((Id == IDExistsFN) ? Cardinality::oneOrMore() : Cardinality::empty());
156
157 const Cardinality card(m_operands.first()->staticType()->cardinality());
158 if(myCard.isMatch(card))
159 { /* Since the dynamic type always is narrower than the static type or equal, and that the
160 static type is in scope, it means we will always be true. */
161 return wrapLiteral(CommonValues::BooleanTrue, context, this);
162 }
163 else
164 {
165 /* Is it even possible to hit? */
166 if(myCard.canMatch(card))
167 {
168 return me;
169 }
170 else
171 { /* We can never hit. */
172 return wrapLiteral(CommonValues::BooleanFalse, context, this);
173 }
174 }
175 }
176 };
177
178 /**
179 * @short Implements the function <tt>fn:distinct-values()</tt>.
180 *
181 * @ingroup Patternist_functions
182 * @author Frans Englich <[email protected]>
183 */
184 class DistinctValuesFN : public FunctionCall,
185 public ComparisonPlatform<IndexOfFN, false>
186 {
187 public:
188 inline DistinctValuesFN() : ComparisonPlatform<IndexOfFN, false>()
189 {
190 }
191
192 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
193 /**
194 * Performs necessary type checks, but also implements the optimization
195 * of rewriting to its operand if the operand's cardinality is zero-or-one
196 * or exactly-one.
197 */
198 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
199 const SequenceType::Ptr &reqType);
200 /**
201 * @returns a type whose item type is the type of the first operand, and
202 * a cardinality which is non-empty if the first operand's type is non-empty
203 * and allows exactly-one. The latter is needed for operands which has the
204 * cardinality 2+, since distinct-values possibly removes items from the
205 * source sequence.
206 */
207 virtual SequenceType::Ptr staticType() const;
208
209 protected:
210 inline AtomicComparator::Operator operatorID() const
211 {
212 return AtomicComparator::OperatorEqual;
213 }
214 };
215
216 /**
217 * @short Implements the function <tt>fn:insert-before()</tt>.
218 *
219 * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented
220 *
221 * @ingroup Patternist_functions
222 * @author Frans Englich <[email protected]>
223 */
224 class InsertBeforeFN : public FunctionCall
225 {
226 public:
227 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
228 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
229
230 /**
231 * Implements the static enferences rules. The function's static item type
232 * is the union type of the first and third argument, and the cardinality is
233 * the cardinalities of the two operands added together. For example,
234 * insert-before((1, "str"), 1, xs:double(0)) has the static type xs:anyAtomicType+.
235 *
236 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_insert_before">XQuery 1.0
237 * and XPath 2.0 Formal Semantics, 7.2.15 The fn:insert-before function</a>
238 */
239 virtual SequenceType::Ptr staticType() const;
240 };
241
242 /**
243 * @short Implements the function <tt>fn:remove()</tt>.
244 *
245 * @ingroup Patternist_functions
246 * @author Frans Englich <[email protected]>
247 */
248 class RemoveFN : public FunctionCall
249 {
250 public:
251 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
252 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
253
254 /**
255 * Implements the static enferences rules, "Since one item may be removed
256 * from the sequence, the resulting type is made optional:"
257 *
258 * <tt>statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)?</tt>
259 *
260 * However, because Patternist's type system is more fine grained than Formal Semantics,
261 * the sequence isn't made optional. Instead its minimum length is reduced with one.
262 *
263 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_remove">XQuery 1.0
264 * and XPath 2.0 Formal Semantics, 7.2.11 The fn:remove function</a>
265 */
266 virtual SequenceType::Ptr staticType() const;
267 };
268
269 /**
270 * @short Implements the function <tt>fn:reverse()</tt>.
271 *
272 * @ingroup Patternist_functions
273 * @author Frans Englich <[email protected]>
274 */
275 class ReverseFN : public FunctionCall
276 {
277 public:
278
279 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
280 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
281 const SequenceType::Ptr &reqType);
282
283 /**
284 * Formally speaking, the type inference is:
285 *
286@verbatim
287statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type)
288@endverbatim
289 *
290 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0
291 * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a>
292 * @returns the static type of the function's first argument.
293 */
294 virtual SequenceType::Ptr staticType() const;
295 };
296
297 /**
298 * @short Implements the function <tt>fn:subsequence()</tt>.
299 *
300 * @ingroup Patternist_functions
301 * @author Frans Englich <[email protected]>
302 * @todo Type inference can be made stronger for this function
303 */
304 class SubsequenceFN : public FunctionCall
305 {
306 public:
307 SubsequenceFN();
308 virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
309 virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
310
311 virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
312 const SequenceType::Ptr &reqType);
313
314 /**
315 * This function implements rewrites the SubsequenceFN instance into an
316 * empty sequence if its third argument, the sequence length argument, is
317 * evaluated and is effectively equal or less than zero.
318 */
319 virtual Expression::Ptr compress(const StaticContext::Ptr &context);
320
321 /**
322 * Partially implements the static type inference rules.
323 *
324 * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_subsequence">XQuery 1.0
325 * and XPath 2.0 Formal Semantics, 7.2.13 The fn:subsequence function</a>
326 */
327 virtual SequenceType::Ptr staticType() const;
328
329 private:
330 bool m_hasTypeChecked;
331 };
332}
333
334QT_END_NAMESPACE
335
336QT_END_HEADER
337
338#endif
Note: See TracBrowser for help on using the repository browser.