diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,7 +270,6 @@ ) #add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) -add_definitions(-DQT_STRICT_ITERATORS) add_subdirectory(src) add_subdirectory(icons) diff --git a/src/shared/akranges.h b/src/shared/akranges.h --- a/src/shared/akranges.h +++ b/src/shared/akranges.h @@ -20,13 +20,6 @@ #ifndef AKONADI_AKRANGES_H #define AKONADI_AKRANGES_H -#ifndef QT_STRICT_ITERATORS -// Without strict iterator QVector::iterator is just a typedef to T*, -// which breaks some of the template magic below. QT_STRICT_ITERATORS -// are a good thing anyway... -#error AkRanges requires QT_STRICT_ITERATORS to be enabled. -#endif - #include "aktraits.h" #include "akhelpers.h" @@ -38,6 +31,7 @@ #include #include #include +#include namespace Akonadi { @@ -79,18 +73,49 @@ return rv; } +template +struct IteratorTrait { + using iterator_category = typename Iterator::iterator_category; + using value_type = typename Iterator::value_type; + using difference_type = typename Iterator::difference_type; + using pointer = typename Iterator::pointer; + using reference = typename Iterator::reference; +}; + +// Without QT_STRICT_ITERATORS QVector and QList iterators do not satisfy STL +// iterator concepts since they are nothing more but typedefs to T* - for those +// we need to provide custom traits. +template +struct IteratorTrait { + // QTypedArrayData::iterator::iterator_category + using iterator_category = std::random_access_iterator_tag; + using value_type = Iterator; + using difference_type = int; + using pointer = Iterator*; + using reference = Iterator&; +}; + +template +struct IteratorTrait { + using iterator_category = std::random_access_iterator_tag; + using value_type = Iterator; + using difference_type = int; + using pointer = const Iterator *; + using reference = const Iterator &; +}; + template struct IteratorBase { public: - using iterator_category = typename Iterator::iterator_category; - using value_type = typename Iterator::value_type; - using difference_type = typename Iterator::difference_type; - using pointer = typename Iterator::pointer; - using reference = typename Iterator::reference; + using iterator_category = typename IteratorTrait::iterator_category; + using value_type = typename IteratorTrait::value_type; + using difference_type = typename IteratorTrait::difference_type; + using pointer = typename IteratorTrait::pointer; + using reference = typename IteratorTrait::reference; IteratorBase(const IteratorBase &other) : mIter(other.mIter), mContainer(other.mContainer) @@ -163,7 +188,7 @@ template using FuncHelper = decltype(Akonadi::invoke(std::declval() ...))(Ts ...); - using IteratorValueType = typename ResultOf>::type; + using IteratorValueType = typename ResultOf::value_type>>::type; public: using value_type = IteratorValueType; using pointer = IteratorValueType *; // FIXME: preserve const-ness @@ -259,7 +284,7 @@ public: using iterator = Iterator; using const_iterator = Iterator; - using value_type = typename Iterator::value_type; + using value_type = typename detail::IteratorTrait::value_type; Range(Iterator &&begin, Iterator &&end) : mBegin(std::move(begin))