134 if ( !lhs.isValid() )
136 return rhs.isValid() ? -1 : 0;
138 else if ( lhs.isNull() )
140 if ( !rhs.isValid() )
146 else if ( !rhs.isValid() || rhs.isNull() )
151 if ( strictTypeCheck && lhs.userType() != rhs.userType() )
153 return lhs.userType() < rhs.userType() ? -1 : 1;
157 switch ( lhs.userType() )
159 case QMetaType::Type::Int:
160 case QMetaType::Type::Char:
161 case QMetaType::Type::Short:
163 switch ( rhs.userType() )
165 case QMetaType::Type::Int:
166 case QMetaType::Type::Char:
167 case QMetaType::Type::Short:
169 const int lhsInt = lhs.toInt();
170 const int rhsInt = rhs.toInt();
171 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
174 case QMetaType::Type::Long:
175 case QMetaType::Type::LongLong:
177 const long long lhsInt = lhs.toLongLong();
178 const long long rhsInt = rhs.toLongLong();
179 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
182 case QMetaType::Type::Double:
183 case QMetaType::Type::Float:
185 const double lhsDouble =
static_cast< double >( lhs.toInt() );
186 const double rhsDouble = rhs.toDouble();
189 const bool lhsIsNan = std::isnan( lhsDouble );
190 const bool rhsIsNan = std::isnan( rhsDouble );
193 return rhsIsNan ? 0 : -1;
200 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
203 case QMetaType::Type::QString:
206 const double rhsDouble = rhs.toDouble( &ok );
209 const double lhsDouble =
static_cast< double >( lhs.toInt() );
210 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
221 case QMetaType::Type::UInt:
222 case QMetaType::Type::UChar:
223 case QMetaType::Type::UShort:
225 switch ( rhs.userType() )
227 case QMetaType::Type::UInt:
228 case QMetaType::Type::UChar:
229 case QMetaType::Type::UShort:
231 const uint lhsUInt = lhs.toUInt();
232 const uint rhsUInt = rhs.toUInt();
233 return lhsUInt < rhsUInt ? -1 : ( lhsUInt == rhsUInt ? 0 : 1 );
236 case QMetaType::Type::ULong:
237 case QMetaType::Type::ULongLong:
239 const qulonglong lhsInt = lhs.toULongLong();
240 const qulonglong rhsInt = rhs.toULongLong();
241 return lhsInt < rhsInt ? -1 : ( lhsInt == rhsInt ? 0 : 1 );
244 case QMetaType::Type::Double:
245 case QMetaType::Type::Float:
247 const double lhsDouble =
static_cast< double >( lhs.toUInt() );
248 const double rhsDouble = rhs.toDouble();
251 const bool lhsIsNan = std::isnan( lhsDouble );
252 const bool rhsIsNan = std::isnan( rhsDouble );
255 return rhsIsNan ? 0 : -1;
262 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
265 case QMetaType::Type::QString:
268 const double rhsDouble = rhs.toDouble( &ok );
271 const double lhsDouble =
static_cast< double >( lhs.toUInt() );
272 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
283 case QMetaType::Type::LongLong:
284 case QMetaType::Type::Long:
286 switch ( rhs.userType() )
288 case QMetaType::Type::Int:
289 case QMetaType::Type::Char:
290 case QMetaType::Type::Short:
291 case QMetaType::Type::LongLong:
292 case QMetaType::Type::Long:
294 const qlonglong lhsLongLong = lhs.toLongLong();
295 const qlonglong rhsLongLong = rhs.toLongLong();
296 return lhsLongLong < rhsLongLong ? -1 : ( lhsLongLong == rhsLongLong ? 0 : 1 );
299 case QMetaType::Type::Double:
300 case QMetaType::Type::Float:
302 const double lhsDouble =
static_cast< double >( lhs.toLongLong() );
303 const double rhsDouble = rhs.toDouble();
306 const bool lhsIsNan = std::isnan( lhsDouble );
307 const bool rhsIsNan = std::isnan( rhsDouble );
310 return rhsIsNan ? 0 : -1;
317 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
320 case QMetaType::Type::QString:
323 const double rhsDouble = rhs.toDouble( &ok );
326 const double lhsDouble =
static_cast< double >( lhs.toLongLong() );
327 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
338 case QMetaType::Type::ULongLong:
339 case QMetaType::Type::ULong:
341 switch ( rhs.userType() )
343 case QMetaType::Type::UInt:
344 case QMetaType::Type::UChar:
345 case QMetaType::Type::UShort:
346 case QMetaType::Type::ULongLong:
347 case QMetaType::Type::ULong:
349 const qulonglong lhsULongLong = lhs.toULongLong();
350 const qulonglong rhsULongLong = rhs.toULongLong();
351 return lhsULongLong < rhsULongLong ? -1 : ( lhsULongLong == rhsULongLong ? 0 : 1 );
360 case QMetaType::Type::Double:
362 switch ( rhs.userType() )
364 case QMetaType::Type::Int:
365 case QMetaType::Type::Char:
366 case QMetaType::Type::Short:
367 case QMetaType::Type::Double:
368 case QMetaType::Type::Float:
369 case QMetaType::Type::LongLong:
370 case QMetaType::Type::Long:
371 case QMetaType::Type::ULongLong:
372 case QMetaType::Type::ULong:
373 case QMetaType::Type::QString:
375 const double lhsDouble = lhs.toDouble();
376 bool rhsIsDoubleCompatible =
false;
377 const double rhsDouble = rhs.toDouble( &rhsIsDoubleCompatible );
378 if ( rhsIsDoubleCompatible )
381 const bool lhsIsNan = std::isnan( lhsDouble );
382 const bool rhsIsNan = std::isnan( rhsDouble );
385 return rhsIsNan ? 0 : -1;
392 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
403 case QMetaType::Type::Float:
405 switch ( rhs.userType() )
407 case QMetaType::Type::Int:
408 case QMetaType::Type::Char:
409 case QMetaType::Type::Short:
410 case QMetaType::Type::Double:
411 case QMetaType::Type::Float:
412 case QMetaType::Type::LongLong:
413 case QMetaType::Type::Long:
414 case QMetaType::Type::ULongLong:
415 case QMetaType::Type::ULong:
416 case QMetaType::Type::QString:
418 const float lhsFloat = lhs.toFloat();
419 bool rhsIsFloatCompatible =
false;
420 const float rhsFloat = rhs.toFloat( &rhsIsFloatCompatible );
421 if ( rhsIsFloatCompatible )
424 const bool lhsIsNan = std::isnan( lhsFloat );
425 const bool rhsIsNan = std::isnan( rhsFloat );
428 return rhsIsNan ? 0 : -1;
435 return lhsFloat < rhsFloat ? -1 : ( lhsFloat == rhsFloat ? 0 : 1 );
445 case QMetaType::Type::QChar:
447 if ( rhs.userType() == QMetaType::Type::QChar )
449 const QChar lhsChar = lhs.toChar();
450 const QChar rhsChar = rhs.toChar();
451 return lhsChar < rhsChar ? -1 : ( lhsChar == rhsChar ? 0 : 1 );
456 case QMetaType::Type::QDate:
458 if ( rhs.userType() == QMetaType::Type::QDate )
460 const QDate lhsDate = lhs.toDate();
461 const QDate rhsDate = rhs.toDate();
462 return lhsDate < rhsDate ? -1 : ( lhsDate == rhsDate ? 0 : 1 );
467 case QMetaType::Type::QTime:
469 if ( rhs.userType() == QMetaType::Type::QTime )
471 const QTime lhsTime = lhs.toTime();
472 const QTime rhsTime = rhs.toTime();
473 return lhsTime < rhsTime ? -1 : ( lhsTime == rhsTime ? 0 : 1 );
478 case QMetaType::Type::QDateTime:
480 if ( rhs.userType() == QMetaType::Type::QDateTime )
482 const QDateTime lhsTime = lhs.toDateTime();
483 const QDateTime rhsTime = rhs.toDateTime();
484 return lhsTime < rhsTime ? -1 : ( lhsTime == rhsTime ? 0 : 1 );
489 case QMetaType::Type::Bool:
491 if ( rhs.userType() == QMetaType::Type::Bool )
493 const bool lhsBool = lhs.toBool();
494 const bool rhsBool = rhs.toBool();
495 return lhsBool == rhsBool ? 0 : ( lhsBool ? 1 : -1 );
500 case QMetaType::Type::QVariantList:
502 if ( rhs.userType() == QMetaType::Type::QVariantList )
504 const QList<QVariant> &lhsl = lhs.toList();
505 const QList<QVariant> &rhsl = rhs.toList();
507 int i, n = std::min( lhsl.size(), rhsl.size() );
508 for ( i = 0; i < n && lhsl[i].userType() == rhsl[i].userType() &&
qgsVariantCompare( lhsl[i], rhsl[i] ) == 0; i++ )
512 return lhsl.size() < rhsl.size() ? -1 : ( lhsl.size() > rhsl.size() ? 1 : 0 );
519 case QMetaType::Type::QStringList:
521 if ( rhs.userType() == QMetaType::Type::QStringList )
523 const QStringList &lhsl = lhs.toStringList();
524 const QStringList &rhsl = rhs.toStringList();
526 int i, n = std::min( lhsl.size(), rhsl.size() );
527 for ( i = 0; i < n && lhsl[i] == rhsl[i]; i++ )
531 return lhsl.size() < rhsl.size() ? -1 : ( lhsl.size() > rhsl.size() ? 1 : 0 );
533 return lhsl[i] < rhsl[i] ? -1 : ( lhsl[i] == rhsl[i] ? 0 : 1 );
538 case QMetaType::Type::QString:
540 switch ( rhs.userType() )
542 case QMetaType::Type::Int:
543 case QMetaType::Type::Char:
544 case QMetaType::Type::Short:
545 case QMetaType::Type::Double:
546 case QMetaType::Type::Float:
547 case QMetaType::Type::LongLong:
548 case QMetaType::Type::Long:
549 case QMetaType::Type::ULongLong:
550 case QMetaType::Type::ULong:
553 bool lhsIsDoubleCompatible =
false;
554 const double lhsDouble = lhs.toDouble( &lhsIsDoubleCompatible );
555 if ( lhsIsDoubleCompatible )
557 const double rhsDouble = rhs.toDouble();
559 const bool lhsIsNan = std::isnan( lhsDouble );
560 const bool rhsIsNan = std::isnan( rhsDouble );
563 return rhsIsNan ? 0 : -1;
570 return lhsDouble < rhsDouble ? -1 : ( lhsDouble == rhsDouble ? 0 : 1 );
585 return std::clamp( QString::localeAwareCompare( lhs.toString(), rhs.toString() ), -1, 1 );