Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICU-22994 Use C++ typeid() instead of Calendar::getType() for calendar type comparison #3310

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions icu4c/source/i18n/datefmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
#include <stdio.h>
#endif
#include <typeinfo>

// *****************************************************************************
// class DateFormat
Expand Down Expand Up @@ -279,9 +280,8 @@ UnicodeString&
DateFormat::format(UDate date, UnicodeString& appendTo, FieldPosition& fieldPosition) const {
if (fCalendar != nullptr) {
UErrorCode ec = U_ZERO_ERROR;
const auto* calType = fCalendar->getType();
// Avoid a heap allocation and corresponding free for the common case
if (uprv_strcmp(calType, "gregorian") == 0) {
if (typeid(*fCalendar) == typeid(GregorianCalendar)) {
GregorianCalendar cal(*static_cast<GregorianCalendar*>(fCalendar));
cal.setTime(date, ec);
if (U_SUCCESS(ec)) {
Expand Down Expand Up @@ -309,9 +309,8 @@ DateFormat::format(UDate date, UnicodeString& appendTo, FieldPositionIterator* p
UErrorCode& status) const {
if (fCalendar != nullptr) {
UErrorCode ec = U_ZERO_ERROR;
const auto* calType = fCalendar->getType();
// Avoid a heap allocation and corresponding free for the common case
if (uprv_strcmp(calType, "gregorian") == 0) {
if (typeid(*fCalendar) == typeid(GregorianCalendar)) {
GregorianCalendar cal(*static_cast<GregorianCalendar*>(fCalendar));
cal.setTime(date, ec);
if (U_SUCCESS(ec)) {
Expand Down
30 changes: 18 additions & 12 deletions icu4c/source/i18n/smpdtfmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@
#include "dayperiodrules.h"
#include "tznames_impl.h" // ZONE_NAME_U16_MAX
#include "number_utypes.h"
#include "chnsecal.h"
#include "dangical.h"
#include "japancal.h"
#include <typeinfo>

#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
#include <stdio.h>
Expand Down Expand Up @@ -945,7 +949,8 @@ SimpleDateFormat::initialize(const Locale& locale,
// if format is non-numeric (includes 年) and fDateOverride is not already specified.
// Now this does get updated if applyPattern subsequently changes the pattern type.
if (fDateOverride.isBogus() && fHasHanYearChar &&
fCalendar != nullptr && uprv_strcmp(fCalendar->getType(),"japanese") == 0 &&
fCalendar != nullptr &&
typeid(*fCalendar) == typeid(JapaneseCalendar) &&
uprv_strcmp(fLocale.getLanguage(),"ja") == 0) {
fDateOverride.setTo(u"y=jpanyear", -1);
}
Expand Down Expand Up @@ -1050,7 +1055,7 @@ SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
}
Calendar* workCal = &cal;
Calendar* calClone = nullptr;
if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
if (&cal != fCalendar && typeid(cal) != typeid(*fCalendar)) {
// Different calendar type
// We use the time and time zone from the input calendar, but
// do not use the input calendar for field calculation.
Expand Down Expand Up @@ -1523,8 +1528,8 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
// "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
case UDAT_ERA_FIELD:
{
const auto* calType = cal.getType();
if (uprv_strcmp(calType,"chinese") == 0 || uprv_strcmp(calType,"dangi") == 0) {
if (typeid(cal) == typeid(ChineseCalendar) ||
typeid(cal) == typeid(DangiCalendar)) {
zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, 9); // as in ICU4J
} else {
if (count == 5) {
Expand Down Expand Up @@ -1575,7 +1580,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
// for "MMMMM"/"LLLLL", use the narrow form
case UDAT_MONTH_FIELD:
case UDAT_STANDALONE_MONTH_FIELD:
if (uprv_strcmp(cal.getType(),"hebrew") == 0) {
if (typeid(cal) == typeid(HebrewCalendar)) {
if (HebrewCalendar::isLeapYear(cal.get(UCAL_YEAR,status)) && value == 6 && count >= 3 )
value = 13; // Show alternate form for Adar II in leap years in Hebrew calendar.
if (!HebrewCalendar::isLeapYear(cal.get(UCAL_YEAR,status)) && value >= 6 && count < 3 )
Expand Down Expand Up @@ -2272,7 +2277,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&

Calendar* calClone = nullptr;
Calendar *workCal = &cal;
if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
if (&cal != fCalendar && typeid(cal) != typeid(*fCalendar)) {
// Different calendar type
// We use the time/zone from the input calendar, but
// do not use the input calendar for field calculation.
Expand Down Expand Up @@ -2903,7 +2908,7 @@ int32_t SimpleDateFormat::matchAlphaMonthStrings(const UnicodeString& text,

if (bestMatch >= 0) {
// Adjustment for Hebrew Calendar month Adar II
if (!strcmp(cal.getType(),"hebrew") && bestMatch==13) {
if (typeid(cal) == typeid(HebrewCalendar) && bestMatch==13) {
cal.set(UCAL_MONTH,6);
} else {
cal.set(UCAL_MONTH, bestMatch);
Expand Down Expand Up @@ -2963,7 +2968,7 @@ int32_t SimpleDateFormat::matchString(const UnicodeString& text,
if (bestMatch >= 0) {
if (field < UCAL_FIELD_COUNT) {
// Adjustment for Hebrew Calendar month Adar II
if (!strcmp(cal.getType(),"hebrew") && field==UCAL_MONTH && bestMatch==13) {
if (typeid(cal) == typeid(HebrewCalendar) && field==UCAL_MONTH && bestMatch==13) {
cal.set(field,6);
} else {
if (field == UCAL_YEAR) {
Expand Down Expand Up @@ -3052,7 +3057,6 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
if (numericLeapMonthFormatter != nullptr) {
numericLeapMonthFormatter->setFormats(reinterpret_cast<const Format**>(&currentNumberFormat), 1);
}
UBool isChineseCalendar = (uprv_strcmp(cal.getType(),"chinese") == 0 || uprv_strcmp(cal.getType(),"dangi") == 0);

// If there are any spaces here, skip over them. If we hit the end
// of the string, then fail.
Expand All @@ -3068,6 +3072,8 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
}
pos.setIndex(start);

UBool isChineseCalendar = typeid(cal) == typeid(ChineseCalendar) ||
typeid(cal) == typeid(DangiCalendar);
// We handle a few special cases here where we need to parse
// a number value. We handle further, more generic cases below. We need
// to handle some of them here because some fields require extra processing on
Expand Down Expand Up @@ -3289,7 +3295,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
// When parsing month numbers from the Hebrew Calendar, we might need to adjust the month depending on whether
// or not it was a leap year. We may or may not yet know what year it is, so might have to delay checking until
// the year is parsed.
if (!strcmp(cal.getType(),"hebrew")) {
if (typeid(cal) == typeid(HebrewCalendar)) {
HebrewCalendar *hc = (HebrewCalendar*)&cal;
if (cal.isSet(UCAL_YEAR)) {
UErrorCode monthStatus = U_ZERO_ERROR;
Expand Down Expand Up @@ -3852,7 +3858,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
switch (patternCharIndex) {
case UDAT_MONTH_FIELD:
// See notes under UDAT_MONTH_FIELD case above
if (!strcmp(cal.getType(),"hebrew")) {
if (typeid(cal) == typeid(HebrewCalendar)) {
HebrewCalendar *hc = (HebrewCalendar*)&cal;
if (cal.isSet(UCAL_YEAR)) {
UErrorCode monthStatus = U_ZERO_ERROR;
Expand Down Expand Up @@ -4034,7 +4040,7 @@ SimpleDateFormat::applyPattern(const UnicodeString& pattern)

// Hack to update use of Gannen year numbering for ja@calendar=japanese -
// use only if format is non-numeric (includes 年) and no other fDateOverride.
if (fCalendar != nullptr && uprv_strcmp(fCalendar->getType(),"japanese") == 0 &&
if (fCalendar != nullptr && typeid(*fCalendar) == typeid(JapaneseCalendar) &&
uprv_strcmp(fLocale.getLanguage(),"ja") == 0) {
if (fDateOverride==UnicodeString(u"y=jpanyear") && !fHasHanYearChar) {
// Gannen numbering is set but new pattern should not use it, unset;
Expand Down
5 changes: 3 additions & 2 deletions icu4c/source/i18n/windtfmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
# define NOIME
# define NOMCX
#include <windows.h>
#include <typeinfo>

U_NAMESPACE_BEGIN

Expand Down Expand Up @@ -251,7 +252,7 @@ UnicodeString &Win32DateFormat::format(Calendar &cal, UnicodeString &appendTo, F
formatDate(&st_local, date);
formatTime(&st_local, time);

if (strcmp(fCalendar->getType(), cal.getType()) != 0) {
if (typeid(cal) != typeid(*fCalendar)) {
pattern = getTimeDateFormat(&cal, &fLocale, status);
}

Expand All @@ -272,7 +273,7 @@ void Win32DateFormat::parse(const UnicodeString& /* text */, Calendar& /* cal */

void Win32DateFormat::adoptCalendar(Calendar *newCalendar)
{
if (fCalendar == nullptr || strcmp(fCalendar->getType(), newCalendar->getType()) != 0) {
if (fCalendar == nullptr || typeid(*fCalendar) != typeid(*newCalendar)) {
UErrorCode status = U_ZERO_ERROR;

if (fDateStyle != DateFormat::kNone && fTimeStyle != DateFormat::kNone) {
Expand Down
Loading