summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qdatetime.cpp114
-rw-r--r--src/corelib/tools/qdatetime.h4
-rw-r--r--src/corelib/tools/qmap.cpp18
-rw-r--r--src/corelib/tools/qmap.h12
-rw-r--r--src/corelib/tools/qregexp.cpp3
-rw-r--r--src/corelib/tools/qvector.h6
6 files changed, 89 insertions, 68 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 7d18e93dce..56dc0fade9 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -93,47 +93,67 @@ static inline QDate fixedDate(int y, int m, int d)
return result;
}
-static inline qint64 julianDayFromDate(qint64 year, int month, int day)
+static inline qint64 floordiv(qint64 a, qint64 b)
{
- // Gregorian calendar
- // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
+ return (a - (a < 0 ? b-1 : 0)) / b;
+}
+static inline qint64 floordiv(qint64 a, int b)
+{
+ return (a - (a < 0 ? b-1 : 0)) / b;
+}
+
+static inline int floordiv(int a, int b)
+{
+ return (a - (a < 0 ? b-1 : 0)) / b;
+}
+
+static inline qint64 julianDayFromDate(int year, int month, int day)
+{
+ // Adjust for no year 0
if (year < 0)
++year;
- return (1461 * (year + 4800 + (month - 14) / 12)) / 4
- + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
- - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
- + day - 32075;
+/*
+ * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php
+ * This formula is correct for all julian days, when using mathematical integer
+ * division (round to negative infinity), not c++11 integer division (round to zero)
+ */
+ int a = floordiv(14 - month, 12);
+ qint64 y = (qint64)year + 4800 - a;
+ int m = month + 12 * a - 3;
+ return day + floordiv(153 * m + 2, 5) + 365 * y + floordiv(y, 4) - floordiv(y, 100) + floordiv(y, 400) - 32045;
}
-static void getDateFromJulianDay(qint64 julianDay, int *year, int *month, int *day)
+static void getDateFromJulianDay(qint64 julianDay, int *yearp, int *monthp, int *dayp)
{
- int y, m, d;
+/*
+ * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php
+ * This formula is correct for all julian days, when using mathematical integer
+ * division (round to negative infinity), not c++11 integer division (round to zero)
+ */
+ qint64 a = julianDay + 32044;
+ qint64 b = floordiv(4 * a + 3, 146097);
+ int c = a - floordiv(146097 * b, 4);
- // Gregorian calendar
- // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
- qint64 ell, n, i, j; //TODO These will need to be bigger to prevent overflow!!!
- ell = julianDay + 68569;
- n = (4 * ell) / 146097;
- ell = ell - (146097 * n + 3) / 4;
- i = (4000 * (ell + 1)) / 1461001;
- ell = ell - (1461 * i) / 4 + 31;
- j = (80 * ell) / 2447;
- d = ell - (2447 * j) / 80;
- ell = j / 11;
- m = j + 2 - (12 * ell);
- y = 100 * (n - 49) + i + ell;
+ int d = floordiv(4 * c + 3, 1461);
+ int e = c - floordiv(1461 * d, 4);
+ int m = floordiv(5 * e + 2, 153);
- if (y<= 0)
- --y;
+ int day = e - floordiv(153 * m + 2, 5) + 1;
+ int month = m + 3 - 12 * floordiv(m, 10);
+ int year = 100 * b + d - 4800 + floordiv(m, 10);
- if (year)
- *year = y;
- if (month)
- *month = m;
- if (day)
- *day = d;
+ // Adjust for no year 0
+ if (year <= 0)
+ --year ;
+
+ if (yearp)
+ *yearp = year;
+ if (monthp)
+ *monthp = month;
+ if (dayp)
+ *dayp = day;
}
@@ -225,14 +245,8 @@ static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* d
QDate::toJulianDay() and can be set using QDate::fromJulianDay().
The range of dates able to be stored by QDate as a Julian Day number is
- limited for convenience from std::numeric_limits<qint64>::min() / 2 to
- std::numeric_limits<qint64>::max() / 2, which on most platforms means
- from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively
- covering the full range of astronomical time. The range of Julian Days
- able to be accurately converted to and from valid YMD form Dates is
- restricted to 1 January 4800 BCE to 31 December 1400000 CE due to
- shortcomings in the available conversion formulas. Conversions outside this
- range are not guaranteed to be correct. This may change in the future.
+ for technical reasons limited to between -784350574879 and 784354017364,
+ which means from before 2 billion BCE to after 2 billion CE.
\sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
*/
@@ -859,9 +873,6 @@ QString QDate::toString(const QString& format) const
If the specified date is invalid, the QDate object is set to be
invalid.
- Note that any date before 4800 BCE or after about 1.4 million CE
- may not be accurately stored.
-
\sa isValid()
*/
bool QDate::setDate(int year, int month, int day)
@@ -882,9 +893,6 @@ bool QDate::setDate(int year, int month, int day)
Returns 0 if the date is invalid.
- Note that any date before 4800 BCE or after about 1.4 million CE
- may not be accurately stored.
-
\sa year(), month(), day(), isValid()
*/
void QDate::getDate(int *year, int *month, int *day)
@@ -2100,14 +2108,8 @@ int QTime::elapsed() const
QDate::toJulianDay() and can be set using QDate::fromJulianDay().
The range of dates able to be stored by QDate as a Julian Day number is
- limited for convenience from std::numeric_limits<qint64>::min() / 2 to
- std::numeric_limits<qint64>::max() / 2, which on most platforms means
- from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively
- covering the full range of astronomical time. The range of Julian Days
- able to be accurately converted to and from valid YMD form Dates is
- restricted to 1 January 4800 BCE to 31 December 1400000 CE due to
- shortcomings in the available conversion formulas. Conversions outside this
- range are not guaranteed to be correct. This may change in the future.
+ for technical reasons limited to between -784350574879 and 784354017364,
+ which means from before 2 billion BCE to after 2 billion CE.
\section2
Use of System Timezone
@@ -2418,7 +2420,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
QDateTimePrivate::Spec oldSpec = d->spec;
- int ddays = msecs / MSECS_PER_DAY;
+ qint64 ddays = msecs / MSECS_PER_DAY;
msecs %= MSECS_PER_DAY;
if (msecs < 0) {
// negative
@@ -3391,10 +3393,11 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
int year;
QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
+ // Year is after time, e.g. "Sun Dec 1 13:02:00 1974"
year = parts.at(4).toInt(&ok);
if (!ok)
return QDateTime();
- } else {
+ } else { // Year is before time, e.g. "Sun Dec 1 1974 13:02:00"
timeParts = parts.at(4).split(QLatin1Char(':'));
if ((timeParts.count() != 3) && (timeParts.count() != 2))
return QDateTime();
@@ -3743,7 +3746,8 @@ static bool hasUnquotedAP(const QString &f)
for (int i=0; i<max; ++i) {
if (f.at(i) == quote) {
inquote = !inquote;
- } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
+ } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')
+ && i + 1 < max && f.at(i + 1).toUpper() == QLatin1Char('P')) {
return true;
}
}
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index ed7d8adb5f..22db5a4830 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -121,8 +121,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d)
private:
static inline qint64 nullJd() { return std::numeric_limits<qint64>::min(); }
- static inline qint64 minJd() { return std::numeric_limits<qint64>::min() / 2; }
- static inline qint64 maxJd() { return (std::numeric_limits<qint64>::max()) / 2; }
+ static inline qint64 minJd() { return Q_INT64_C(-784350574879); }
+ static inline qint64 maxJd() { return Q_INT64_C( 784354017364); }
qint64 jd;
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index dea87c6b63..7c33d60750 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 } };
+const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 }, 0 };
const QMapNodeBase *QMapNodeBase::nextNode() const
{
@@ -177,6 +177,12 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
QMapNodeBase *x_parent;
if (y->left == 0) {
x = y->right;
+ if (y == mostLeftNode) {
+ if (x)
+ mostLeftNode = x; // It cannot have (left) children due the red black invariant.
+ else
+ mostLeftNode = y->parent();
+ }
} else {
if (y->right == 0) {
x = y->left;
@@ -290,6 +296,13 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
--size;
}
+void QMapDataBase::recalcMostLeftNode()
+{
+ mostLeftNode = &header;
+ while (mostLeftNode->left)
+ mostLeftNode = mostLeftNode->left;
+}
+
static inline int qMapAlignmentThreshold()
{
// malloc on 32-bit platforms should return pointers that are 8-byte
@@ -324,6 +337,8 @@ QMapNodeBase *QMapDataBase::createNode(int alloc, int alignment, QMapNodeBase *p
if (parent) {
if (left) {
parent->left = node;
+ if (parent == mostLeftNode)
+ mostLeftNode = node;
} else {
parent->right = node;
}
@@ -352,6 +367,7 @@ QMapDataBase *QMapDataBase::createData()
d->header.p = 0;
d->header.left = 0;
d->header.right = 0;
+ d->mostLeftNode = &(d->header);
return d;
}
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 642cf82f08..d44a79473d 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -173,11 +173,13 @@ struct Q_CORE_EXPORT QMapDataBase
QtPrivate::RefCount ref;
int size;
QMapNodeBase header;
+ QMapNodeBase *mostLeftNode;
void rotateLeft(QMapNodeBase *x);
void rotateRight(QMapNodeBase *x);
void rebalance(QMapNodeBase *x);
void freeNodeAndRebalance(QMapNodeBase *z);
+ void recalcMostLeftNode();
QMapNodeBase *createNode(int size, int alignment, QMapNodeBase *parent, bool left);
void freeTree(QMapNodeBase *root, int alignment);
@@ -197,8 +199,8 @@ struct QMapData : public QMapDataBase
const Node *end() const { return static_cast<const Node *>(&header); }
Node *end() { return static_cast<Node *>(&header); }
- const Node *begin() const { if (root()) return root()->minimumNode(); return end(); }
- Node *begin() { if (root()) return root()->minimumNode(); return end(); }
+ const Node *begin() const { if (root()) return static_cast<const Node*>(mostLeftNode); return end(); }
+ Node *begin() { if (root()) return static_cast<Node*>(mostLeftNode); return end(); }
void deleteNode(Node *z);
Node *findNode(const Key &akey) const;
@@ -555,6 +557,7 @@ inline QMap<Key, T>::QMap(const QMap<Key, T> &other)
if (other.d->header.left) {
d->header.left = static_cast<Node *>(other.d->header.left)->copy(d);
d->header.left->setParent(&d->header);
+ d->recalcMostLeftNode();
}
}
}
@@ -780,6 +783,7 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper()
if (!d->ref.deref())
d->destroy();
d = x;
+ d->recalcMostLeftNode();
}
template <class Key, class T>
@@ -935,7 +939,7 @@ Q_OUTOFLINE_TEMPLATE QMap<Key, T>::QMap(const std::map<Key, T> &other)
typename std::map<Key,T>::const_iterator it = other.end();
while (it != other.begin()) {
--it;
- insert((*it).first, (*it).second);
+ d->createNode((*it).first, (*it).second, d->begin(), true); // insert on most left node.
}
}
@@ -946,7 +950,7 @@ Q_OUTOFLINE_TEMPLATE std::map<Key, T> QMap<Key, T>::toStdMap() const
const_iterator it = end();
while (it != begin()) {
--it;
- map.insert(std::pair<Key, T>(it.key(), it.value()));
+ map.insert(map.begin(), std::pair<Key, T>(it.key(), it.value()));
}
return map;
}
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index e87e5efc1f..7aea083788 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -1324,14 +1324,11 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &pattern, QRegExp::Pat
#ifndef QT_NO_REGEXP_WILDCARD
case QRegExp::Wildcard:
return wc2rx(pattern, false);
- break;
case QRegExp::WildcardUnix:
return wc2rx(pattern, true);
- break;
#endif
case QRegExp::FixedString:
return QRegExp::escape(pattern);
- break;
case QRegExp::W3CXmlSchema11:
default:
return pattern;
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 94733f77da..2c688db507 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -252,7 +252,7 @@ void QVector<T>::defaultConstruct(T *from, T *to)
new (from++) T();
}
} else {
- ::memset(from, 0, (to - from) * sizeof(T));
+ ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T));
}
}
@@ -267,7 +267,7 @@ void QVector<T>::copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom)
while (srcFrom != srcTo)
new (dstFrom++) T(*srcFrom++);
} else {
- ::memcpy(dstFrom, srcFrom, (srcTo - srcFrom) * sizeof(T));
+ ::memcpy(static_cast<void *>(dstFrom), static_cast<const void *>(srcFrom), (srcTo - srcFrom) * sizeof(T));
}
}
@@ -467,7 +467,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
new (dst++) T(*srcBegin++);
}
} else {
- ::memcpy(static_cast<void *>(dst), srcBegin, (srcEnd - srcBegin) * sizeof(T));
+ ::memcpy(static_cast<void *>(dst), static_cast<void *>(srcBegin), (srcEnd - srcBegin) * sizeof(T));
dst += srcEnd - srcBegin;
// destruct unused / not moved data