summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydata.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-06-02 15:51:15 +0200
committerLars Knoll <lars.knoll@qt.io>2020-06-09 16:51:16 +0200
commitd2833a3ce5af725d66ef9338f2a61b766dd3cb2d (patch)
tree3b74823b5f2da7cfd179e4faeed1697c4ff14d09 /src/corelib/tools/qarraydata.h
parentfd856532d7472ccc6daf6a95d5c28264d9e6adca (diff)
Ensure left/right/mid behave in a compatible way
QString and QStringRef did bounds checking for left/right/mid, whereas QStringView was asserting on out of bounds. Relax the behavior for QStringView and do bounds checking on pos/n as well. This removes a source of potentially hidden errors when porting from QStringRef (or QString) to QStringView. Unfortunately, one difference remains, where QByteArray::left/right() behaves differently (and somewhat more sane) than QString and QStringRef. We're keeping the difference here, as it has been around for many years. Mark left/right/mid as obsolete and to be replaced with the new first/last/slice methods. Change-Id: I18c203799ba78c928a4610a6038089f27696c22e Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydata.h')
-rw-r--r--src/corelib/tools/qarraydata.h32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index b6fc05e108..de52713348 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -306,7 +306,37 @@ namespace QtPrivate {
struct Q_CORE_EXPORT QContainerImplHelper
{
enum CutResult { Null, Empty, Full, Subset };
- static CutResult mid(int originalLength, int *position, int *length);
+ static constexpr CutResult mid(qsizetype originalLength, qsizetype *_position, qsizetype *_length)
+ {
+ qsizetype &position = *_position;
+ qsizetype &length = *_length;
+ if (position > originalLength) {
+ position = 0;
+ length = 0;
+ return Null;
+ }
+
+ if (position < 0) {
+ if (length < 0 || length + position >= originalLength) {
+ position = 0;
+ length = originalLength;
+ return Full;
+ }
+ if (length + position <= 0) {
+ position = length = 0;
+ return Null;
+ }
+ length += position;
+ position = 0;
+ } else if (size_t(length) > size_t(originalLength - position)) {
+ length = originalLength - position;
+ }
+
+ if (position == 0 && length == originalLength)
+ return Full;
+
+ return length > 0 ? Subset : Empty;
+ }
};
}