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 <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2022-09-24 14:06:56 +02:00
parent 261f07dfa4
commit 94641c510f
8 changed files with 44 additions and 31 deletions

View file

@ -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 \

View file

@ -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

View file

@ -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<int> 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 <typename Vector>
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++

32
core/range.h Normal file
View file

@ -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<int> 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 <typename Range>
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

View file

@ -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);

View file

@ -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();
}

View file

@ -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.

View file

@ -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();
}