source: trunk/src/xmlpatterns/expr/qcomparisonplatform.cpp@ 561

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

trunk: Merged in qt 4.6.1 sources.

File size: 8.1 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 * @file
44 * @short This file is included by qcomparisonplatform_p.h.
45 * If you need includes in this file, put them in qcomparisonplatform_p.h, outside of the namespace.
46 */
47
48template <typename TSubClass, bool issueError,
49 AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
50bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
51flexibleCompare(const Item &it1,
52 const Item &it2,
53 const DynamicContext::Ptr &context) const
54{
55 if(m_comparator)
56 /* The comparator was located at compile time. */
57 return compare(it1, it2, m_comparator, operatorID());
58 else
59 {
60 const AtomicComparator::Ptr cp(fetchComparator(it1.type(),
61 it2.type(),
62 context));
63
64 return cp ? compare(it1, it2, cp, operatorID()) : false;
65 }
66}
67
68template <typename TSubClass, bool issueError,
69 AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
70AtomicComparator::ComparisonResult
71ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
72detailedFlexibleCompare(const Item &it1,
73 const Item &it2,
74 const DynamicContext::Ptr &context) const
75{
76 AtomicComparator::Ptr comp;
77
78 if(m_comparator)
79 comp = m_comparator;
80 else
81 {
82 comp = fetchComparator(it1.type(),
83 it2.type(),
84 context);
85 }
86
87 Q_ASSERT_X(operatorID() == AtomicComparator::OperatorLessThanNaNLeast || operatorID() == AtomicComparator::OperatorLessThanNaNGreatest,
88 Q_FUNC_INFO, "Only OperatorLessThan is currently supported for this function.");
89 return comp->compare(it1, operatorID(), it2);
90}
91
92template <typename TSubClass, bool issueError,
93 AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
94bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
95compare(const Item &oand1,
96 const Item &oand2,
97 const AtomicComparator::Ptr &comp,
98 const AtomicComparator::Operator op) const
99{
100 Q_ASSERT(oand1);
101 Q_ASSERT(oand2);
102 Q_ASSERT(comp);
103
104 switch(op)
105 {
106 case AtomicComparator::OperatorEqual:
107 return comp->equals(oand1, oand2);
108 case AtomicComparator::OperatorNotEqual:
109 return !comp->equals(oand1, oand2);
110 case AtomicComparator::OperatorLessThanNaNLeast:
111 case AtomicComparator::OperatorLessThanNaNGreatest:
112 /* Fallthrough. */
113 case AtomicComparator::OperatorLessThan:
114 return comp->compare(oand1, op, oand2) == AtomicComparator::LessThan;
115 case AtomicComparator::OperatorGreaterThan:
116 return comp->compare(oand1, op, oand2) == AtomicComparator::GreaterThan;
117 case AtomicComparator::OperatorLessOrEqual:
118 {
119 const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
120 return ret == AtomicComparator::LessThan || ret == AtomicComparator::Equal;
121 }
122 case(AtomicComparator::OperatorGreaterOrEqual):
123 {
124 const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
125 return ret == AtomicComparator::GreaterThan || ret == AtomicComparator::Equal;
126 }
127 }
128
129 /* GCC unbarfer, this line should never be reached. */
130 Q_ASSERT(false);
131 return false;
132}
133
134template <typename TSubClass, bool issueError,
135 AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
136AtomicComparator::Ptr ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
137fetchComparator(const ItemType::Ptr &t1,
138 const ItemType::Ptr &t2,
139 const ReportContext::Ptr &context) const
140{
141 Q_ASSERT(t1);
142 Q_ASSERT(t2);
143
144 if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
145 *BuiltinTypes::xsAnyAtomicType == *t2 ||
146 *BuiltinTypes::item == *t1 ||
147 *BuiltinTypes::item == *t2 ||
148 *BuiltinTypes::numeric == *t1 ||
149 *BuiltinTypes::numeric == *t2 ||
150 *CommonSequenceTypes::Empty == *t1 ||
151 *CommonSequenceTypes::Empty == *t2)
152 {
153 /* The static type of(at least) one of the operands could not
154 * be narrowed further, so we do the operator
155 * lookup at runtime.
156 */
157 return AtomicComparator::Ptr();
158 }
159
160 const AtomicComparatorLocator::Ptr locator
161 (static_cast<const AtomicType *>(t1.data())->comparatorLocator());
162
163 if(!locator)
164 {
165 if(issueError)
166 {
167 context->error(QtXmlPatterns::tr("No comparisons can be done involving the type %1.")
168 .arg(formatType(context->namePool(), t1)),
169 errorCode, static_cast<const TSubClass *>(this)->actualReflection());
170 }
171 return AtomicComparator::Ptr();
172 }
173
174 const AtomicComparator::Ptr comp(static_cast<const AtomicType *>(t2.data())->accept(locator, operatorID(),
175 static_cast<const TSubClass *>(this)->actualReflection()));
176
177 if(comp)
178 return comp;
179 else if(issueError)
180 {
181 context->error(QtXmlPatterns::tr("Operator %1 is not available between atomic values of type %2 and %3.")
182 .arg(formatKeyword(AtomicComparator::displayName(operatorID(),
183 comparisonType)),
184 formatType(context->namePool(), t1),
185 formatType(context->namePool(), t2)),
186 errorCode, static_cast<const TSubClass *>(this)->actualReflection());
187 }
188
189 return AtomicComparator::Ptr();
190}
191
192template <typename TSubClass, bool issueError,
193 AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
194void ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
195prepareComparison(const AtomicComparator::Ptr &c)
196{
197 m_comparator = c;
198}
199
Note: See TracBrowser for help on using the repository browser.