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

Last change on this file since 987 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 12.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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]>