15class QT_TECH_PREVIEW_API QRangeModelAdapter
17 using Impl = QRangeModelDetails::RangeImplementation<Range, Protocol>;
18 using Storage = QRangeModelDetails::AdapterStorage<Model, Impl>;
23 using range_type = Range;
25 using range_type = QRangeModelDetails::wrapped_t<Range>;
27 using const_row_reference =
typename Impl::const_row_reference;
28 using row_reference =
typename Impl::row_reference;
29 using range_features =
typename QRangeModelDetails::range_traits<range_type>;
30 using row_type = std::remove_reference_t<row_reference>;
31 using row_features = QRangeModelDetails::range_traits<
typename Impl::wrapped_row_type>;
32 using row_ptr =
typename Impl::wrapped_row_type *;
33 using row_traits =
typename Impl::row_traits;
34 using item_type = std::remove_reference_t<
typename row_traits::item_type>;
35 using data_type =
typename QRangeModelDetails::data_type<item_type>::type;
36 using const_data_type = QRangeModelDetails::asConst_t<data_type>;
37 using protocol_traits =
typename Impl::protocol_traits;
39 template <
typename I>
static constexpr bool is_list = I::protocol_traits::is_list;
40 template <
typename I>
static constexpr bool is_table = I::protocol_traits::is_table;
41 template <
typename I>
static constexpr bool is_tree = I::protocol_traits::is_tree;
42 template <
typename I>
static constexpr bool canInsertColumns = I::dynamicColumns()
44 && row_features::has_insert;
45 template <
typename I>
static constexpr bool canRemoveColumns = I::dynamicColumns()
47 && row_features::has_erase;
49 template <
typename I>
using if_writable = std::enable_if_t<I::isMutable(),
bool>;
50 template <
typename I>
using if_list = std::enable_if_t<is_list<I>,
bool>;
51 template <
typename I>
using unless_list = std::enable_if_t<!is_list<I>,
bool>;
52 template <
typename I>
using if_table = std::enable_if_t<is_table<I>,
bool>;
53 template <
typename I>
using if_tree = std::enable_if_t<is_tree<I>,
bool>;
54 template <
typename I>
using unless_tree = std::enable_if_t<!is_tree<I>,
bool>;
55 template <
typename I>
using if_flat = std::enable_if_t<is_list<I> || is_table<I>,
bool>;
58 using if_canInsertRows = std::enable_if_t<I::canInsertRows(),
bool>;
60 using if_canRemoveRows = std::enable_if_t<I::canRemoveRows(),
bool>;
62 using if_canMoveItems = std::enable_if_t<F::has_rotate || F::has_splice,
bool>;
65 using if_canInsertColumns = std::enable_if_t<canInsertColumns<I>,
bool>;
67 using if_canRemoveColumns = std::enable_if_t<canRemoveColumns<I>,
bool>;
69 template <
typename Row>
70 static constexpr bool is_compatible_row = std::is_convertible_v<Row, const_row_reference>;
71 template <
typename Row>
72 using if_compatible_row = std::enable_if_t<is_compatible_row<Row>,
bool>;
75 static constexpr bool is_compatible_row_range = is_compatible_row<
76 decltype(*std::begin(std::declval<C&>()))
79 using if_compatible_row_range = std::enable_if_t<is_compatible_row_range<C>,
bool>;
80 template <
typename Data>
81 static constexpr bool is_compatible_data = std::is_convertible_v<Data, data_type>;
82 template <
typename Data>
83 using if_compatible_data = std::enable_if_t<is_compatible_data<Data>,
bool>;
85 static constexpr bool is_compatible_data_range = is_compatible_data<
86 typename QRangeModelDetails::data_type<
87 typename QRangeModelDetails::row_traits<
88 decltype(*std::begin(std::declval<C&>()))
93 using if_compatible_column_data = std::enable_if_t<is_compatible_data<C>
94 || is_compatible_data_range<C>,
bool>;
96 using if_compatible_column_range = std::enable_if_t<is_compatible_data_range<C>,
bool>;
99 using if_assignable_range = std::enable_if_t<std::is_assignable_v<range_type, R>,
bool>;
101 friend class QRangeModel;
102 template <
typename T>
103 static constexpr bool is_adapter = QRangeModelDetails::is_any_of<q20::remove_cvref_t<T>,
104 QRangeModelAdapter>::value;
105 template <
typename T>
106 using unless_adapter = std::enable_if_t<!is_adapter<T>,
bool>;
108 template <
typename R,
typename P>
109 using if_compatible_model_params =
113 std::is_convertible<R &&, Range>,
114 std::is_convertible<R &&, Range &&>
116 std::is_convertible<P, Protocol>
119#if !defined(Q_OS_VXWORKS) && !defined(Q_OS_INTEGRITY)
125 template <
typename T>
static constexpr T asMutable(
const T &);
126 template <
typename T>
static constexpr T *asMutable(
const T *);
127 template <
template <
typename,
typename...>
typename U,
typename T,
typename ...Args>
128 static constexpr U<T, Args...> asMutable(
const U<
const T, Args...> &);
130 template <
typename T>
131 using asMutable_t =
decltype(asMutable(std::declval<T>()));
132 friend class QRangeModelAdapter<asMutable_t<Range>, Protocol, Model>;
134 template <
typename R,
typename P,
typename M>
135 friend class QRangeModelAdapter;
138 explicit QRangeModelAdapter(
const std::shared_ptr<QRangeModel> &model,
const QModelIndex &root,
140 : storage{model, root}
143 explicit QRangeModelAdapter(QRangeModel *model)
151 using value_type =
int;
152 using const_value_type =
const int;
153 using pointer =
void *;
155 using value_type = data_type;
156 using const_value_type = const_data_type;
157 using pointer = QRangeModelDetails::data_pointer_t<const_value_type>;
160 explicit DataReference(
const QModelIndex &index)
noexcept
164 DataReference(
const DataReference &other) =
default;
165 DataReference(DataReference &&other) =
default;
168 DataReference &operator=(
const DataReference &other)
174 DataReference &operator=(DataReference &&other)
180 ~DataReference() =
default;
182 DataReference &operator=(
const value_type &value)
188 DataReference &operator=(value_type &&value)
190 assign(std::move(value));
194 const_value_type get()
const
196 Q_ASSERT_X(m_index.isValid(),
"QRangeModelAdapter::at",
"Index at position is invalid");
197 return QRangeModelDetails::dataAtIndex<q20::remove_cvref_t<value_type>>(m_index);
200 operator const_value_type()
const
205 pointer operator->()
const
210 bool isValid()
const {
return m_index.isValid(); }
215 template <
typename Value>
216 void assign(Value &&value)
218 constexpr Qt::ItemDataRole dataRole = Qt::RangeModelAdapterRole;
220 if (m_index.isValid()) {
221 auto model =
const_cast<QAbstractItemModel *>(m_index.model());
222 [[maybe_unused]]
bool couldWrite =
false;
223 if constexpr (std::is_same_v<q20::remove_cvref_t<Value>, QVariant>) {
224 couldWrite = model->setData(m_index, value, dataRole);
226 couldWrite = model->setData(m_index,
227 QVariant::fromValue(std::forward<Value>(value)),
232 qWarning() <<
"Writing value of type"
233 << QMetaType::fromType<q20::remove_cvref_t<Value>>().name()
234 <<
"to role" << dataRole <<
"at index" << m_index <<
"failed";
237 qCritical(
"Data reference for invalid index, can't write to model");
242 friend inline bool comparesEqual(
const DataReference &lhs,
const DataReference &rhs)
244 return lhs.m_index == rhs.m_index
245 || lhs.get() == rhs.get();
247 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(DataReference);
249 friend inline bool comparesEqual(
const DataReference &lhs,
const value_type &rhs)
251 return lhs.get() == rhs;
253 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(DataReference, value_type);
255 friend inline void swap(DataReference lhs, DataReference rhs)
257 const value_type lhsValue = lhs.get();
262#ifndef QT_NO_DEBUG_STREAM
263 friend inline QDebug operator<<(QDebug dbg,
const DataReference &ref)
265 return dbg << ref.get();
268#ifndef QT_NO_DATASTREAM
269 friend inline QDataStream &operator<<(QDataStream &ds,
const DataReference &ref)
271 return ds << ref.get();
273 friend inline QDataStream &operator>>(QDataStream &ds, DataReference &ref)
277 ref = std::move(value);
282 template <
typename Iterator,
typename Adapter>
283 struct ColumnIteratorBase
285 using iterator_category = std::random_access_iterator_tag;
286 using difference_type =
int;
288 ColumnIteratorBase() =
default;
289 ColumnIteratorBase(
const ColumnIteratorBase &other) =
default;
290 ColumnIteratorBase(ColumnIteratorBase &&other) =
default;
291 ColumnIteratorBase &operator=(
const ColumnIteratorBase &other) =
default;
292 ColumnIteratorBase &operator=(ColumnIteratorBase &&other) =
default;
294 ColumnIteratorBase(
const QModelIndex &rowIndex,
int column, Adapter *adapter)
noexcept
295 : m_rowIndex(rowIndex), m_column(column), m_adapter(adapter)
299 void swap(ColumnIteratorBase &other)
noexcept
301 std::swap(m_rowIndex, other.m_rowIndex);
302 std::swap(m_column, other.m_column);
303 q_ptr_swap(m_adapter, other.m_adapter);
306 friend Iterator &operator++(Iterator &that)
311 friend Iterator operator++(Iterator &that,
int)
317 friend Iterator operator+(
const Iterator &that, difference_type n)
319 return {that.m_rowIndex, that.m_column + n, that.m_adapter};
321 friend Iterator operator+(difference_type n,
const Iterator &that)
325 friend Iterator &operator+=(Iterator &that, difference_type n)
331 friend Iterator &operator--(Iterator &that)
336 friend Iterator operator--(Iterator &that,
int)
342 friend Iterator operator-(
const Iterator &that, difference_type n)
344 return {that.m_rowIndex, that.m_column - n, that.m_adapter};
346 friend Iterator operator-(difference_type n,
const Iterator &that)
350 friend Iterator &operator-=(Iterator &that, difference_type n)
356 friend difference_type operator-(
const Iterator &lhs,
const Iterator &rhs)
358 Q_PRE(lhs.m_rowIndex == rhs.m_rowIndex);
359 Q_PRE(lhs.m_adapter == rhs.m_adapter);
360 return lhs.m_column - rhs.m_column;
364 ~ColumnIteratorBase() =
default;
365 QModelIndex m_rowIndex;
367 Adapter *m_adapter =
nullptr;
370 friend bool comparesEqual(
const Iterator &lhs,
const Iterator &rhs)
372 Q_ASSERT(lhs.m_rowIndex == rhs.m_rowIndex);
373 return lhs.m_column == rhs.m_column;
375 friend Qt::strong_ordering compareThreeWay(
const Iterator &lhs,
const Iterator &rhs)
377 Q_ASSERT(lhs.m_rowIndex == rhs.m_rowIndex);
378 return qCompareThreeWay(lhs.m_column, rhs.m_column);
381 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Iterator)
383#ifndef QT_NO_DEBUG_STREAM
384 friend inline QDebug operator<<(QDebug dbg,
const Iterator &it)
386 QDebugStateSaver saver(dbg);
388 return dbg <<
"ColumnIterator(" << it.m_rowIndex.siblingAtColumn(it.m_column) <<
")";
393 struct ConstColumnIterator : ColumnIteratorBase<ConstColumnIterator,
const QRangeModelAdapter>
396 using Base = ColumnIteratorBase<ConstColumnIterator,
const QRangeModelAdapter>;
398 using difference_type =
typename Base::difference_type;
399 using value_type = data_type;
400 using reference = const_data_type;
401 using pointer = QRangeModelDetails::data_pointer_t<value_type>;
404 using Base::operator=;
405 ~ConstColumnIterator() =
default;
407 pointer operator->()
const
409 return pointer{operator*()};
412 reference operator*()
const
414 return std::as_const(
this->m_adapter)->at(
this->m_rowIndex.row(),
this->m_column);
417 reference operator[](difference_type n)
const
423 struct ColumnIterator : ColumnIteratorBase<ColumnIterator, QRangeModelAdapter>
426 using Base = ColumnIteratorBase<ColumnIterator, QRangeModelAdapter>;
428 using difference_type =
typename Base::difference_type;
429 using value_type = DataReference;
430 using reference = DataReference;
431 using pointer = reference;
434 using Base::operator=;
435 ~ColumnIterator() =
default;
437 operator ConstColumnIterator()
const
439 return ConstColumnIterator{
this->m_rowIndex,
this->m_column,
this->m_adapter};
442 pointer operator->()
const
447 reference operator*()
const
449 return reference{
this->m_rowIndex.siblingAtColumn(
this->m_column)};
452 reference operator[](difference_type n)
const
458 template <
typename Reference,
typename const_row_type,
459 bool = std::is_reference_v<const_row_type>,
460 bool = std::is_pointer_v<const_row_type>>
463 const_row_type get()
const
465 const Reference *that =
static_cast<
const Reference *>(
this);
466 const auto *impl = that->m_adapter->storage.implementation();
467 auto *childRange = impl->childRange(that->m_index.parent());
468 if constexpr (std::is_convertible_v<
const row_type &, const_row_type>) {
469 return *std::next(QRangeModelDetails::adl_begin(childRange), that->m_index.row());
471 const auto &row = *std::next(QRangeModelDetails::adl_begin(childRange),
472 that->m_index.row());
473 return const_row_type{QRangeModelDetails::adl_begin(row),
474 QRangeModelDetails::adl_end(row)};
478 const_row_type operator->()
const
483 operator const_row_type()
const
489 template <
typename Reference,
typename const_row_type>
490 struct RowGetter<Reference, const_row_type,
true,
false>
492 const_row_type get()
const
494 const Reference *that =
static_cast<
const Reference *>(
this);
495 const auto *impl = that->m_adapter->storage.implementation();
496 return *std::next(QRangeModelDetails::begin(
497 QRangeModelDetails::refTo(impl->childRange(that->m_index.parent()))),
498 that->m_index.row());
501 auto operator->()
const
503 return std::addressof(get());
506 operator const_row_type()
const
512 template <
typename Reference,
typename const_row_type>
513 struct RowGetter<Reference, const_row_type,
false,
true>
515 const_row_type get()
const
517 const Reference *that =
static_cast<
const Reference *>(
this);
518 const auto *impl = that->m_adapter->storage.implementation();
519 return *std::next(QRangeModelDetails::begin(
520 QRangeModelDetails::refTo(impl->childRange(that->m_index.parent()))),
521 that->m_index.row());
524 const_row_type operator->()
const
529 operator const_row_type()
const
535 template <
typename Reference,
typename Adapter>
536 struct RowReferenceBase : RowGetter<Reference, QRangeModelDetails::asConstRow_t<row_type>>
538 using const_iterator = ConstColumnIterator;
539 using size_type =
int;
540 using difference_type =
int;
541 using const_row_type = QRangeModelDetails::asConstRow_t<row_type>;
543 RowReferenceBase(
const QModelIndex &index, Adapter *adapter)
noexcept
544 : m_index(index), m_adapter(adapter)
547 template <
typename I = Impl, if_tree<I> =
true>
548 bool hasChildren()
const
550 return m_adapter->model()->hasChildren(m_index);
553 template <
typename I = Impl, if_tree<I> =
true>
554 auto children()
const
556 using ConstRange = QRangeModelDetails::asConst_t<Range>;
557 return QRangeModelAdapter<ConstRange, Protocol, Model>(m_adapter->storage.m_model,
558 m_index, std::in_place);
561 ConstColumnIterator cbegin()
const
563 return ConstColumnIterator{m_index, 0, m_adapter};
565 ConstColumnIterator cend()
const
567 return ConstColumnIterator{m_index, m_adapter->columnCount(), m_adapter};
570 ConstColumnIterator begin()
const {
return cbegin(); }
571 ConstColumnIterator end()
const {
return cend(); }
573 size_type size()
const
575 return m_adapter->columnCount();
578 auto at(
int column)
const
580 Q_ASSERT(column >= 0 && column < m_adapter->columnCount());
581 return *ConstColumnIterator{m_index, column, m_adapter};
584 auto operator[](
int column)
const
590 friend struct RowGetter<Reference, const_row_type>;
591 ~RowReferenceBase() =
default;
596 friend bool comparesEqual(
const Reference &lhs,
const Reference &rhs)
598 Q_ASSERT(lhs.m_adapter == rhs.m_adapter);
599 return lhs.m_index == rhs.m_index;
601 friend Qt::strong_ordering compareThreeWay(
const Reference &lhs,
const Reference &rhs)
603 Q_ASSERT(lhs.m_adapter == rhs.m_adapter);
604 return qCompareThreeWay(lhs.m_index, rhs.m_index);
607 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Reference)
609 friend bool comparesEqual(
const Reference &lhs,
const row_type &rhs)
611 return lhs.get() == rhs;
613 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(Reference, row_type)
615#ifndef QT_NO_DEBUG_STREAM
616 friend inline QDebug operator<<(QDebug dbg,
const Reference &ref)
618 QDebugStateSaver saver(dbg);
620 return dbg <<
"RowReference(" << ref.m_index <<
")";
623#ifndef QT_NO_DATASTREAM
624 friend inline QDataStream &operator<<(QDataStream &ds,
const Reference &ref)
626 return ds << ref.get();
631 struct ConstRowReference : RowReferenceBase<ConstRowReference,
const QRangeModelAdapter>
634 using Base = RowReferenceBase<ConstRowReference,
const QRangeModelAdapter>;
638 ConstRowReference() =
default;
639 ConstRowReference(
const ConstRowReference &) =
default;
640 ConstRowReference(ConstRowReference &&) =
default;
641 ConstRowReference &operator=(
const ConstRowReference &) =
default;
642 ConstRowReference &operator=(ConstRowReference &&) =
default;
643 ~ConstRowReference() =
default;
646 struct RowReference : RowReferenceBase<RowReference, QRangeModelAdapter>
649 using Base = RowReferenceBase<RowReference, QRangeModelAdapter>;
651 using iterator = ColumnIterator;
652 using const_iterator =
typename Base::const_iterator;
653 using size_type =
typename Base::size_type;
654 using difference_type =
typename Base::difference_type;
656 using row_type =
int;
658 using const_row_type =
typename Base::const_row_type;
661 RowReference() =
delete;
662 ~RowReference() =
default;
663 RowReference(
const RowReference &other) =
default;
664 RowReference(RowReference &&other) =
default;
667 RowReference &operator=(
const ConstRowReference &other)
673 RowReference &operator=(
const RowReference &other)
679 RowReference &operator=(
const row_type &other)
685 RowReference &operator=(row_type &&other)
687 assign(std::move(other));
691 operator ConstRowReference()
const
693 return ConstRowReference{
this->m_index,
this->m_adapter};
696 template <
typename ConstRowType = const_row_type,
697 std::enable_if_t<!std::is_same_v<ConstRowType,
const row_type &>,
bool> =
true>
698 RowReference &operator=(
const ConstRowType &other)
704 template <
typename T,
typename It,
typename Sentinel>
705 RowReference &operator=(
const QRangeModelDetails::RowView<T, It, Sentinel> &other)
707 *
this = row_type{other.begin(), other.end()};
711 friend inline void swap(RowReference lhs, RowReference rhs)
713 auto lhsRow = lhs.get();
715 rhs = std::move(lhsRow);
718 template <
typename I = Impl, if_tree<I> =
true>
721 return QRangeModelAdapter(
this->m_adapter->storage.m_model,
this->m_index,
726 ColumnIterator begin()
728 return ColumnIterator{
this->m_index, 0,
this->m_adapter};
734 return ColumnIterator{
this->m_index,
this->m_adapter->columnCount(),
this->m_adapter};
740 Q_ASSERT(column >= 0 && column <
this->m_adapter->columnCount());
741 return *ColumnIterator{
this->m_index, column,
this->m_adapter};
744 using Base::operator[];
745 auto operator[](
int column)
751 template <
typename RHS>
752 void verifyRows(
const row_type &oldRow,
const RHS &newRow)
754 if constexpr (QRangeModelDetails::test_size<row_type>::value) {
756 Q_ASSERT_X(Impl::size(newRow) == Impl::size(oldRow),
757 "RowReference::operator=()",
758 "The new row has the wrong size!");
761 if constexpr (is_tree<Impl>) {
763 Q_ASSERT_X(QRangeModelDetails::isValid(newRow),
764 "RowReference::operator=()",
765 "An invalid row can not inserted into a tree!");
769 template <
typename R>
770 void assign(R &&other)
772 auto *impl =
this->m_adapter->storage.implementation();
773 decltype(
auto) oldRow = impl->rowData(
this->m_index);
775 verifyRows(oldRow, other);
777 if constexpr (is_tree<Impl>) {
778 auto &protocol = impl->protocol();
779 auto *oldParent = protocol.parentRow(QRangeModelDetails::refTo(oldRow));
783 if (
decltype(
auto) oldChildren = protocol.childRows(QRangeModelDetails::refTo(oldRow));
784 QRangeModelDetails::isValid(oldChildren)) {
785 if (
int oldChildCount =
this->m_adapter->model()->rowCount(
this->m_index)) {
786 impl->beginRemoveRows(
this->m_index, 0, oldChildCount - 1);
787 impl->deleteRemovedRows(QRangeModelDetails::refTo(oldChildren));
789 QRangeModelDetails::refTo(oldChildren) = range_type{};
790 impl->endRemoveRows();
794 if constexpr (protocol_traits::has_deleteRow)
795 protocol.deleteRow(oldRow);
796 oldRow = std::forward<R>(other);
797 if constexpr (protocol_traits::has_setParentRow) {
798 protocol.setParentRow(QRangeModelDetails::refTo(oldRow),
799 QRangeModelDetails::pointerTo(oldParent));
800 if (
decltype(
auto) newChildren = protocol.childRows(QRangeModelDetails::refTo(oldRow));
801 QRangeModelDetails::isValid(newChildren)) {
802 impl->beginInsertRows(
this->m_index, 0,
803 Impl::size(QRangeModelDetails::refTo(newChildren)) - 1);
804 impl->setParentRow(QRangeModelDetails::refTo(newChildren),
805 QRangeModelDetails::pointerTo(oldRow));
806 impl->endInsertRows();
810 oldRow = std::forward<R>(other);
812 this->m_adapter->emitDataChanged(
this->m_index,
813 this->m_index.siblingAtColumn(
this->m_adapter->columnCount() - 1));
814 if constexpr (Impl::itemsAreQObjects) {
815 if (
this->m_adapter->model()->autoConnectPolicy() == QRangeModel::AutoConnectPolicy::Full) {
816 impl->autoConnectPropertiesInRow(oldRow,
this->m_index.row(),
this->m_index.parent());
817 if constexpr (is_tree<Impl>)
818 impl->autoConnectProperties(
this->m_index);
824#ifndef QT_NO_DATASTREAM
825 friend inline QDataStream &operator>>(QDataStream &ds, RowReference &ref)
835 template <
typename Iterator,
typename Adapter>
836 struct RowIteratorBase : QRangeModelDetails::ParentIndex<is_tree<Impl>>
838 using iterator_category = std::random_access_iterator_tag;
839 using difference_type =
int;
841 RowIteratorBase() =
default;
842 RowIteratorBase(
const RowIteratorBase &) =
default;
843 RowIteratorBase(RowIteratorBase &&) =
default;
844 RowIteratorBase &operator=(
const RowIteratorBase &) =
default;
845 RowIteratorBase &operator=(RowIteratorBase &&) =
default;
847 RowIteratorBase(
int row,
const QModelIndex &parent, Adapter *adapter)
848 : QRangeModelDetails::ParentIndex<is_tree<Impl>>{parent}
849 , m_row(row), m_adapter(adapter)
852 void swap(RowIteratorBase &other)
noexcept
854 qSwap(m_row, other.m_row);
855 qSwap(
this->m_rootIndex, other.m_rootIndex);
856 q_ptr_swap(m_adapter, other.m_adapter);
859 friend Iterator &operator++(Iterator &that)
864 friend Iterator operator++(Iterator &that,
int)
870 friend Iterator operator+(
const Iterator &that, difference_type n)
872 return {that.m_row + n, that.root(), that.m_adapter};
874 friend Iterator operator+(difference_type n,
const Iterator &that)
878 friend Iterator &operator+=(Iterator &that, difference_type n)
884 friend Iterator &operator--(Iterator &that)
889 friend Iterator operator--(Iterator &that,
int)
895 friend Iterator operator-(
const Iterator &that, difference_type n)
897 return {that.m_row - n, that.root(), that.m_adapter};
899 friend Iterator operator-(difference_type n,
const Iterator &that)
903 friend Iterator &operator-=(Iterator &that, difference_type n)
909 friend difference_type operator-(
const Iterator &lhs,
const Iterator &rhs)
911 return lhs.m_row - rhs.m_row;
915 ~RowIteratorBase() =
default;
917 Adapter *m_adapter =
nullptr;
920 friend bool comparesEqual(
const Iterator &lhs,
const Iterator &rhs)
noexcept
922 return lhs.m_row == rhs.m_row && lhs.root() == rhs.root();
924 friend Qt::strong_ordering compareThreeWay(
const Iterator &lhs,
const Iterator &rhs)
noexcept
926 if (lhs.root() == rhs.root())
927 return qCompareThreeWay(lhs.m_row, rhs.m_row);
928 return qCompareThreeWay(lhs.root(), rhs.root());
931 Q_DECLARE_STRONGLY_ORDERED(Iterator)
933#ifndef QT_NO_DEBUG_STREAM
934 friend inline QDebug operator<<(QDebug dbg,
const Iterator &it)
936 QDebugStateSaver saver(dbg);
938 return dbg <<
"RowIterator(" << it.m_row << it.root() <<
")";
944 struct ConstRowIterator :
public RowIteratorBase<ConstRowIterator,
const QRangeModelAdapter>
947 using Base = RowIteratorBase<ConstRowIterator,
const QRangeModelAdapter>;
951 using difference_type =
typename Base::difference_type;
952 using value_type = std::conditional_t<is_list<Impl>,
955 using reference = std::conditional_t<is_list<Impl>,
958 using pointer = std::conditional_t<is_list<Impl>,
959 QRangeModelDetails::data_pointer_t<const_data_type>,
962 ConstRowIterator(
const ConstRowIterator &other) =
default;
963 ConstRowIterator(ConstRowIterator &&other) =
default;
964 ConstRowIterator &operator=(
const ConstRowIterator &other) =
default;
965 ConstRowIterator &operator=(ConstRowIterator &&other) =
default;
966 ~ConstRowIterator() =
default;
968 pointer operator->()
const
970 return pointer{operator*()};
973 reference operator*()
const
975 if constexpr (is_list<Impl>) {
976 return this->m_adapter->at(
this->m_row);
978 const QModelIndex index =
this->m_adapter->model()->index(
this->m_row, 0,
980 return ConstRowReference{index,
this->m_adapter};
984 reference operator[](difference_type n)
const
990 struct RowIterator :
public RowIteratorBase<RowIterator, QRangeModelAdapter>
993 using Base = RowIteratorBase<RowIterator, QRangeModelAdapter>;
997 using difference_type =
typename Base::difference_type;
998 using value_type = std::conditional_t<is_list<Impl>,
1001 using reference = std::conditional_t<is_list<Impl>,
1004 using pointer = std::conditional_t<is_list<Impl>,
1008 RowIterator(
const RowIterator &other) =
default;
1009 RowIterator(RowIterator &&other) =
default;
1010 RowIterator &operator=(
const RowIterator &other) =
default;
1011 RowIterator &operator=(RowIterator &&other) =
default;
1012 ~RowIterator() =
default;
1014 operator ConstRowIterator()
const
1016 return ConstRowIterator{
this->m_row,
this->root(),
this->m_adapter};
1019 pointer operator->()
const
1021 return pointer{operator*()};
1024 reference operator*()
const
1026 const QModelIndex index =
this->m_adapter->model()->index(
this->m_row, 0,
this->root());
1027 if constexpr (is_list<Impl>) {
1028 return reference{index};
1030 return reference{index,
this->m_adapter};
1034 reference operator[](difference_type n)
const
1036 return *(*
this + n);
1040 using const_iterator = ConstRowIterator;
1041 using iterator = RowIterator;
1043 template <
typename R,
1045 if_compatible_model_params<R, P> =
true>
1046 explicit QRangeModelAdapter(R &&range, P &&protocol)
1047 : QRangeModelAdapter(
new Model(QRangeModelDetails::forwardOrConvert<Range>(std::forward<R>(range)),
1048 QRangeModelDetails::forwardOrConvert<Protocol>(std::forward<P>(protocol))))
1051 template <
typename R,
1053 if_compatible_model_params<R, P> =
true,
1054 unless_adapter<R> =
true>
1055 explicit QRangeModelAdapter(R &&range)
1056 : QRangeModelAdapter(
new Model(QRangeModelDetails::forwardOrConvert<Range>(std::forward<R>(range))))
1061 Model *model()
const
1063 return storage.m_model.get();
1066 const range_type &range()
const
1068 return QRangeModelDetails::refTo(storage.implementation()->childRange(storage.root()));
1071 template <
typename NewRange = range_type, if_assignable_range<NewRange> =
true>
1072 void assign(NewRange &&newRange)
1074 assignImpl(qsizetype(Impl::size(QRangeModelDetails::refTo(newRange))),
1075 [&newRange](
auto &oldRange) {
1076 oldRange = std::forward<NewRange>(newRange);
1080 template <
typename NewRange = range_type, if_assignable_range<NewRange> =
true,
1081 unless_adapter<NewRange> =
true>
1082 QRangeModelAdapter &operator=(NewRange &&newRange)
1084 assign(std::forward<NewRange>(newRange));
1088 template <
typename Row, if_assignable_range<std::initializer_list<Row>> =
true>
1089 void assign(std::initializer_list<Row> newRange)
1091 assignImpl(newRange.size(), [&newRange](
auto &oldRange) {
1092 oldRange = newRange;
1096 template <
typename Row, if_assignable_range<std::initializer_list<Row>> =
true>
1097 QRangeModelAdapter &operator=(std::initializer_list<Row> newRange)
1103 template <
typename InputIterator,
typename Sentinel,
typename I = Impl, if_writable<I> =
true>
1104 void assign(InputIterator first, Sentinel last)
1106 assignImpl(size_t(std::distance(first, last)), [first, last](
auto &oldRange) {
1107 oldRange.assign(first, last);
1112 ConstRowIterator cbegin()
const
1114 return ConstRowIterator{ 0, storage.root(),
this };
1116 ConstRowIterator begin()
const {
return cbegin(); }
1118 ConstRowIterator cend()
const
1120 return ConstRowIterator{ rowCount(), storage.root(),
this };
1122 ConstRowIterator end()
const {
return cend(); }
1124 template <
typename I = Impl, if_writable<I> =
true>
1127 return RowIterator{ 0, storage.root(),
this };
1130 template <
typename I = Impl, if_writable<I> =
true>
1133 return RowIterator{ rowCount(), storage.root(),
this };
1141 template <
typename I = Impl, if_list<I> =
true>
1142 QModelIndex index(
int row)
const
1144 return storage->index(row, 0, storage.root());
1147 template <
typename I = Impl, unless_list<I> =
true>
1148 QModelIndex index(
int row,
int column)
const
1150 return storage->index(row, column, storage.root());
1153 template <
typename I = Impl, if_tree<I> =
true>
1154 QModelIndex index(QSpan<
const int> path,
int col)
const
1156 QModelIndex result = storage.root();
1157 auto count = path.size();
1158 for (
const int r : path) {
1160 result = storage->index(r, 0, result);
1162 result = storage->index(r, col, result);
1167 int columnCount()
const
1170 return storage->columnCount({});
1173 int rowCount()
const
1175 return storage->rowCount(storage.root());
1178 template <
typename I = Impl, if_tree<I> =
true>
1179 int rowCount(
int row)
const
1181 return rowCount(index(row, 0));
1184 template <
typename I = Impl, if_tree<I> =
true>
1185 int rowCount(QSpan<
const int> path)
const
1187 return rowCount(index(path, 0));
1190 template <
typename I = Impl, if_tree<I> =
true>
1191 int rowCount(
const QModelIndex &index)
const
1193 return storage->rowCount(index);
1196 template <
typename I = Impl, if_tree<I> =
true>
1197 constexpr bool hasChildren(
int row)
const
1199 return hasChildren(index(row, 0));
1202 template <
typename I = Impl, if_tree<I> =
true>
1203 constexpr bool hasChildren(QSpan<
const int> path)
const
1205 return hasChildren(index(path, 0));
1208 template <
typename I = Impl, if_tree<I> =
true>
1209 constexpr bool hasChildren(
const QModelIndex &index)
const
1211 return storage.m_model->hasChildren(index);
1214 template <
typename I = Impl, if_list<I> =
true>
1215 QVariant data(
int row)
const
1217 return data(index(row));
1220 template <
typename I = Impl, if_list<I> =
true>
1221 QVariant data(
int row,
int role)
const
1223 return data(index(row), role);
1226 template <
typename I = Impl, if_list<I> =
true, if_writable<I> =
true>
1227 bool setData(
int row,
const QVariant &value,
int role = Qt::EditRole)
1229 return setData(index(row), value, role);
1232 template <
typename I = Impl, unless_list<I> =
true>
1233 QVariant data(
int row,
int column)
const
1235 return data(index(row, column));
1238 template <
typename I = Impl, unless_list<I> =
true>
1239 QVariant data(
int row,
int column,
int role)
const
1241 return data(index(row, column), role);
1244 template <
typename I = Impl, unless_list<I> =
true, if_writable<I> =
true>
1245 bool setData(
int row,
int column,
const QVariant &value,
int role = Qt::EditRole)
1247 return setData(index(row, column), value, role);
1250 template <
typename I = Impl, if_tree<I> =
true>
1251 QVariant data(QSpan<
const int> path,
int column)
const
1253 return data(index(path, column));
1256 template <
typename I = Impl, if_tree<I> =
true>
1257 QVariant data(QSpan<
const int> path,
int column,
int role)
const
1259 return data(index(path, column), role);
1262 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1263 bool setData(QSpan<
const int> path,
int column,
const QVariant &value,
int role = Qt::EditRole)
1265 return setData(index(path, column), value, role);
1268 QVariant data(
const QModelIndex &index)
const
1270 return QRangeModelDetails::dataAtIndex<QVariant>(index);
1273 QVariant data(
const QModelIndex &index,
int role)
const
1275 return QRangeModelDetails::dataAtIndex<QVariant>(index, role);
1278 template <
typename I = Impl, if_writable<I> =
true>
1279 bool setData(
const QModelIndex &index,
const QVariant &value,
int role = Qt::EditRole)
1281 return storage->setData(index, value, role);
1286 template <
typename I= Impl, if_list<I> =
true>
1287 const_data_type at(
int row)
const
1289 return QRangeModelDetails::dataAtIndex<data_type>(index(row));
1291 template <
typename I = Impl, if_list<I> =
true>
1292 const_data_type operator[](
int row)
const {
return at(row); }
1294 template <
typename I= Impl, if_list<I> =
true, if_writable<I> =
true>
1296 const QModelIndex idx =
this->index(row);
1297 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::at",
"Index at row is invalid");
1298 return DataReference{idx};
1300 template <
typename I = Impl, if_list<I> =
true, if_writable<I> =
true>
1301 auto operator[](
int row) {
1302 const QModelIndex idx =
this->index(row);
1303 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::operator[]",
"Index at row is invalid");
1304 return DataReference{idx};
1308 template <
typename I = Impl, unless_list<I> =
true>
1309 decltype(
auto) at(
int row)
const
1311 return ConstRowReference{index(row, 0),
this}.get();
1313 template <
typename I = Impl, unless_list<I> =
true>
1314 decltype(
auto) operator[](
int row)
const {
return at(row); }
1316 template <
typename I = Impl, if_table<I> =
true, if_writable<I> =
true>
1319 return RowReference{index(row, 0),
this};
1321 template <
typename I = Impl, if_table<I> =
true, if_writable<I> =
true>
1322 auto operator[](
int row) {
return at(row); }
1325 template <
typename I = Impl, unless_list<I> =
true>
1326 const_data_type at(
int row,
int column)
const
1328 return QRangeModelDetails::dataAtIndex<data_type>(index(row, column));
1331#ifdef __cpp_multidimensional_subscript
1332 template <
typename I = Impl, unless_list<I> =
true>
1333 const_data_type operator[](
int row,
int column)
const {
return at(row, column); }
1336 template <
typename I = Impl, unless_list<I> =
true, if_writable<I> =
true>
1337 auto at(
int row,
int column)
1339 const QModelIndex idx =
this->index(row, column);
1340 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::at",
"Index at cell is invalid");
1341 return DataReference{idx};
1343#ifdef __cpp_multidimensional_subscript
1344 template <
typename I = Impl, unless_list<I> =
true, if_writable<I> =
true>
1345 auto operator[](
int row,
int column)
1347 const QModelIndex idx =
this->index(row, column);
1348 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::operator[]",
"Index at cell is invalid");
1349 return DataReference{idx};
1355 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1358 return RowReference{index(row, 0),
this};
1360 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1361 auto operator[](
int row) {
return at(row); }
1364 template <
typename I = Impl, if_tree<I> =
true>
1365 decltype(
auto) at(QSpan<
const int> path)
const
1367 return ConstRowReference{index(path, 0),
this}.get();
1369 template <
typename I = Impl, if_tree<I> =
true>
1370 decltype(
auto) operator[](QSpan<
const int> path)
const {
return at(path); }
1372 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1373 auto at(QSpan<
const int> path)
1375 return RowReference{index(path, 0),
this};
1377 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1378 auto operator[](QSpan<
const int> path) {
return at(path); }
1381 template <
typename I = Impl, if_tree<I> =
true>
1382 const_data_type at(QSpan<
const int> path,
int column)
const
1385 return QRangeModelDetails::dataAtIndex<data_type>(index(path, column));
1388#ifdef __cpp_multidimensional_subscript
1389 template <
typename I = Impl, if_tree<I> =
true>
1390 const_data_type operator[](QSpan<
const int> path,
int column)
const {
return at(path, column); }
1393 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1394 auto at(QSpan<
const int> path,
int column)
1397 const QModelIndex idx =
this->index(path, column);
1398 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::at",
"Index at path is invalid");
1399 return DataReference{idx};
1401#ifdef __cpp_multidimensional_subscript
1402 template <
typename I = Impl, if_tree<I> =
true, if_writable<I> =
true>
1403 auto operator[](QSpan<
const int> path,
int column)
1405 const QModelIndex idx =
this->index(path, column);
1406 Q_ASSERT_X(idx.isValid(),
"QRangeModelAdapter::operator[]",
"Index at path is invalid");
1407 return DataReference{idx};
1411 const_data_type at(
const QModelIndex &index)
const
1413 Q_ASSERT_X(index.isValid(),
"QRangeModelAdapter::at",
"Index is invalid");
1414 return QRangeModelDetails::dataAtIndex<data_type>(index);
1417 template <
typename I = Impl, if_writable<I> =
true>
1418 auto at(
const QModelIndex &index)
1420 Q_ASSERT_X(index.isValid(),
"QRangeModelAdapter::at",
"Index is invalid");
1421 return DataReference{index};
1424 template <
typename I = Impl, if_canInsertRows<I> =
true>
1425 bool insertRow(
int before)
1427 return storage.m_model->insertRow(before);
1430 template <
typename I = Impl, if_canInsertRows<I> =
true, if_tree<I> =
true>
1431 bool insertRow(QSpan<
const int> before)
1433 Q_PRE(before.size());
1434 return insertRow(before.back(),
this->index(before.first(before.size() - 1), 0));
1437 template <
typename I = Impl, if_canInsertRows<I> =
true, if_tree<I> =
true>
1438 bool insertRow(
int before,
const QModelIndex &parent)
1440 return storage.m_model->insertRow(before, parent);
1443 template <
typename D = row_type,
typename I = Impl,
1444 if_canInsertRows<I> =
true, if_compatible_row<D> =
true>
1445 bool insertRow(
int before, D &&data)
1447 return insertRowImpl(before, storage.root(), std::forward<D>(data));
1450 template <
typename D = row_type,
typename I = Impl,
1451 if_canInsertRows<I> =
true, if_compatible_row<D> =
true, if_tree<I> =
true>
1452 bool insertRow(QSpan<
const int> before, D &&data)
1454 return insertRow(before.back(),
this->index(before.sliced(0, before.size() - 1), 0),
1455 std::forward<D>(data));
1458 template <
typename D = row_type,
typename I = Impl,
1459 if_canInsertRows<I> =
true, if_compatible_row<D> =
true, if_tree<I> =
true>
1460 bool insertRow(
int before,
const QModelIndex &parent, D &&data)
1462 return insertRowImpl(before, parent, std::forward<D>(data));
1465 template <
typename C,
typename I = Impl,
1466 if_canInsertRows<I> =
true, if_compatible_row_range<C> =
true>
1467 bool insertRows(
int before, C &&data)
1469 return insertRowsImpl(before, storage.root(), std::forward<C>(data));
1472 template <
typename C,
typename I = Impl,
1473 if_canInsertRows<I> =
true, if_compatible_row_range<C> =
true, if_tree<I> =
true>
1474 bool insertRows(QSpan<
const int> before, C &&data)
1476 return insertRows(before.back(),
this->index(before.sliced(0, before.size() - 1), 0),
1477 std::forward<C>(data));
1480 template <
typename C,
typename I = Impl,
1481 if_canInsertRows<I> =
true, if_compatible_row_range<C> =
true, if_tree<I> =
true>
1482 bool insertRows(
int before,
const QModelIndex &parent, C &&data)
1484 return insertRowsImpl(before, parent, std::forward<C>(data));
1487 template <
typename I = Impl, if_canRemoveRows<I> =
true>
1488 bool removeRow(
int row)
1490 return removeRows(row, 1);
1493 template <
typename I = Impl, if_canRemoveRows<I> =
true, if_tree<I> =
true>
1494 bool removeRow(QSpan<
const int> path)
1496 return removeRows(path, 1);
1499 template <
typename I = Impl, if_canRemoveRows<I> =
true, if_tree<I> =
true>
1500 bool removeRow(
int row,
const QModelIndex &parent)
1502 return removeRows(row, 1, parent);
1505 template <
typename I = Impl, if_canRemoveRows<I> =
true>
1506 bool removeRows(
int row,
int count)
1508 return storage->removeRows(row, count, storage.root());
1511 template <
typename I = Impl, if_canRemoveRows<I> =
true, if_tree<I> =
true>
1512 bool removeRows(QSpan<
const int> path,
int count)
1514 return removeRows(path.back(), count,
this->index(path.first(path.size() - 1), 0));
1517 template <
typename I = Impl, if_canRemoveRows<I> =
true, if_tree<I> =
true>
1518 bool removeRows(
int row,
int count,
const QModelIndex &parent)
1520 return storage->removeRows(row, count, parent);
1523 template <
typename F = range_features, if_canMoveItems<F> =
true>
1524 bool moveRow(
int source,
int destination)
1526 return moveRows(source, 1, destination);
1529 template <
typename F = range_features, if_canMoveItems<F> =
true>
1530 bool moveRows(
int source,
int count,
int destination)
1532 return storage->moveRows(storage.root(), source, count, storage.root(), destination);
1535 template <
typename I = Impl,
typename F = range_features,
1536 if_canMoveItems<F> =
true, if_tree<I> =
true>
1537 bool moveRow(QSpan<
const int> source, QSpan<
const int> destination)
1539 return moveRows(source, 1, destination);
1542 template <
typename I = Impl,
typename F = range_features,
1543 if_canMoveItems<F> =
true, if_tree<I> =
true>
1544 bool moveRow(
const QModelIndex &sourceParent,
int sourceRow,
1545 const QModelIndex &destinationParent,
int destinationChild)
1547 return moveRows(sourceParent, sourceRow, 1, destinationParent, destinationChild);
1550 template <
typename I = Impl,
typename F = range_features,
1551 if_canMoveItems<F> =
true, if_tree<I> =
true>
1552 bool moveRows(QSpan<
const int> source,
int count, QSpan<
const int> destination)
1554 return moveRows(
this->index(source.first(source.size() - 1), 0),
1557 this->index(destination.first(destination.size() - 1), 0),
1558 destination.back());
1561 template <
typename I = Impl,
typename F = range_features,
1562 if_canMoveItems<F> =
true, if_tree<I> =
true>
1563 bool moveRows(
const QModelIndex &sourceParent,
int sourceRow,
int count,
1564 const QModelIndex &destinationParent,
int destinationChild)
1566 return storage->moveRows(sourceParent, sourceRow, count,
1567 destinationParent, destinationChild);
1570 template <
typename I = Impl, if_canInsertColumns<I> =
true>
1571 bool insertColumn(
int before)
1573 return storage.m_model->insertColumn(before);
1576 template <
typename D,
typename I = Impl,
1577 if_canInsertColumns<I> =
true, if_compatible_column_data<D> =
true>
1578 bool insertColumn(
int before, D &&data)
1580 return insertColumnImpl(before, storage.root(), std::forward<D>(data));
1583 template <
typename C,
typename I = Impl,
1584 if_canInsertColumns<I> =
true, if_compatible_column_range<C> =
true>
1585 bool insertColumns(
int before, C &&data)
1587 return insertColumnsImpl(before, storage.root(), std::forward<C>(data));
1590 template <
typename I = Impl, if_canRemoveColumns<I> =
true>
1591 bool removeColumn(
int column)
1593 return storage.m_model->removeColumn(column);
1596 template <
typename I = Impl, if_canRemoveColumns<I> =
true>
1597 bool removeColumns(
int column,
int count)
1599 return storage->removeColumns(column, count, {});
1602 template <
typename F = row_features, if_canMoveItems<F> =
true>
1603 bool moveColumn(
int from,
int to)
1605 return moveColumns(from, 1, to);
1608 template <
typename F = row_features, if_canMoveItems<F> =
true>
1609 bool moveColumns(
int from,
int count,
int to)
1611 return storage->moveColumns(storage.root(), from, count, storage.root(), to);
1614 template <
typename I = Impl,
typename F = row_features,
1615 if_canMoveItems<F> =
true, if_tree<I> =
true>
1616 bool moveColumn(QSpan<
const int> source,
int to)
1618 const QModelIndex parent =
this->index(source.first(source.size() - 1), 0);
1619 return storage->moveColumns(parent, source.back(), 1, parent, to);
1622 template <
typename I = Impl,
typename F = row_features,
1623 if_canMoveItems<F> =
true, if_tree<I> =
true>
1624 bool moveColumns(QSpan<
const int> source,
int count,
int destination)
1626 const QModelIndex parent =
this->index(source.first(source.size() - 1), 0);
1627 return storage->moveColumns(parent, source.back(), count, parent, destination);
1632 bool comparesEqual(
const QRangeModelAdapter &lhs,
const QRangeModelAdapter &rhs)
noexcept
1634 return lhs.storage.m_model == rhs.storage.m_model;
1636 Q_DECLARE_EQUALITY_COMPARABLE(QRangeModelAdapter)
1639 bool comparesEqual(
const QRangeModelAdapter &lhs,
const range_type &rhs)
1641 return lhs.range() == rhs;
1643 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QRangeModelAdapter, range_type)
1646 void emitDataChanged(
const QModelIndex &topLeft,
const QModelIndex &bottomRight)
1648 Q_EMIT storage.implementation()->dataChanged(topLeft, bottomRight, {});
1651 void beginAssignImpl(Impl *impl, range_type *oldRange,
int newLastRow)
1653 const QModelIndex root = storage.root();
1654 const qsizetype oldLastRow = qsizetype(Impl::size(oldRange)) - 1;
1656 if (!root.isValid()) {
1657 impl->beginResetModel();
1658 impl->deleteOwnedRows();
1659 }
else if constexpr (is_tree<Impl>) {
1660 if (oldLastRow >= 0) {
1661 impl->beginRemoveRows(root, 0, model()->rowCount(root) - 1);
1662 impl->deleteRemovedRows(QRangeModelDetails::refTo(oldRange));
1663 impl->endRemoveRows();
1665 if (newLastRow >= 0)
1666 impl->beginInsertRows(root, 0, newLastRow);
1668 Q_ASSERT_X(
false,
"QRangeModelAdapter::assign",
1669 "Internal error: The root index in a table or list must be invalid.");
1673 void endAssignImpl(Impl *impl,
int newLastRow)
1675 const QModelIndex root = storage.root();
1676 if (!root.isValid()) {
1677 impl->endResetModel();
1678 }
else if constexpr (is_tree<Impl>) {
1679 if (newLastRow >= 0) {
1680 Q_ASSERT(model()->hasChildren(root));
1683 impl->setParentRow(QRangeModelDetails::refTo(impl->childRange(root)),
1684 QRangeModelDetails::pointerTo(impl->rowData(root)));
1685 impl->endInsertRows();
1690 template <
typename Assigner>
1691 void assignImpl(std::size_t newSize, Assigner &&assigner)
1693 const auto sz = q26::saturating_cast<
int>(newSize);
1694 Q_ASSERT_X(q20::cmp_equal(sz, newSize),
1695 "QRangeModelAdapter::assign",
"New range is too large");
1696 const int newLastRow = sz - 1;
1698 auto *impl = storage.implementation();
1699 auto *oldRange = impl->childRange(storage.root());
1700 beginAssignImpl(impl, oldRange, newLastRow);
1701 assigner(QRangeModelDetails::refTo(oldRange));
1702 endAssignImpl(impl, newLastRow);
1704 if constexpr (Impl::itemsAreQObjects) {
1705 if (model()->autoConnectPolicy() == QRangeModel::AutoConnectPolicy::Full) {
1706 const auto begin = QRangeModelDetails::begin(QRangeModelDetails::refTo(oldRange));
1707 const auto end = QRangeModelDetails::end(QRangeModelDetails::refTo(oldRange));
1709 for (
auto it = begin; it != end; ++it, ++rowIndex)
1710 impl->autoConnectPropertiesInRow(*it, rowIndex, storage.root());
1716 template <
typename P,
typename Row>
1717 static auto setParentRow(P &protocol, Row &newRow, row_ptr parentRow)
1718 ->
decltype(protocol.setParentRow(newRow, parentRow))
1720 return protocol.setParentRow(newRow, parentRow);
1722 template <
typename ...Args>
static constexpr void setParentRow(Args &&...)
1724 static_assert(!protocol_traits::has_setParentRow,
1725 "Internal error, wrong setParentRow overload called");
1728 template <
typename D>
1729 bool insertRowImpl(
int before,
const QModelIndex &parent, D &&data)
1731 return storage.implementation()->doInsertRows(before, 1, parent, [&data,
this]
1732 (range_type &range,
auto *parentRow,
int row,
int count) {
1734 const auto oldSize = range.size();
1735 auto newRow = range.emplace(QRangeModelDetails::pos(range, row), std::forward<D>(data));
1736 setParentRow(storage->protocol(), QRangeModelDetails::refTo(*newRow),
1737 QRangeModelDetails::pointerTo(parentRow));
1738 return range.size() == oldSize + count;
1742 template <
typename LHS>
1743 static auto selfInsertion(LHS *lhs, LHS *rhs) ->
decltype(lhs == rhs)
1747 qCritical(
"Inserting data into itself is not supported");
1753 template <
typename LHS,
typename RHS>
1754 static constexpr bool selfInsertion(LHS *, RHS *) {
return false; }
1756 template <
typename C>
1757 bool insertRowsImpl(
int before,
const QModelIndex &parent, C &&data)
1759 bool result =
false;
1760 result = storage->doInsertRows(before,
int(std::size(data)), parent, [&data,
this]
1761 (range_type &range,
auto *parentRow,
int row,
int count){
1762 Q_UNUSED(parentRow);
1764 const auto pos = QRangeModelDetails::pos(range, row);
1765 const auto oldSize = range.size();
1767 auto dataRange = [&data]{
1768 if constexpr (std::is_rvalue_reference_v<C&&>) {
1769 return std::make_pair(
1770 std::move_iterator(std::begin(data)),
1771 std::move_iterator(std::end(data))
1774 return std::make_pair(std::begin(data), std::end(data));
1778 if constexpr (range_features::has_insert_range) {
1779 if (selfInsertion(&range, &data))
1781 auto start = range.insert(pos, dataRange.first, dataRange.second);
1782 if constexpr (protocol_traits::has_setParentRow) {
1784 setParentRow(storage->protocol(), QRangeModelDetails::refTo(*start),
1785 QRangeModelDetails::pointerTo(parentRow));
1793 auto newRow = range.insert(pos, count, row_type{});
1794 while (dataRange.first != dataRange.second) {
1795 *newRow = *dataRange.first;
1796 setParentRow(storage->protocol(), QRangeModelDetails::refTo(*newRow),
1797 QRangeModelDetails::pointerTo(parentRow));
1802 return range.size() == oldSize + count;
1807 template <
typename D,
typename =
void>
1808 struct DataFromList {
1809 static constexpr auto first(D &data) {
return &data; }
1810 static constexpr auto next(D &, D *entry) {
return entry; }
1813 template <
typename D>
1814 struct DataFromList<D, std::enable_if_t<QRangeModelDetails::range_traits<D>::value>>
1816 static constexpr auto first(D &data) {
return std::begin(data); }
1817 static constexpr auto next(D &data,
typename D::iterator entry)
1820 if (entry == std::end(data))
1821 entry = first(data);
1826 template <
typename D,
typename =
void>
struct RowFromTable
1828 static constexpr auto first(D &data) {
return &data; }
1829 static constexpr auto next(D &, D *entry) {
return entry; }
1832 template <
typename D>
1833 struct RowFromTable<D, std::enable_if_t<std::conjunction_v<
1834 QRangeModelDetails::range_traits<D>,
1835 QRangeModelDetails::range_traits<
typename D::value_type>
1840 template <
typename D>
1841 bool insertColumnImpl(
int before,
const QModelIndex &parent, D data)
1843 auto entry = DataFromList<D>::first(data);
1845 return storage->doInsertColumns(before, 1, parent, [&entry, &data]
1846 (
auto &range,
auto pos,
int count) {
1847 const auto oldSize = range.size();
1848 range.insert(pos, *entry);
1849 entry = DataFromList<D>::next(data, entry);
1850 return range.size() == oldSize + count;
1854 template <
typename C>
1855 bool insertColumnsImpl(
int before,
const QModelIndex &parent, C data)
1857 bool result =
false;
1858 auto entries = RowFromTable<C>::first(data);
1859 auto begin = std::begin(*entries);
1860 auto end = std::end(*entries);
1861 result = storage->doInsertColumns(before,
int(std::size(*entries)), parent,
1862 [&begin, &end, &entries, &data](
auto &range,
auto pos,
int count) {
1863 const auto oldSize = range.size();
1864 if constexpr (row_features::has_insert_range) {
1865 range.insert(pos, begin, end);
1867 auto start = range.insert(pos, count, {});
1868 std::copy(begin, end, start);
1870 entries = RowFromTable<C>::next(data, entries);
1871 begin = std::begin(*entries);
1872 end = std::end(*entries);
1873 return range.size() == oldSize + count;