18 #ifndef NURIA_VARIANT_HPP
19 #define NURIA_VARIANT_HPP
21 #include "essentials.hpp"
22 #include <QStringList>
27 class VariantIteratorPrivate;
118 typedef bool (*Comparison)(
const void *,
const void *);
123 typedef void *(*Conversion)(
const void *);
126 typedef void (*IteratorDtorFunc)(
void *);
129 typedef void *(*IteratorCopyFunc)(
void *);
132 typedef QVariant (*IteratorValueFunc)(
void *, int);
135 typedef void (*IteratorIncFunc)(
void *);
138 typedef void *(*IteratorMoveFunc)(
void *, int);
141 typedef int (*IteratorDistanceFunc)(
void *,
void *);
144 typedef void *(*IteratorStartEndFunc)(
void *);
147 typedef bool (*IteratorComparisonFunc)(
void *,
void *);
150 typedef int (*IteratorCountFunc)(
void *);
153 typedef void *(*IteratorFindFunc)(
void *,
const QVariant &);
159 static bool equal (
const QVariant &left,
const QVariant &right);
160 static bool notEqual (
const QVariant &left,
const QVariant &right);
162 static bool lessThan (
const QVariant &left,
const QVariant &right);
163 static bool greaterThan (
const QVariant &left,
const QVariant &right);
165 static bool lessEqualThan (
const QVariant &left,
const QVariant &right);
166 static bool greaterEqualThan (
const QVariant &left,
const QVariant &right);
178 inline static bool canCompare (
const QVariant &left,
const QVariant &right)
179 {
return canCompare (left.userType (), right.userType ()); }
184 inline static bool canCompare (
const QVariant &left,
int rightType)
185 {
return canCompare (left.userType (), rightType); }
190 template<
typename Right >
inline static bool canCompare (
const QVariant &left)
191 {
return canCompare (left.userType (), qMetaTypeId< Right > ()); }
196 template<
typename Left,
typename Right >
inline static bool canCompare ()
197 {
return canCompare (qMetaTypeId< Left > (), qMetaTypeId< Right > ()); }
202 static bool canCompare (
int leftType,
int rightType);
215 static QVariant convert (
const QVariant &variant,
int type);
220 template<
typename T >
static QVariant
convert (
const QVariant &variant)
221 {
return convert (variant, qMetaTypeId< T > ()); }
236 template<
typename T >
inline static bool canConvert (
const QVariant &variant)
237 {
return canConvert (variant.userType (), qMetaTypeId< T > ()); }
243 inline static bool canConvert (
const QVariant &variant,
int toType)
244 {
return canConvert (variant.userType (), toType); }
249 static bool canConvert (
int fromType,
int toType);
257 template<
typename T >
static T
toValue (
const QVariant &variant) {
258 QVariant result = convert (variant, qMetaTypeId< T > ());
260 if (result.isValid ()) {
261 return result.value< T > ();
280 { registerType< T, T > (); }
287 template<
typename T,
typename Right >
inline static void registerType () {
288 typedef bool(T::*Func)(
const Right &)
const;
289 Func equal = &T::operator==;
290 Func less = &T::operator<;
291 registerType (qMetaTypeId< T > (), qMetaTypeId< Right > (),
292 (Comparison)equal, (Comparison)less);
302 static void registerType (
int type,
int rightType, Comparison equal, Comparison lessThan);
309 static void registerType (
int type,
int rightType, Comparison equal, Comparison notEqual,
310 Comparison less, Comparison greater, Comparison lessEqual,
311 Comparison greaterEqual);
320 template<
typename From,
typename To >
322 { registerConversion (qMetaTypeId< From > (), qMetaTypeId< To > (), (Conversion)func); }
334 template<
typename From,
typename To >
336 auto func = &autoConvTempl< From, To >;
337 registerConversion (qMetaTypeId< From > (), qMetaTypeId< To > (), (Conversion)func);
345 static void registerConversion (
int from,
int to, Conversion func);
351 template<
typename T >
354 int keyType = qMetaTypeId< typename T::key_type > ();
355 int valueType = qMetaTypeId< typename T::mapped_type > ();
357 registerIterator (qMetaTypeId< T > (), valueType, keyType,
358 (IteratorDtorFunc)&iteratorDtor< T >,
359 (IteratorCopyFunc)&iteratorCopy< T >,
360 (IteratorStartEndFunc)&iteratorBegin< T >,
361 (IteratorStartEndFunc)&iteratorEnd< T >,
362 (IteratorIncFunc)&iteratorNext< T >,
363 (IteratorIncFunc)&iteratorPrev< T >,
364 (IteratorMoveFunc)&iteratorMove< T >,
365 (IteratorDistanceFunc)&iteratorDistance< T >,
366 (IteratorValueFunc)&iteratorValue< T >,
367 (IteratorValueFunc)&iteratorKey< T >,
368 (IteratorComparisonFunc)&iteratorEqual< T >,
369 (IteratorCountFunc)&iteratorCount< T >,
370 (IteratorFindFunc)&iteratorFindMap< T, typename T::key_type >);
378 template<
typename T >
381 int valueType = qMetaTypeId< typename T::value_type > ();
383 registerIterator (qMetaTypeId< T > (), valueType, 0,
384 (IteratorDtorFunc)&iteratorDtor< T >,
385 (IteratorCopyFunc)&iteratorCopy< T >,
386 (IteratorStartEndFunc)&iteratorBegin< T >,
387 (IteratorStartEndFunc)&iteratorEnd< T >,
388 (IteratorIncFunc)&iteratorNext< T >,
389 (IteratorIncFunc)&iteratorPrev< T >,
390 (IteratorMoveFunc)&iteratorMove< T >,
391 (IteratorDistanceFunc)&iteratorDistance< T >,
392 (IteratorValueFunc)&iteratorValue< T >,
394 (IteratorComparisonFunc)&iteratorEqual< T >,
395 (IteratorCountFunc)&iteratorCount< T >,
396 (IteratorFindFunc)&iteratorFindList< T, typename T::value_type >);
418 bool isValid ()
const;
422 bool operator== (
const Iterator &other)
const;
423 inline bool operator!= (
const Iterator &other)
const
424 {
return !(*
this == other); }
427 inline Iterator &operator++ (
int) {
return operator++ (); }
430 inline Iterator &operator-- (
int) {
return operator--(); }
435 int operator- (
const Iterator &other)
const;
442 QVariant key ()
const;
443 QVariant value ()
const;
445 inline QVariant operator* ()
const
450 Iterator (
const QVariant &variant,
void *iter,
void *info,
int pos);
451 VariantIteratorPrivate *d_ptr;
479 static Iterator find (QVariant &variant, QVariant ident);
487 static int itemCount (
const QVariant &variant);
493 static bool isList (
const QVariant &variant);
496 static bool isList (
int typeId);
501 static bool isMap (
const QVariant &variant);
504 static bool isMap (
int typeId);
510 static bool isGeneric (
const QVariant &variant);
523 static QVariantList
toList (QVariant variant);
534 static QVariantMap
toMap (QVariant variant);
546 template<
typename ... Items >
547 static QVariantList
buildList (
const Items &... items) {
549 buildListImpl (list, items ...);
572 template<
typename T >
inline static void iteratorDtor (
void *t)
573 {
delete (
typename T::const_iterator *)t; }
575 template<
typename T >
inline static void *iteratorCopy (
void *t)
576 {
return (
void *)(
new typename T::const_iterator (*(
typename T::const_iterator *)t)); }
578 template<
typename T >
inline static void *iteratorBegin (
void *t)
579 {
return (
void *)(
new typename T::const_iterator (((T *)t)->constBegin ())); }
581 template<
typename T >
inline static void *iteratorEnd (
void *t)
582 {
return (
void *)(
new typename T::const_iterator (((T *)t)->constEnd ())); }
584 template<
typename T >
inline static void iteratorMove (
void *t,
int n)
585 { (*
static_cast< typename T::const_iterator *
> (t)) += n; }
587 template<
typename T >
inline static int iteratorDistance (
void *t,
void *o) {
588 typename T::const_iterator *l =
static_cast< typename T::const_iterator *
> (t);
589 typename T::const_iterator *r =
static_cast< typename T::const_iterator *
> (o);
590 return std::distance (*l, *r);
593 template<
typename T >
inline static void iteratorNext (
void *t)
594 { ++(*
static_cast< typename T::const_iterator *
> (t)); }
596 template<
typename T >
inline static void iteratorPrev (
void *t)
597 { --(*
static_cast< typename T::const_iterator *
> (t)); }
599 template<
typename T >
inline static QVariant iteratorKey (
void *t,
int type)
600 {
return QVariant::fromValue (static_cast< typename T::const_iterator * > (t)->key ()); }
602 template<
typename T >
inline static QVariant iteratorValue (
void *t,
int) {
603 return QVariant::fromValue (*(*static_cast< typename T::const_iterator * > (t)));
606 template<
typename T >
inline static bool iteratorEqual (
void *t,
void *r) {
607 typename T::const_iterator &left = *
static_cast< typename T::const_iterator *
> (t);
608 typename T::const_iterator &right = *
static_cast< typename T::const_iterator *
> (r);
609 return (left == right);
612 template<
typename T >
inline static int iteratorCount (
void *t)
613 {
return static_cast< T *
> (t)->count (); }
615 template<
typename T,
typename Key >
inline static void *iteratorFindMap (
void *t,
const QVariant &what) {
616 typename T::const_iterator it =
static_cast< T *
> (t)
617 ->
find (*static_cast< const Key * >(what.constData ()));
618 if (it == static_cast< T * > (t)->end ())
620 return (
void *)(
new typename T::const_iterator (it));
623 template<
typename T,
typename Key >
inline static void *iteratorFindList (
void *t,
const QVariant &what) {
624 T *list =
static_cast< T *
> (t);
625 const Key *item =
static_cast< const Key *
> (qMetaTypeId< Key > () == QMetaType::QVariant
626 ? &what : what.constData ());
628 typename T::const_iterator it = list->begin ();
629 typename T::const_iterator
end = list->end ();
631 if (qMetaTypeId< Key > () != QMetaType::QVariant) {
632 for (; it !=
end; ++it) {
633 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
634 if (equal (*it, what))
636 if ((*it).operator== (*item))
638 return new typename T::const_iterator (it);
641 for (; it !=
end; ++it) {
642 if (equal (*it, *item))
643 return new typename T::const_iterator (it);
653 template<
typename From,
typename To >
654 static To *autoConvTempl (From *from)
655 {
return new To (*from); }
660 static void registerIterator (
int type,
int valueType,
int keyType,
661 IteratorDtorFunc dtor, IteratorCopyFunc copy,
662 IteratorStartEndFunc start, IteratorStartEndFunc end,
663 IteratorIncFunc increment, IteratorIncFunc decrement,
664 IteratorMoveFunc move, IteratorDistanceFunc distance,
665 IteratorValueFunc value, IteratorValueFunc key,
666 IteratorComparisonFunc equal,
667 IteratorCountFunc count, IteratorFindFunc
find);
670 template<
typename T >
static inline const T &passThrough (
const T &t) {
return t; }
673 #ifndef NURIA_NO_CHAR_ARRAY_TO_QSTRING
674 static inline QString passThrough (
const char *str) {
return QString (str); }
678 static inline void buildListImpl (QVariantList &) { }
681 template<
typename T,
typename ... Items >
682 static inline void buildListImpl (QVariantList &list,
const T &cur,
const Items & ... items) {
683 list.append (QVariant::fromValue (passThrough (cur)));
684 buildListImpl (list, items ...);
694 #ifdef NURIA_VARIANT_COMPARISON
695 inline bool operator== (
const QVariant &left,
const QVariant &right)
696 {
return Nuria::Variant::equal (left, right); }
698 inline bool operator!= (
const QVariant &left,
const QVariant &right)
699 {
return Nuria::Variant::notEqual (left, right); }
701 inline bool operator< (
const QVariant &left,
const QVariant &right)
702 {
return Nuria::Variant::lessThan (left, right); }
704 inline bool operator> (
const QVariant &left,
const QVariant &right)
705 {
return Nuria::Variant::greaterThan (left, right); }
707 inline bool operator<= (
const QVariant &left,
const QVariant &right)
708 {
return Nuria::Variant::lessEqualThan (left, right); }
710 inline bool operator>= (
const QVariant &left,
const QVariant &right)
711 {
return Nuria::Variant::greaterEqualThan (left, right); }
717 #define VARIANT_FOREACH(variable, variant) \
718 for (Nuria::Variant::Iterator _niter_ = Nuria::Variant::begin (variant), \
719 _nend_ = Nuria::Variant::end (variant); \
720 _niter_ != _nend_; ++_niter_) \
721 if (!(variable = _niter_.value()).isNull ())
723 #endif // NURIA_VARIANT_HPP
static void registerType()
Definition: variant.hpp:287
static bool isMap(const QVariant &variant)
static bool canCompare(const QVariant &left, int rightType)
Definition: variant.hpp:184
The Variant class provides utilities for working with QVariants. Working with QVariants can be tediou...
Definition: variant.hpp:112
static void * stealPointer(QVariant &variant)
static void registerIterators(typename T::mapped_type *a=(typename T::mapped_type *) 0)
Definition: variant.hpp:352
static Iterator begin(QVariant &variant)
static QVariantList buildList(const Items &...items)
Definition: variant.hpp:547
static bool canCompare(const QVariant &left, const QVariant &right)
Definition: variant.hpp:178
static bool canCompare(const QVariant &left)
Definition: variant.hpp:190
static Iterator find(QVariant &variant, QVariant ident)
static QVariantList toList(QVariant variant)
static bool canConvert(const QVariant &variant)
Definition: variant.hpp:236
static bool canConvert(const QVariant &variant, int toType)
Definition: variant.hpp:243
static void registerConversion()
Definition: variant.hpp:335
static void registerIterators(typename T::value_type *a=(typename T::value_type *) 0)
Definition: variant.hpp:379
static bool isGeneric(const QVariant &variant)
static void registerType()
Definition: variant.hpp:279
static T toValue(const QVariant &variant)
Definition: variant.hpp:257
static QVariant convert(const QVariant &variant)
Definition: variant.hpp:220
static int itemCount(const QVariant &variant)
static Iterator end(QVariant &variant)
static bool isList(const QVariant &variant)
static void registerConversion(To *(*func)(const From &))
Definition: variant.hpp:321
Definition: variant.hpp:407
static bool canCompare()
Definition: variant.hpp:196
static QVariantMap toMap(QVariant variant)