QList: Satisfy contiguous_range requirements

With C++20, there is a new iterator_category: contiguous_iterator, for
containers whose elements are stored contiguously in memory. In Qt 6,
QList satisfies this requirement.

However, we still need to tell the standard machinery about it. Step one
is to mark the iterators as contiguous_iterator; as that exists only in
C++20, we have to ifdef accordingly.
We also have to ensure that the iterators satisfy pointer_traits by
defining element_type due to how contiguous_range is specified. As this
runs afoul of LWG 3346, we check for known bad _GLIBCXX_RELEASE
versions.

Change-Id: I8c134544e694ba937e4d912393eb72fa75b49e3d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
bb10
Fabian Kosmale 2021-03-29 14:13:46 +02:00
parent 0eb0fc8701
commit 595b4e1a9b
2 changed files with 35 additions and 2 deletions

View File

@ -132,9 +132,16 @@ public:
class iterator {
T *i = nullptr;
public:
using iterator_category = std::random_access_iterator_tag;
using difference_type = qsizetype;
using value_type = T;
// libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
using iterator_category = std::contiguous_iterator_tag;
#else
using iterator_category = std::random_access_iterator_tag;
#endif
using element_type = value_type;
using pointer = T *;
using reference = T &;
@ -167,9 +174,15 @@ public:
class const_iterator {
const T *i = nullptr;
public:
using iterator_category = std::random_access_iterator_tag;
using difference_type = qsizetype;
using value_type = T;
// libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
using iterator_category = std::contiguous_iterator_tag;
#else
using iterator_category = std::random_access_iterator_tag;
#endif
using element_type = const value_type;
using pointer = const T *;
using reference = const T &;

View File

@ -33,6 +33,26 @@
#include <QScopedValueRollback>
#include <qlist.h>
#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
# if __has_include(<concepts>)
# include <concepts>
# if defined(__cpp_concepts)
static_assert(std::contiguous_iterator<QList<int>::iterator>);
static_assert(std::contiguous_iterator<QList<int>::const_iterator>);
# endif
# endif
# if __has_include(<ranges>)
# include <ranges>
# if defined(__cpp_lib_ranges)
namespace rns = std::ranges;
static_assert(rns::contiguous_range<QList<int>>);
static_assert(rns::contiguous_range<const QList<int>>);
# endif
# endif
#endif
struct Movable {
Movable(char input = 'j')
: i(input)