summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2020-08-07 15:13:00 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-10-06 10:48:23 +0000
commit4178673ce8024459fb6d8e27947936a03e2ed295 (patch)
tree89f4582dae4655b0b15c5852f081a3ca51952b53
parent83a96cbc5113adcecaf5845be9f6c27efa6bf9d2 (diff)
Break out calendar backend-from-enum as a static function
This lets the registry's populate() avoid recursing into constructors that are typically what (indirectly) called it. This, in turn, makes it possible to assert the constructor from enum gets what it expects. Change-Id: I190f9dcfe405e3ee1c6a3f0926fa33cf9ddf64e0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 48cc034c3fad709e7c145a3793d6521b944b36c2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/time/qcalendar.cpp65
1 files changed, 38 insertions, 27 deletions
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index 9b892efe8e..b25b84ba9b 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -49,6 +49,8 @@
QT_BEGIN_NAMESPACE
+static const QCalendarBackend *backendFromEnum(QCalendar::System system);
+
namespace {
struct CalendarName : public QString
@@ -121,8 +123,10 @@ struct Registry {
if (populated)
return;
- for (int i = 0; i <= int(QCalendar::System::Last); ++i)
- (void)QCalendar(QCalendar::System(i));
+ for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
+ if (!byId[i])
+ (void)backendFromEnum(QCalendar::System(i));
+ }
populated = true;
}
@@ -132,6 +136,32 @@ struct Registry {
Q_GLOBAL_STATIC(Registry, calendarRegistry);
+static const QCalendarBackend *backendFromEnum(QCalendar::System system)
+{
+ switch (system) {
+ case QCalendar::System::Gregorian:
+ return new QGregorianCalendar;
+#ifndef QT_BOOTSTRAPPED
+ case QCalendar::System::Julian:
+ return new QJulianCalendar;
+ case QCalendar::System::Milankovic:
+ return new QMilankovicCalendar;
+#endif
+#if QT_CONFIG(jalalicalendar)
+ case QCalendar::System::Jalali:
+ return new QJalaliCalendar;
+#endif
+#if QT_CONFIG(islamiccivilcalendar)
+ case QCalendar::System::IslamicCivil:
+ return new QIslamicCivilCalendar;
+#else // When highest-numbered system isn't enabled, ensure we have a case for Last:
+ case QCalendar::System::Last:
+#endif
+ case QCalendar::System::User:
+ Q_UNREACHABLE();
+ }
+ return nullptr;
+}
/*!
\since 5.14
@@ -159,7 +189,7 @@ Q_GLOBAL_STATIC(Registry, calendarRegistry);
Most backends are pure code, with no data elements. Such backends should
normally be implemented as singletons. For a backend to be added to the
QCalendar::System \c enum, it should be such a singleton, with a case in
- QCalendar::fromEnum()'s switch statement to instantiate it.
+ backendFromEnum()'s switch statement (above) to instantiate it.
Non-singleton calendar backends should ensure that each instance is created
with a distinct primary name. Later instances attempting to register with a
@@ -632,29 +662,7 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
Q_ASSERT(calendarRegistry->byId.size() >= size_t(system));
if (auto *c = calendarRegistry->byId[size_t(system)])
return c;
- switch (system) {
- case QCalendar::System::Gregorian:
- return new QGregorianCalendar;
-#ifndef QT_BOOTSTRAPPED
- case QCalendar::System::Julian:
- return new QJulianCalendar;
- case QCalendar::System::Milankovic:
- return new QMilankovicCalendar;
-#endif
-#if QT_CONFIG(jalalicalendar)
- case QCalendar::System::Jalali:
- return new QJalaliCalendar;
-#endif
-#if QT_CONFIG(islamiccivilcalendar)
- case QCalendar::System::IslamicCivil:
- return new QIslamicCivilCalendar;
-#else // When highest-numbered system isn't enabled, ensure we have a case for Last:
- case QCalendar::System::Last:
-#endif
- case QCalendar::System::User:
- Q_UNREACHABLE();
- }
- return nullptr;
+ return backendFromEnum(system);
}
/*!
@@ -727,7 +735,10 @@ QCalendar::QCalendar()
}
QCalendar::QCalendar(QCalendar::System system)
- : d(QCalendarBackend::fromEnum(system)) {}
+ : d(QCalendarBackend::fromEnum(system))
+{
+ Q_ASSERT(d);
+}
QCalendar::QCalendar(QLatin1String name)
: d(QCalendarBackend::fromName(name)) {}