142 if ( !lhs.isValid() )
144 return rhs.isValid() ? -1 : 0;
146 else if ( lhs.isNull() )
148 if ( !rhs.isValid() )
154 else if ( !rhs.isValid() || rhs.isNull() )
159 if ( strictTypeCheck && lhs.userType() != rhs.userType() )
161 return lhs.userType() < rhs.userType() ? -1 : 1;
165 switch ( lhs.userType() )
167 case QMetaType::Type::Int:
168 case QMetaType::Type::Char:
169 case QMetaType::Type::Short:
171 switch ( rhs.userType() )
173 case QMetaType::Type::Int:
174 case QMetaType::Type::Char:
175 case QMetaType::Type::Short:
177 const int lhsInt = lhs.toInt();
178 const int rhsInt = rhs.toInt();
179 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
182 case QMetaType::Type::Long:
183 case QMetaType::Type::LongLong:
185 const long long lhsInt = lhs.toLongLong();
186 const long long rhsInt = rhs.toLongLong();
187 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
190 case QMetaType::Type::Double:
191 case QMetaType::Type::Float:
193 const double lhsDouble =
static_cast< double >( lhs.toInt() );
194 const double rhsDouble = rhs.toDouble();
197 const bool lhsIsNan = std::isnan( lhsDouble );
198 const bool rhsIsNan = std::isnan( rhsDouble );
201 return rhsIsNan ? 0 : -1;
208 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
211 case QMetaType::Type::QString:
214 const double rhsDouble = rhs.toDouble( &ok );
217 const double lhsDouble =
static_cast< double >( lhs.toInt() );
218 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
229 case QMetaType::Type::UInt:
230 case QMetaType::Type::UChar:
231 case QMetaType::Type::UShort:
233 switch ( rhs.userType() )
235 case QMetaType::Type::UInt:
236 case QMetaType::Type::UChar:
237 case QMetaType::Type::UShort:
239 const uint lhsUInt = lhs.toUInt();
240 const uint rhsUInt = rhs.toUInt();
241 return lhsUInt < rhsUInt ? -1 : ( lhsUInt == rhsUInt ? 0 : 1 );
244 case QMetaType::Type::ULong:
245 case QMetaType::Type::ULongLong:
247 const qulonglong lhsInt = lhs.toULongLong();
248 const qulonglong rhsInt = rhs.toULongLong();
249 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
252 case QMetaType::Type::Double:
253 case QMetaType::Type::Float:
255 const double lhsDouble =
static_cast< double >( lhs.toUInt() );
256 const double rhsDouble = rhs.toDouble();
259 const bool lhsIsNan = std::isnan( lhsDouble );
260 const bool rhsIsNan = std::isnan( rhsDouble );
263 return rhsIsNan ? 0 : -1;
270 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
273 case QMetaType::Type::QString:
276 const double rhsDouble = rhs.toDouble( &ok );
279 const double lhsDouble =
static_cast< double >( lhs.toUInt() );
280 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
291 case QMetaType::Type::LongLong:
292 case QMetaType::Type::Long:
294 switch ( rhs.userType() )
296 case QMetaType::Type::Int:
297 case QMetaType::Type::Char:
298 case QMetaType::Type::Short:
299 case QMetaType::Type::LongLong:
300 case QMetaType::Type::Long:
302 const qlonglong lhsLongLong = lhs.toLongLong();
303 const qlonglong rhsLongLong = rhs.toLongLong();
304 return lhsLongLong < rhsLongLong ? -1 : ( lhsLongLong == rhsLongLong ? 0 : 1 );
307 case QMetaType::Type::Double:
308 case QMetaType::Type::Float:
310 const double lhsDouble =
static_cast< double >( lhs.toLongLong() );
311 const double rhsDouble = rhs.toDouble();
314 const bool lhsIsNan = std::isnan( lhsDouble );
315 const bool rhsIsNan = std::isnan( rhsDouble );
318 return rhsIsNan ? 0 : -1;
325 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
328 case QMetaType::Type::QString:
331 const double rhsDouble = rhs.toDouble( &ok );
334 const double lhsDouble =
static_cast< double >( lhs.toLongLong() );
335 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
346 case QMetaType::Type::ULongLong:
347 case QMetaType::Type::ULong:
349 switch ( rhs.userType() )
351 case QMetaType::Type::UInt:
352 case QMetaType::Type::UChar:
353 case QMetaType::Type::UShort:
354 case QMetaType::Type::ULongLong:
355 case QMetaType::Type::ULong:
357 const qulonglong lhsULongLong = lhs.toULongLong();
358 const qulonglong rhsULongLong = rhs.toULongLong();
359 return lhsULongLong < rhsULongLong ? -1 : ( lhsULongLong == rhsULongLong ? 0 : 1 );
368 case QMetaType::Type::Double:
370 switch ( rhs.userType() )
372 case QMetaType::Type::Int:
373 case QMetaType::Type::Char:
374 case QMetaType::Type::Short:
375 case QMetaType::Type::Double:
376 case QMetaType::Type::Float:
377 case QMetaType::Type::LongLong:
378 case QMetaType::Type::Long:
379 case QMetaType::Type::ULongLong:
380 case QMetaType::Type::ULong:
381 case QMetaType::Type::QString:
383 const double lhsDouble = lhs.toDouble();
384 bool rhsIsDoubleCompatible =
false;
385 const double rhsDouble = rhs.toDouble( &rhsIsDoubleCompatible );
386 if ( rhsIsDoubleCompatible )
389 const bool lhsIsNan = std::isnan( lhsDouble );
390 const bool rhsIsNan = std::isnan( rhsDouble );
393 return rhsIsNan ? 0 : -1;
400 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
411 case QMetaType::Type::Float:
413 switch ( rhs.userType() )
415 case QMetaType::Type::Int:
416 case QMetaType::Type::Char:
417 case QMetaType::Type::Short:
418 case QMetaType::Type::Double:
419 case QMetaType::Type::Float:
420 case QMetaType::Type::LongLong:
421 case QMetaType::Type::Long:
422 case QMetaType::Type::ULongLong:
423 case QMetaType::Type::ULong:
424 case QMetaType::Type::QString:
426 const float lhsFloat = lhs.toFloat();
427 bool rhsIsFloatCompatible =
false;
428 const float rhsFloat = rhs.toFloat( &rhsIsFloatCompatible );
429 if ( rhsIsFloatCompatible )
432 const bool lhsIsNan = std::isnan( lhsFloat );
433 const bool rhsIsNan = std::isnan( rhsFloat );
436 return rhsIsNan ? 0 : -1;
443 return lhsFloat < rhsFloat ? -1 : ( lhsFloat == rhsFloat ? 0 : 1 );
453 case QMetaType::Type::QChar:
455 if ( rhs.userType() == QMetaType::Type::QChar )
457 const QChar lhsChar = lhs.toChar();
458 const QChar rhsChar = rhs.toChar();
459 return lhsChar < rhsChar ? -1 : ( lhsChar == rhsChar ? 0 : 1 );
464 case QMetaType::Type::QDate:
466 if ( rhs.userType() == QMetaType::Type::QDate )
468 const QDate lhsDate = lhs.toDate();
469 const QDate rhsDate = rhs.toDate();
470 return lhsDate < rhsDate ? -1 : ( lhsDate == rhsDate ? 0 : 1 );
475 case QMetaType::Type::QTime:
477 if ( rhs.userType() == QMetaType::Type::QTime )
479 const QTime lhsTime = lhs.toTime();
480 const QTime rhsTime = rhs.toTime();
481 return lhsTime < rhsTime ? -1 : ( lhsTime == rhsTime ? 0 : 1 );
486 case QMetaType::Type::QDateTime:
488 if ( rhs.userType() == QMetaType::Type::QDateTime )
490 const QDateTime lhsTime = lhs.toDateTime();
491 const QDateTime rhsTime = rhs.toDateTime();
492 return lhsTime < rhsTime ? -1 : ( lhsTime == rhsTime ? 0 : 1 );
497 case QMetaType::Type::Bool:
499 if ( rhs.userType() == QMetaType::Type::Bool )
501 const bool lhsBool = lhs.toBool();
502 const bool rhsBool = rhs.toBool();
503 return lhsBool == rhsBool ? 0 : ( lhsBool ? 1 : -1 );
508 case QMetaType::Type::QVariantList:
510 if ( rhs.userType() == QMetaType::Type::QVariantList )
512 const QList<QVariant> &lhsl = lhs.toList();
513 const QList<QVariant> &rhsl = rhs.toList();
515 int i, n = std::min( lhsl.size(), rhsl.size() );
516 for ( i = 0; i < n && lhsl[i].userType() == rhsl[i].userType() &&
qgsVariantCompare( lhsl[i], rhsl[i] ) == 0; i++ )
520 return lhsl.size() < rhsl.size() ? -1 : ( lhsl.size() > rhsl.size() ? 1 : 0 );
527 case QMetaType::Type::QStringList:
529 if ( rhs.userType() == QMetaType::Type::QStringList )
531 const QStringList &lhsl = lhs.toStringList();
532 const QStringList &rhsl = rhs.toStringList();
534 int i, n = std::min( lhsl.size(), rhsl.size() );
535 for ( i = 0; i < n && lhsl[i] == rhsl[i]; i++ )
539 return lhsl.size() < rhsl.size() ? -1 : ( lhsl.size() > rhsl.size() ? 1 : 0 );
541 return lhsl[i] < rhsl[i] ? -1 : ( lhsl[i] == rhsl[i] ? 0 : 1 );
546 case QMetaType::Type::QString:
548 switch ( rhs.userType() )
550 case QMetaType::Type::Int:
551 case QMetaType::Type::Char:
552 case QMetaType::Type::Short:
553 case QMetaType::Type::Double:
554 case QMetaType::Type::Float:
555 case QMetaType::Type::LongLong:
556 case QMetaType::Type::Long:
557 case QMetaType::Type::ULongLong:
558 case QMetaType::Type::ULong:
561 bool lhsIsDoubleCompatible =
false;
562 const double lhsDouble = lhs.toDouble( &lhsIsDoubleCompatible );
563 if ( lhsIsDoubleCompatible )
565 const double rhsDouble = rhs.toDouble();
567 const bool lhsIsNan = std::isnan( lhsDouble );
568 const bool rhsIsNan = std::isnan( rhsDouble );
571 return rhsIsNan ? 0 : -1;
578 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
593 return std::clamp( QString::localeAwareCompare( lhs.toString(), rhs.toString() ), -1, 1 );