Qt 4.8
qcomparisonplatform.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
48 template <typename TSubClass, bool issueError,
49  AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
50 bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
51 flexibleCompare(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 
68 template <typename TSubClass, bool issueError,
73  const Item &it2,
74  const DynamicContext::Ptr &context) const
75 {
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 
92 template <typename TSubClass, bool issueError,
95 compare(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 
134 template <typename TSubClass, bool issueError,
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 ||
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 
192 template <typename TSubClass, bool issueError,
196 {
197  m_comparator = c;
198 }
199 
static QString formatKeyword(const VariableDeclaration::Ptr &var, const NamePool::Ptr &np)
Formats var appropriately for display.
unsigned char c[8]
Definition: qnumeric_p.h:62
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
T * data() const
Returns a pointer to the shared data object.
Definition: qshareddata.h:145
static bool compare(const QVariant::Private *a, const QVariant::Private *b)
Compares a to b.
Definition: qvariant.cpp:383
QExplicitlySharedDataPointer< ItemType > type() const
Returns the ItemType this Item is of.
Definition: qitem_p.h:365
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
Represents an item in the XPath 2.0 Data Model.
Definition: qitem_p.h:182
Provides comparison functionality for classes that compare Items, such as ValueComparison or MaxFN...
bool(* LessThan)(const QPair< QListWidgetItem *, int > &, const QPair< QListWidgetItem *, int > &)
Definition: qlistwidget.cpp:53
#define Q_FUNC_INFO
Definition: qglobal.h:1871