From 94641c510f496dbc50305cf627be09b1bda51bd0 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 24 Sep 2022 14:06:56 +0200 Subject: [PATCH] core: create range.h header for range manupulation functions The moveInVector() function was defined in qthelper.h, even though it has nothing to do with Qt. Therefore, move it into its own header. Morover, since it is a very low-level function, use snake_case. And rename it to move_in_range(), because it does not only work on vectors, but any range with random-access iterators. Signed-off-by: Berthold Stoeger --- Subsurface-mobile.pro | 1 + core/CMakeLists.txt | 1 + core/qthelper.h | 25 ------------------------ core/range.h | 32 +++++++++++++++++++++++++++++++ profile-widget/profilewidget2.cpp | 7 ++++--- qt-models/divepicturemodel.cpp | 3 ++- qt-models/diveplannermodel.cpp | 3 ++- qt-models/divetripmodel.cpp | 3 ++- 8 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 core/range.h diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index f1afbceaf..36db76407 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -206,6 +206,7 @@ HEADERS += \ core/pref.h \ core/profile.h \ core/qthelper.h \ + core/range.h \ core/save-html.h \ core/statistics.h \ core/units.h \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 54cafd7d6..83ad52eb9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -147,6 +147,7 @@ set(SUBSURFACE_CORE_LIB_SRCS qt-init.cpp qthelper.cpp qthelper.h + range.h sample.c sample.h save-git.c diff --git a/core/qthelper.h b/core/qthelper.h index ddc0d3ac3..af73cc813 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -108,31 +108,6 @@ void uiNotification(const QString &msg); #define TITLE_OR_TEXT(_t, _m) _t, _m #endif -// Move a range in a vector to a different position. -// The parameters are given according to the usual STL-semantics: -// v: a container with STL-like random access iterator via std::begin(...) -// rangeBegin: index of first element -// rangeEnd: index one *past* last element -// destination: index to element before which the range will be moved -// Owing to std::begin() magic, this function works with STL-like containers: -// QVector v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// moveInVector(v, 1, 4, 6); -// as well as with C-style arrays: -// int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// moveInVector(array, 1, 4, 6); -// Both calls will have the following effect: -// Before: 0 1 2 3 4 5 6 7 8 9 -// After: 0 4 5 1 2 3 6 7 8 9 -// No sanitizing of the input arguments is performed. -template -void moveInVector(Vector &v, int rangeBegin, int rangeEnd, int destination) -{ - auto it = std::begin(v); - if (destination > rangeEnd) - std::rotate(it + rangeBegin, it + rangeEnd, it + destination); - else if (destination < rangeBegin) - std::rotate(it + destination, it + rangeBegin, it + rangeEnd); -} #endif // 3) Functions visible to C and C++ diff --git a/core/range.h b/core/range.h new file mode 100644 index 000000000..fa4f1465c --- /dev/null +++ b/core/range.h @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +// Helper functions for range manipulations +#ifndef RANGE_H +#define RANGE_H + +// Move a range in a vector to a different position. +// The parameters are given according to the usual STL-semantics: +// v: a container with STL-like random access iterator via std::begin(...) +// rangeBegin: index of first element +// rangeEnd: index one *past* last element +// destination: index to element before which the range will be moved +// Owing to std::begin() magic, this function works with STL-like containers: +// QVector v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +// move_in_range(v, 1, 4, 6); +// as well as with C-style arrays: +// int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +// move_in_range(array, 1, 4, 6); +// Both calls will have the following effect: +// Before: 0 1 2 3 4 5 6 7 8 9 +// After: 0 4 5 1 2 3 6 7 8 9 +// No sanitizing of the input arguments is performed. +template +void move_in_range(Range &v, int rangeBegin, int rangeEnd, int destination) +{ + auto it = std::begin(v); + if (destination > rangeEnd) + std::rotate(it + rangeBegin, it + rangeEnd, it + destination); + else if (destination < rangeBegin) + std::rotate(it + destination, it + rangeBegin, it + rangeEnd); +} + +#endif diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 89d1b2840..492588fbe 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -5,6 +5,7 @@ #include "core/event.h" #include "core/subsurface-string.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/settings/qPrefTechnicalDetails.h" #include "core/settings/qPrefPartialPressureGas.h" #include "profile-widget/diveeventitem.h" @@ -868,8 +869,8 @@ void ProfileWidget2::pointsRemoved(const QModelIndex &, int start, int end) void ProfileWidget2::pointsMoved(const QModelIndex &, int start, int end, const QModelIndex &, int row) { - moveInVector(handles, start, end + 1, row); - moveInVector(gases, start, end + 1, row); + move_in_range(handles, start, end + 1, row); + move_in_range(gases, start, end + 1, row); } void ProfileWidget2::repositionDiveHandlers() @@ -1317,7 +1318,7 @@ void ProfileWidget2::pictureOffsetChanged(dive *dIn, QString filename, offset_t // Move image from old to new position int oldIndex = oldPos - pictures.begin(); int newIndex = newPos - pictures.begin(); - moveInVector(pictures, oldIndex, oldIndex + 1, newIndex); + move_in_range(pictures, oldIndex, oldIndex + 1, newIndex); } else { // Case 1b): remove picture pictures.erase(oldPos); diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index af2813e78..867929911 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -5,6 +5,7 @@ #include "core/imagedownloader.h" #include "core/picture.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/selection.h" #include "core/subsurface-qt/divelistnotifier.h" #include "commands/command.h" @@ -312,6 +313,6 @@ void DivePictureModel::pictureOffsetChanged(dive *d, const QString filenameIn, o if (oldIndex == newIndex || oldIndex + 1 == newIndex) return; beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex); - moveInVector(pictures, oldIndex, oldIndex + 1, newIndex); + move_in_range(pictures, oldIndex, oldIndex + 1, newIndex); endMoveRows(); } diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 17be91a29..058bc3821 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -7,6 +7,7 @@ #include "qt-models/models.h" #include "core/device.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/sample.h" #include "core/settings/qPrefDivePlanner.h" #include "core/settings/qPrefUnit.h" @@ -877,7 +878,7 @@ void DivePlannerPointsModel::editStop(int row, divedatapoint newData) if (newRow != row && newRow != row + 1) { beginMoveRows(QModelIndex(), row, row, QModelIndex(), newRow); - moveInVector(divepoints, row, row + 1, newRow); + move_in_range(divepoints, row, row + 1, newRow); endMoveRows(); // Account for moving the row backwards in the array. diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 2f35367a3..a4dbbf25b 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -10,6 +10,7 @@ #include "core/string-format.h" #include "core/trip.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/divesite.h" #include "core/picture.h" #include "core/subsurface-string.h" @@ -974,7 +975,7 @@ void DiveTripModelTree::topLevelChanged(int idx) // If index changed, move items if (newIdx != idx && newIdx != idx + 1) { beginMoveRows(QModelIndex(), idx, idx, QModelIndex(), newIdx); - moveInVector(items, idx, idx + 1, newIdx); + move_in_range(items, idx, idx + 1, newIdx); endMoveRows(); }