ICU-7455 use compiler RTTI; stop adding poor mans RTTI to new class hierarchies

X-SVN-Rev: 28075
This commit is contained in:
Markus Scherer 2010-05-19 17:29:33 +00:00
parent 6dce030d93
commit f6a04770ff
71 changed files with 619 additions and 488 deletions

View File

@ -240,8 +240,6 @@ FilteredNormalizer2::isInert(UChar32 c) const {
return !set.contains(c) || norm2.isInert(c);
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(FilteredNormalizer2)
U_NAMESPACE_END
// C API ------------------------------------------------------------------- ***

View File

@ -89,13 +89,8 @@ class NoopNormalizer2 : public Normalizer2 {
virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; }
virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; }
virtual UBool isInert(UChar32) const { return TRUE; }
static UClassID U_EXPORT2 getStaticClassID();
virtual UClassID getDynamicClassID() const;
};
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NoopNormalizer2)
// Intermediate class:
// Has Normalizer2Impl and does boilerplate argument checking and setup.
class Normalizer2WithImpl : public Normalizer2 {
@ -203,14 +198,9 @@ public:
return UNORM_YES;
}
static UClassID U_EXPORT2 getStaticClassID();
virtual UClassID getDynamicClassID() const;
const Normalizer2Impl &impl;
};
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Normalizer2WithImpl)
class DecomposeNormalizer2 : public Normalizer2WithImpl {
public:
DecomposeNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
@ -611,7 +601,7 @@ Normalizer2::getInstance(const char *packageName,
return NULL;
}
UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(Normalizer2)
UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(Normalizer2)
U_NAMESPACE_END
@ -646,9 +636,9 @@ unorm2_normalize(const UNormalizer2 *norm2,
}
UnicodeString destString(dest, 0, capacity);
const Normalizer2 *n2=(const Normalizer2 *)norm2;
if(n2->getDynamicClassID()==Normalizer2WithImpl::getStaticClassID()) {
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
if(n2wi!=NULL) {
// Avoid duplicate argument checking and support NUL-terminated src.
const Normalizer2WithImpl *n2wi=(const Normalizer2WithImpl *)n2;
ReorderingBuffer buffer(n2wi->impl, destString);
if(buffer.init(length, *pErrorCode)) {
n2wi->normalize(src, length>=0 ? src+length : NULL, buffer, *pErrorCode);
@ -678,9 +668,9 @@ normalizeSecondAndAppend(const UNormalizer2 *norm2,
}
UnicodeString firstString(first, firstLength, firstCapacity);
const Normalizer2 *n2=(const Normalizer2 *)norm2;
if(n2->getDynamicClassID()==Normalizer2WithImpl::getStaticClassID()) {
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
if(n2wi!=NULL) {
// Avoid duplicate argument checking and support NUL-terminated src.
const Normalizer2WithImpl *n2wi=(const Normalizer2WithImpl *)n2;
ReorderingBuffer buffer(n2wi->impl, firstString);
if(buffer.init(firstLength+secondLength+1, *pErrorCode)) { // destCapacity>=-1
n2wi->normalizeAndAppend(second, secondLength>=0 ? second+secondLength : NULL,

View File

@ -1,7 +1,7 @@
/*
***************************************************************************
* Copyright (C) 1999-2009 International Business Machines Corporation *
* and others. All rights reserved. *
* Copyright (C) 1999-2010 International Business Machines Corporation
* and others. All rights reserved.
***************************************************************************
*/
//
@ -10,6 +10,8 @@
// class RuleBasedBreakIterator
//
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_BREAK_ITERATION
@ -290,7 +292,7 @@ RuleBasedBreakIterator::clone(void) const {
*/
UBool
RuleBasedBreakIterator::operator==(const BreakIterator& that) const {
if (that.getDynamicClassID() != getDynamicClassID()) {
if (typeid(*this) != typeid(that)) {
return FALSE;
}

View File

@ -1,7 +1,7 @@
/*
******************************************************************************
* Copyright (C) 1998-2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1998-2010, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*
* File schriter.cpp
@ -13,6 +13,8 @@
******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/chariter.h"
#include "unicode/schriter.h"
@ -85,7 +87,7 @@ StringCharacterIterator::operator==(const ForwardCharacterIterator& that) const
// because that checks for array pointer equality
// while we compare UnicodeString objects
if (getDynamicClassID() != that.getDynamicClassID()) {
if (typeid(*this) != typeid(that)) {
return FALSE;
}

View File

@ -1,7 +1,7 @@
/**
*******************************************************************************
* Copyright (C) 2001-2008, International Business Machines Corporation. *
* All Rights Reserved. *
* Copyright (C) 2001-2010, International Business Machines Corporation.
* All Rights Reserved.
*******************************************************************************
*/
@ -948,7 +948,7 @@ ICUService::clearServiceCache()
UBool
ICUService::acceptsListener(const EventListener& l) const
{
return l.getDynamicClassID() == ServiceListener::getStaticClassID();
return dynamic_cast<const ServiceListener*>(&l) != NULL;
}
void

View File

@ -1,10 +1,12 @@
/*
******************************************************************************
* Copyright (C) 1998-2004, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1998-2010, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/uchriter.h"
#include "unicode/ustring.h"
#include "uhash.h"
@ -66,8 +68,7 @@ UCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()) {
if (typeid(*this) != typeid(that)) {
return FALSE;
}

View File

@ -279,19 +279,9 @@ public:
*/
virtual UBool isInert(UChar32 c) const = 0;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
* @returns a UClassID for this class.
* @draft ICU 4.4
*/
static UClassID U_EXPORT2 getStaticClassID();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
* @return a UClassID for the actual class.
* @draft ICU 4.4
*/
virtual UClassID getDynamicClassID() const = 0;
private:
// No ICU "poor man's RTTI" for this class nor its subclasses.
virtual UClassID getDynamicClassID() const;
};
/**
@ -442,20 +432,6 @@ public:
* @draft ICU 4.4
*/
virtual UBool isInert(UChar32 c) const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
* @returns a UClassID for this class.
* @draft ICU 4.4
*/
static UClassID U_EXPORT2 getStaticClassID();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
* @return a UClassID for the actual class.
* @draft ICU 4.4
*/
virtual UClassID getDynamicClassID() const;
private:
UnicodeString &
normalize(const UnicodeString &src,

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1999-2006, International Business Machines Corporation and others.
* Copyright (C) 1999-2010, International Business Machines Corporation and others.
* All Rights Reserved.
**********************************************************************
* Date Name Description
@ -96,13 +96,6 @@ public:
*/
virtual void setData(const TransliterationRuleData*);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @stable ICU 2.2
*/
virtual UClassID getDynamicClassID() const = 0;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*

View File

@ -317,6 +317,19 @@ protected:
return (UClassID)&classID; \
}
/**
* This is a simple macro to express that a class and its subclasses do not offer
* ICU's "poor man's RTTI".
* Beginning with ICU 4.6, ICU requires C++ compiler RTTI.
* This does not go into the header. This should only be used in *.cpp files.
* Use this with a private getDynamicClassID() in an immediate subclass of UObject.
*
* @param myClass The name of the class that needs RTTI defined.
* @internal
*/
#define UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(myClass) \
UClassID myClass::getDynamicClassID() const { return NULL; }
// /**
// * This macro adds ICU RTTI to an ICU concrete class implementation.
// * This macro should be invoked in *.cpp files. The corresponding

View File

@ -609,13 +609,14 @@ void UnicodeSet::applyPattern(RuleCharacterIterator& chars,
} else if (symbols != 0) {
const UnicodeFunctor *m = symbols->lookupMatcher(c);
if (m != 0) {
if (m->getDynamicClassID() != UnicodeSet::getStaticClassID()) {
const UnicodeSet *ms = dynamic_cast<const UnicodeSet *>(m);
if (ms == NULL) {
ec = U_MALFORMED_SET;
return;
}
// casting away const, but `nested' won't be modified
// (important not to modify stored set)
nested = (UnicodeSet*) m;
nested = const_cast<UnicodeSet*>(ms);
setMode = 3;
}
}

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2009, International Business Machines
* Copyright (c) 2002-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -8,6 +8,8 @@
* Since: ICU 2.4
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/ustring.h"
#include "unicode/strenum.h"
#include "unicode/putil.h"
@ -113,7 +115,7 @@ StringEnumeration::setChars(const char *s, int32_t length, UErrorCode &status) {
}
UBool
StringEnumeration::operator==(const StringEnumeration& that)const {
return getDynamicClassID() == that.getDynamicClassID();
return typeid(*this) == typeid(that);
}
UBool

View File

@ -1,6 +1,6 @@
## -*-makefile-*-
## Aix-specific setup (for Visual Age 5+)
## Copyright (c) 1999-2009, International Business Machines Corporation and
## Copyright (c) 1999-2010, International Business Machines Corporation and
## others. All Rights Reserved.
## Commands to generate dependency files
@ -10,8 +10,9 @@ GEN_DEPS.cc= $(CXX) -E -M $(DEFS) $(CPPFLAGS)
# -qroconst make the strings readonly, which is usually the default.
# This helps in the data library,
# -qproto assumes all functions are prototyped (for optimization)
# -qrtti turns on compiler RTTI, required beginning with ICU 4.6
CFLAGS += -qproto -qroconst
CXXFLAGS += -qproto -qroconst
CXXFLAGS += -qproto -qroconst -qrtti
# If you readd this line, you must change the SO value
#LDFLAGS += -brtl

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2007-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -377,9 +377,9 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial,
if (done[i]) {
continue;
}
if (toRule->getDynamicClassID() == TimeArrayTimeZoneRule::getStaticClassID()) {
TimeArrayTimeZoneRule *tar = (TimeArrayTimeZoneRule*)toRule;
const TimeArrayTimeZoneRule *tar = dynamic_cast<const TimeArrayTimeZoneRule *>(toRule);
const AnnualTimeZoneRule *ar;
if (tar != NULL) {
// Get the previous raw offset and DST savings before the very first start time
TimeZoneTransition tzt0;
t = start;
@ -448,8 +448,7 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial,
}
}
}
} else if (toRule->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()) {
AnnualTimeZoneRule *ar = (AnnualTimeZoneRule*)toRule;
} else if ((ar = dynamic_cast<const AnnualTimeZoneRule *>(toRule)) != NULL) {
ar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart);
if (firstStart == tzt.getTime()) {
// Just add the rule as is

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 2008-2009, International Business Machines
* Copyright (C) 2008-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Date Name Description
@ -173,11 +173,13 @@ BreakIterator *BreakTransliterator::getBreakIterator() {
// will normally be efficient.
//
UnicodeString BreakTransliterator::replaceableAsString(Replaceable &r) {
if (r.getDynamicClassID() == UnicodeString::getStaticClassID()) {
return (UnicodeString &) r;
}
UnicodeString s;
r.extractBetween(0, r.length(), s);
UnicodeString *rs = dynamic_cast<UnicodeString *>(&r);
if (rs != NULL) {
s = *rs;
} else {
r.extractBetween(0, r.length(), s);
}
return s;
}

View File

@ -24,6 +24,8 @@
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -371,7 +373,7 @@ protected:
virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const {
#ifdef U_DEBUG_CALSVC
if(key.getDynamicClassID() != LocaleKey::getStaticClassID()) {
if(dynamic_cast<const LocaleKey*>(&key) == NULL) {
fprintf(stderr, "::create - not a LocaleKey!\n");
}
#endif
@ -442,8 +444,9 @@ public:
}
virtual UObject* cloneInstance(UObject* instance) const {
if(instance->getDynamicClassID() == UnicodeString::getStaticClassID()) {
return ((UnicodeString*)instance)->clone();
UnicodeString *s = dynamic_cast<UnicodeString *>(instance);
if(s != NULL) {
return s->clone();
} else {
#ifdef U_DEBUG_CALSVC_F
UErrorCode status2 = U_ZERO_ERROR;
@ -811,13 +814,12 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
}
#if !UCONFIG_NO_SERVICE
if(u->getDynamicClassID() == UnicodeString::getStaticClassID()) {
const UnicodeString* str = dynamic_cast<const UnicodeString*>(u);
if(str != NULL) {
// It's a unicode string telling us what type of calendar to load ("gregorian", etc)
const UnicodeString& str = *(UnicodeString*)u;
// Create a Locale over this string
Locale l("");
LocaleUtility::initLocaleFromName(str, l);
LocaleUtility::initLocaleFromName(*str, l);
#ifdef U_DEBUG_CALSVC
fprintf(stderr, "Calendar::createInstance(%s), looking up [%s]\n", aLocale.getName(), l.getName());
@ -840,19 +842,19 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
return NULL;
}
if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) {
str = dynamic_cast<const UnicodeString*>(c);
if(str != NULL) {
// recursed! Second lookup returned a UnicodeString.
// Perhaps DefaultCalendar{} was set to another locale.
#ifdef U_DEBUG_CALSVC
char tmp[200];
const UnicodeString& str = *(UnicodeString*)c;
// Extract a char* out of it..
int32_t len = str.length();
int32_t len = str->length();
int32_t actLen = sizeof(tmp)-1;
if(len > actLen) {
len = actLen;
}
str.extract(0,len,tmp);
str->extract(0,len,tmp);
tmp[len]=0;
fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp);
@ -907,7 +909,7 @@ Calendar::operator==(const Calendar& that) const
UBool
Calendar::isEquivalentTo(const Calendar& other) const
{
return getDynamicClassID() == other.getDynamicClassID() &&
return typeid(*this) == typeid(other) &&
fLenient == other.fLenient &&
fFirstDayOfWeek == other.fFirstDayOfWeek &&
fMinimalDaysInFirstWeek == other.fMinimalDaysInFirstWeek &&

View File

@ -1,7 +1,7 @@
/*
******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1996-2010, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*/
@ -235,8 +235,8 @@ Collator::createUCollator(const char *loc,
if (status && U_SUCCESS(*status) && hasService()) {
Locale desiredLocale(loc);
Collator *col = (Collator*)gService->get(desiredLocale, *status);
if (col && col->getDynamicClassID() == RuleBasedCollator::getStaticClassID()) {
RuleBasedCollator *rbc = (RuleBasedCollator *)col;
RuleBasedCollator *rbc;
if (col && (rbc = dynamic_cast<RuleBasedCollator *>(col))) {
if (!rbc->dataIsOwned) {
result = ucol_safeClone(rbc->ucollator, NULL, NULL, status);
} else {

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2004-2008, International Business Machines
* Copyright (c) 2004-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -8,6 +8,8 @@
* Since: ICU 3.0
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -37,7 +39,7 @@ UBool CurrencyFormat::operator==(const Format& other) const {
if (this == &other) {
return TRUE;
}
if (other.getDynamicClassID() != CurrencyFormat::getStaticClassID()) {
if (typeid(*this) != typeid(other)) {
return FALSE;
}
const CurrencyFormat* c = (const CurrencyFormat*) &other;

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2004, International Business Machines
* Copyright (c) 2004-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -8,6 +8,8 @@
* Since: ICU 3.0
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -49,7 +51,7 @@ CurrencyUnit::~CurrencyUnit() {
UBool CurrencyUnit::operator==(const UObject& other) const {
const CurrencyUnit& c = (const CurrencyUnit&) other;
return other.getDynamicClassID() == CurrencyUnit::getStaticClassID() &&
return typeid(*this) == typeid(other) &&
u_strcmp(isoCode, c.isoCode) == 0;
}

View File

@ -8,6 +8,8 @@
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/dtitvfmt.h"
#if !UCONFIG_NO_FORMATTING
@ -188,8 +190,8 @@ DateIntervalFormat::clone(void) const {
UBool
DateIntervalFormat::operator==(const Format& other) const {
if ( other.getDynamicClassID() == DateIntervalFormat::getStaticClassID() ) {
DateIntervalFormat* fmt = (DateIntervalFormat*)&other;
if (typeid(*this) == typeid(other)) {
const DateIntervalFormat* fmt = (DateIntervalFormat*)&other;
#ifdef DTITVFMT_DEBUG
UBool equal;
equal = (this == fmt);
@ -241,8 +243,9 @@ DateIntervalFormat::format(const Formattable& obj,
if ( obj.getType() == Formattable::kObject ) {
const UObject* formatObj = obj.getObject();
if (formatObj->getDynamicClassID() == DateInterval::getStaticClassID()){
return format((DateInterval*)formatObj, appendTo, fieldPosition, status);
const DateInterval* interval = dynamic_cast<const DateInterval*>(formatObj);
if (interval != NULL){
return format(interval, appendTo, fieldPosition, status);
}
}
status = U_ILLEGAL_ARGUMENT_ERROR;

View File

@ -413,8 +413,8 @@ DateTimePatternGenerator::addICUPatterns(const Locale& locale, UErrorCode& statu
for (int32_t i=DateFormat::kFull; i<=DateFormat::kShort; i++) {
DateFormat::EStyle style = (DateFormat::EStyle)i;
df = DateFormat::createDateInstance(style, locale);
if (df != NULL && df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
SimpleDateFormat* sdf = (SimpleDateFormat*)df;
SimpleDateFormat* sdf;
if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) {
conflictingStatus = addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status);
}
// TODO Maybe we should return an error when the date format isn't simple.
@ -424,8 +424,7 @@ DateTimePatternGenerator::addICUPatterns(const Locale& locale, UErrorCode& statu
}
df = DateFormat::createTimeInstance(style, locale);
if (df != NULL && df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
SimpleDateFormat* sdf = (SimpleDateFormat*)df;
if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) {
conflictingStatus = addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status);
// HACK for hh:ss
if ( i==DateFormat::kMedium ) {

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -80,7 +82,7 @@ DateTimeRule::operator=(const DateTimeRule& right) {
UBool
DateTimeRule::operator==(const DateTimeRule& that) const {
return ((this == &that) ||
(getDynamicClassID() == that.getDynamicClassID() &&
(typeid(*this) == typeid(that) &&
fMonth == that.fMonth &&
fDayOfMonth == that.fDayOfMonth &&
fDayOfWeek == that.fDayOfWeek &&

View File

@ -38,8 +38,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
// NOTE: As of 3.0, there are limitations to the UObject API. It does
// not (yet) support cloning, operator=, nor operator==. RTTI is also
// restricted in that subtype testing is not (yet) implemented. To
// not (yet) support cloning, operator=, nor operator==. To
// work around this, I implement some simple inlines here. Later
// these can be modified or removed. [alan]
@ -60,9 +59,7 @@ static inline UObject* objectClone(const UObject* a) {
// Return TRUE if *a is an instance of Measure.
static inline UBool instanceOfMeasure(const UObject* a) {
// LATER: return a->instanceof(Measure::getStaticClassID());
return a->getDynamicClassID() ==
CurrencyAmount::getStaticClassID();
return dynamic_cast<const Measure*>(a) != NULL;
}
/**

View File

@ -19,6 +19,8 @@
// This file was generated from the java source file Format.java
// *****************************************************************************
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
/*
@ -151,7 +153,7 @@ UBool
Format::operator==(const Format& that) const
{
// Subclasses: Call this method and then add more specific checks.
return getDynamicClassID() == that.getDynamicClassID();
return typeid(*this) == typeid(that);
}
//---------------------------------------

View File

@ -18,7 +18,7 @@
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(FieldPositionIterator)
UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(FieldPositionIterator)
FieldPositionIterator::~FieldPositionIterator() {
delete data;

View File

@ -145,7 +145,7 @@ ICUDataTable::getNoFallback(const char* tableKey, const char* subTableKey, const
////////////////////////////////////////////////////////////////////////////////////////////////////
UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(LocaleDisplayNames)
UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(LocaleDisplayNames)
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -298,16 +298,12 @@ public:
virtual UnicodeString& keyValueDisplayName(const char* key,
const char* value,
UnicodeString& result) const;
static UClassID U_EXPORT2 getStaticClassID();
virtual UClassID getDynamicClassID() const;
private:
UnicodeString& localeIdName(const char* localeId,
UnicodeString& result) const;
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
};
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleDisplayNamesImpl)
LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
UDialectHandling dialectHandling)
: dialectHandling(dialectHandling)

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2004-2008, International Business Machines
* Copyright (c) 2004-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -8,6 +8,8 @@
* Since: ICU 3.0
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -48,7 +50,7 @@ Measure::~Measure() {
UBool Measure::operator==(const UObject& other) const {
const Measure* m = (const Measure*) &other;
return getDynamicClassID() == other.getDynamicClassID() &&
return typeid(*this) == typeid(other) &&
number == m->getNumber() &&
(unit != NULL && *unit == m->getUnit());
}

View File

@ -725,13 +725,17 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
appendTo += *subformats[i].argName;
}
Format* fmt = subformats[i].format;
DecimalFormat* decfmt;
SimpleDateFormat* sdtfmt;
ChoiceFormat* chcfmt;
PluralFormat* plfmt;
SelectFormat* selfmt;
if (fmt == NULL) {
// do nothing, string format
}
else if (fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
else if ((decfmt = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
UErrorCode ec = U_ZERO_ERROR;
NumberFormat& formatAlias = *(NumberFormat*)fmt;
NumberFormat& formatAlias = *decfmt;
NumberFormat *defaultTemplate = NumberFormat::createInstance(fLocale, ec);
NumberFormat *currencyTemplate = NumberFormat::createCurrencyInstance(fLocale, ec);
NumberFormat *percentTemplate = NumberFormat::createPercentInstance(fLocale, ec);
@ -752,7 +756,7 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
}
else {
UnicodeString buffer;
appendTo += ((DecimalFormat*)fmt)->toPattern(buffer);
appendTo += decfmt->toPattern(buffer);
}
}
@ -761,8 +765,8 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
delete percentTemplate;
delete integerTemplate;
}
else if (fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
DateFormat& formatAlias = *(DateFormat*)fmt;
else if ((sdtfmt = dynamic_cast<SimpleDateFormat*>(fmt)) != NULL) {
DateFormat& formatAlias = *sdtfmt;
DateFormat *defaultDateTemplate = DateFormat::createDateInstance(DateFormat::kDefault, fLocale);
DateFormat *shortDateTemplate = DateFormat::createDateInstance(DateFormat::kShort, fLocale);
DateFormat *longDateTemplate = DateFormat::createDateInstance(DateFormat::kLong, fLocale);
@ -824,7 +828,7 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
UnicodeString buffer;
appendTo += ID_DATE;
appendTo += COMMA;
appendTo += ((SimpleDateFormat*)fmt)->toPattern(buffer);
appendTo += sdtfmt->toPattern(buffer);
}
delete defaultDateTemplate;
@ -837,18 +841,18 @@ MessageFormat::toPattern(UnicodeString& appendTo) const {
delete fullTimeTemplate;
// {sfb} there should be a more efficient way to do this!
}
else if (fmt->getDynamicClassID() == ChoiceFormat::getStaticClassID()) {
else if ((chcfmt = dynamic_cast<ChoiceFormat*>(fmt)) != NULL) {
UnicodeString buffer;
appendTo += COMMA;
appendTo += ID_CHOICE;
appendTo += COMMA;
appendTo += ((ChoiceFormat*)fmt)->toPattern(buffer);
}
else if (fmt->getDynamicClassID() == PluralFormat::getStaticClassID()) {
else if ((plfmt = dynamic_cast<PluralFormat*>(fmt)) != NULL) {
UnicodeString buffer;
appendTo += ((PluralFormat*)fmt)->toPattern(buffer);
appendTo += plfmt->toPattern(buffer);
}
else if (fmt->getDynamicClassID() == SelectFormat::getStaticClassID()) {
else if ((selfmt = dynamic_cast<SelectFormat*>(fmt)) != NULL) {
UnicodeString buffer;
appendTo += ((SelectFormat*)fmt)->toPattern(buffer);
}
@ -1238,7 +1242,7 @@ MessageFormat::format(const Formattable* arguments,
// Recursively calling the format process only if the current
// format argument refers to either of the following:
// a ChoiceFormat object ,a PluralFormat object, a SelectFormat object.
// a ChoiceFormat object, a PluralFormat object, a SelectFormat object.
Format* fmt = subformats[i].format;
if (fmt != NULL) {
UnicodeString argNum;
@ -1246,11 +1250,11 @@ MessageFormat::format(const Formattable* arguments,
// Needs to reprocess the ChoiceFormat and PluralFormat and SelectFormat option by using the
// MessageFormat pattern application.
if ((fmt->getDynamicClassID() == ChoiceFormat::getStaticClassID() ||
fmt->getDynamicClassID() == PluralFormat::getStaticClassID() ||
fmt->getDynamicClassID() == SelectFormat::getStaticClassID()
) &&
argNum.indexOf(LEFT_CURLY_BRACE) >= 0) {
if ((dynamic_cast<ChoiceFormat*>(fmt) != NULL ||
dynamic_cast<PluralFormat*>(fmt) != NULL ||
dynamic_cast<SelectFormat*>(fmt) != NULL) &&
argNum.indexOf(LEFT_CURLY_BRACE) >= 0
) {
MessageFormat temp(argNum, fLocale, success);
// TODO: Implement recursion protection
if ( isArgNumeric ) {
@ -1563,9 +1567,11 @@ MessageFormat::makeFormat(int32_t formatNumber,
break;
default: // pattern
fmt = NumberFormat::createInstance(fLocale, ec);
if (fmt &&
fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
((DecimalFormat*)fmt)->applyPattern(segments[3],parseError,ec);
if (fmt) {
DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fmt);
if (decfmt != NULL) {
decfmt->applyPattern(segments[3],parseError,ec);
}
}
break;
}
@ -1583,10 +1589,11 @@ MessageFormat::makeFormat(int32_t formatNumber,
fmt = DateFormat::createTimeInstance(style, fLocale);
}
if (styleID < 0 &&
fmt != NULL &&
fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
((SimpleDateFormat*)fmt)->applyPattern(segments[3]);
if (styleID < 0 && fmt != NULL) {
SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(fmt);
if (sdtfmt != NULL) {
sdtfmt->applyPattern(segments[3]);
}
}
break;
@ -1744,8 +1751,8 @@ MessageFormat::copyAndFixQuotes(const UnicodeString& source,
NumberFormat*
MessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) const {
NumberFormat *temp = NumberFormat::createInstance(locale, status);
if (temp != NULL && temp->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
DecimalFormat *temp2 = (DecimalFormat*) temp;
DecimalFormat *temp2;
if (temp != NULL && (temp2 = dynamic_cast<DecimalFormat*>(temp)) != NULL) {
temp2->setMaximumFractionDigits(0);
temp2->setDecimalSeparatorAlwaysShown(FALSE);
temp2->setParseIntegerOnly(TRUE);

View File

@ -13,11 +13,12 @@
* 10/11/2001 Doug Ported from ICU4J
*/
#include <stdio.h>
#include <typeinfo> // for 'typeid' to work
#include "nfsubs.h"
#include "digitlst.h"
#include <stdio.h>
#if U_HAVE_RBNF
static const UChar gLessThan = 0x003c;
@ -525,7 +526,7 @@ NFSubstitution::operator==(const NFSubstitution& rhs) const
// compare class and all of the fields all substitutions have
// in common
// this should be called by subclasses before their own equality tests
return getDynamicClassID() == rhs.getDynamicClassID()
return typeid(*this) == typeid(rhs)
&& pos == rhs.pos
&& (ruleSet == NULL) == (rhs.ruleSet == NULL)
// && ruleSet == rhs.ruleSet causes circularity, other checks to make instead?

View File

@ -379,11 +379,10 @@ ArgExtractor::ArgExtractor(const NumberFormat& nf, const Formattable& obj, UErro
: ncnf((NumberFormat*) &nf), num(&obj), setCurr(FALSE) {
const UObject* o = obj.getObject(); // most commonly o==NULL
if (o != NULL &&
o->getDynamicClassID() == CurrencyAmount::getStaticClassID()) {
const CurrencyAmount* amt;
if (o != NULL && (amt = dynamic_cast<const CurrencyAmount*>(o)) != NULL) {
// getISOCurrency() returns a pointer to internal storage, so we
// copy it to retain it across the call to setCurrency().
const CurrencyAmount* amt = (const CurrencyAmount*) o;
const UChar* curr = amt->getISOCurrency();
u_strcpy(save, nf.getCurrency());
setCurr = (u_strcmp(curr, save) != 0);

View File

@ -9,6 +9,8 @@
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "olsontz.h"
#if !UCONFIG_NO_FORMATTING
@ -299,7 +301,7 @@ OlsonTimeZone::~OlsonTimeZone() {
*/
UBool OlsonTimeZone::operator==(const TimeZone& other) const {
return ((this == &other) ||
(getDynamicClassID() == other.getDynamicClassID() &&
(typeid(*this) == typeid(other) &&
TimeZone::operator==(other) &&
hasSameRules(other)));
}
@ -592,10 +594,10 @@ OlsonTimeZone::hasSameRules(const TimeZone &other) const {
if (this == &other) {
return TRUE;
}
if (other.getDynamicClassID() != OlsonTimeZone::getStaticClassID()) {
const OlsonTimeZone* z = dynamic_cast<const OlsonTimeZone*>(&other);
if (z == NULL) {
return FALSE;
}
const OlsonTimeZone* z = (const OlsonTimeZone*) &other;
// [sic] pointer comparison: typeMapData points into
// memory-mapped or DLL space, so if two zones have the same

View File

@ -110,7 +110,7 @@ class SimpleTimeZone;
* (UN M.49 - World). This data is generated from "zone.tab"
* in the tz database.
*/
class OlsonTimeZone: public BasicTimeZone {
class U_I18N_API OlsonTimeZone: public BasicTimeZone {
public:
/**
* Construct from a resource bundle.

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 1997-2009, International Business Machines Corporation
* Copyright (C) 1997-2010, International Business Machines Corporation
* and others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/rbnf.h"
#if U_HAVE_RBNF
@ -872,7 +874,7 @@ RuleBasedNumberFormat::operator==(const Format& other) const
return TRUE;
}
if (other.getDynamicClassID() == getStaticClassID()) {
if (typeid(*this) == typeid(other)) {
const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other;
if (locale == rhs.locale &&
lenient == rhs.lenient &&
@ -1550,10 +1552,8 @@ RuleBasedNumberFormat::getCollator() const
UErrorCode status = U_ZERO_ERROR;
Collator* temp = Collator::createInstance(locale, status);
if (U_SUCCESS(status) &&
temp->getDynamicClassID() == RuleBasedCollator::getStaticClassID()) {
RuleBasedCollator* newCollator = (RuleBasedCollator*)temp;
RuleBasedCollator* newCollator;
if (U_SUCCESS(status) && (newCollator = dynamic_cast<RuleBasedCollator*>(temp)) != NULL) {
if (lenientParseRules) {
UnicodeString rules(newCollator->getRules());
rules.append(*lenientParseRules);

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2007-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -88,7 +90,7 @@ RuleBasedTimeZone::operator==(const TimeZone& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()
if (typeid(*this) != typeid(that)
|| BasicTimeZone::operator==(that) == FALSE) {
return FALSE;
}
@ -113,8 +115,8 @@ RuleBasedTimeZone::addTransitionRule(TimeZoneRule* rule, UErrorCode& status) {
if (U_FAILURE(status)) {
return;
}
if (rule->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()
&& ((AnnualTimeZoneRule*)rule)->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
AnnualTimeZoneRule* atzrule = dynamic_cast<AnnualTimeZoneRule*>(rule);
if (atzrule != NULL && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
// A final rule
if (fFinalRules == NULL) {
fFinalRules = new UVector(status);
@ -506,7 +508,7 @@ RuleBasedTimeZone::hasSameRules(const TimeZone& other) const {
if (this == &other) {
return TRUE;
}
if (getDynamicClassID() != other.getDynamicClassID()) {
if (typeid(*this) != typeid(other)) {
return FALSE;
}
const RuleBasedTimeZone& that = (const RuleBasedTimeZone&)other;

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2007-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -288,8 +288,9 @@ RelativeDateFormat::toPatternDate(UnicodeString& result, UErrorCode& status) con
if (!U_FAILURE(status)) {
result.remove();
if ( fDateFormat ) {
if ( fDateFormat->getDynamicClassID()==SimpleDateFormat::getStaticClassID() ) {
((SimpleDateFormat*)fDateFormat)->toPattern(result);
SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(fDateFormat);
if (sdtfmt != NULL) {
sdtfmt->toPattern(result);
} else {
status = U_UNSUPPORTED_ERROR;
}
@ -304,8 +305,9 @@ RelativeDateFormat::toPatternTime(UnicodeString& result, UErrorCode& status) con
if (!U_FAILURE(status)) {
result.remove();
if ( fTimeFormat ) {
if ( fTimeFormat->getDynamicClassID()==SimpleDateFormat::getStaticClassID() ) {
((SimpleDateFormat*)fTimeFormat)->toPattern(result);
SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(fTimeFormat);
if (sdtfmt != NULL) {
sdtfmt->toPattern(result);
} else {
status = U_UNSUPPORTED_ERROR;
}
@ -318,19 +320,21 @@ void
RelativeDateFormat::applyPatterns(const UnicodeString& datePattern, const UnicodeString& timePattern, UErrorCode &status)
{
if (!U_FAILURE(status)) {
if ( fDateFormat && fDateFormat->getDynamicClassID()!=SimpleDateFormat::getStaticClassID() ) {
SimpleDateFormat* sdtfmt = NULL;
SimpleDateFormat* stmfmt = NULL;
if (fDateFormat && (sdtfmt = dynamic_cast<SimpleDateFormat*>(fDateFormat)) == NULL) {
status = U_UNSUPPORTED_ERROR;
return;
}
if ( fTimeFormat && fTimeFormat->getDynamicClassID()!=SimpleDateFormat::getStaticClassID() ) {
if (fTimeFormat && (stmfmt = dynamic_cast<SimpleDateFormat*>(fTimeFormat)) == NULL) {
status = U_UNSUPPORTED_ERROR;
return;
}
if ( fDateFormat ) {
((SimpleDateFormat*)fDateFormat)->applyPattern(datePattern);
sdtfmt->applyPattern(datePattern);
}
if ( fTimeFormat ) {
((SimpleDateFormat*)fTimeFormat)->applyPattern(timePattern);
stmfmt->applyPattern(timePattern);
}
}
}

View File

@ -14,6 +14,8 @@
* 11/16/09 kirtig Improved version
********************************************************************/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#include "unicode/ustring.h"
#include "unicode/ucnv_err.h"
@ -347,7 +349,7 @@ SelectFormat::operator==(const Format& other) const {
if( this == &other){
return TRUE;
}
if( other.getDynamicClassID() != SelectFormat::getStaticClassID() ){
if (typeid(*this) != typeid(other)) {
return FALSE;
}
SelectFormat* fmt = (SelectFormat*)&other;

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 1997-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
* File SIMPLETZ.H
@ -21,6 +21,8 @@
********************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -229,7 +231,7 @@ UBool
SimpleTimeZone::operator==(const TimeZone& that) const
{
return ((this == &that) ||
(getDynamicClassID() == that.getDynamicClassID() &&
(typeid(*this) == typeid(that) &&
TimeZone::operator==(that) &&
hasSameRules(that)));
}
@ -741,7 +743,7 @@ UBool
SimpleTimeZone::hasSameRules(const TimeZone& other) const
{
if (this == &other) return TRUE;
if (other.getDynamicClassID() != SimpleTimeZone::getStaticClassID()) return FALSE;
if (typeid(*this) != typeid(other)) return FALSE;
SimpleTimeZone *that = (SimpleTimeZone*)&other;
return rawOffset == that->rawOffset &&
useDaylight == that->useDaylight &&

View File

@ -685,8 +685,10 @@ SimpleDateFormat::initialize(const Locale& locale,
// show the decimal point, and recognizes integers only when parsing
fNumberFormat->setGroupingUsed(FALSE);
if (fNumberFormat->getDynamicClassID() == DecimalFormat::getStaticClassID())
((DecimalFormat*)fNumberFormat)->setDecimalSeparatorAlwaysShown(FALSE);
DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
if (decfmt != NULL) {
decfmt->setDecimalSeparatorAlwaysShown(FALSE);
}
fNumberFormat->setParseIntegerOnly(TRUE);
fNumberFormat->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
@ -1363,8 +1365,10 @@ SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeStrin
if (U_SUCCESS(status)) {
nf->setGroupingUsed(FALSE);
if (nf->getDynamicClassID() == DecimalFormat::getStaticClassID())
((DecimalFormat*)nf)->setDecimalSeparatorAlwaysShown(FALSE);
DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(nf);
if (decfmt != NULL) {
decfmt->setDecimalSeparatorAlwaysShown(FALSE);
}
nf->setParseIntegerOnly(TRUE);
nf->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
@ -2044,10 +2048,10 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
const TimeZone & tz = cal.getTimeZone();
BasicTimeZone *btz = NULL;
if (tz.getDynamicClassID() == OlsonTimeZone::getStaticClassID()
|| tz.getDynamicClassID() == SimpleTimeZone::getStaticClassID()
|| tz.getDynamicClassID() == RuleBasedTimeZone::getStaticClassID()
|| tz.getDynamicClassID() == VTimeZone::getStaticClassID()) {
if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL
|| dynamic_cast<const SimpleTimeZone *>(&tz) != NULL
|| dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL
|| dynamic_cast<const VTimeZone *>(&tz) != NULL) {
btz = (BasicTimeZone*)&tz;
}
@ -2930,9 +2934,7 @@ void SimpleDateFormat::parseInt(const UnicodeString& text,
NumberFormat *fmt) const {
UnicodeString oldPrefix;
DecimalFormat* df = NULL;
if (!allowNegative &&
fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
df = (DecimalFormat*)fmt;
if (!allowNegative && (df = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
df->getNegativePrefix(oldPrefix);
df->setNegativePrefix(SUPPRESS_NEGATIVE_PREFIX);
}
@ -3161,12 +3163,13 @@ SimpleDateFormat::checkIntSuffix(const UnicodeString& text, int32_t start,
}
// get the suffix
if (fNumberFormat->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
if (decfmt != NULL) {
if (isNegative) {
suf = ((DecimalFormat*)fNumberFormat)->getNegativeSuffix(suf);
suf = decfmt->getNegativeSuffix(suf);
}
else {
suf = ((DecimalFormat*)fNumberFormat)->getPositiveSuffix(suf);
suf = decfmt->getPositiveSuffix(suf);
}
}

View File

@ -1,7 +1,7 @@
/*
******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1996-2010, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*/
@ -54,6 +54,8 @@
* 01/29/01 synwee Modified into a C++ wrapper calling C APIs (ucol.h)
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_COLLATION
@ -193,7 +195,7 @@ UBool RuleBasedCollator::operator==(const Collator& that) const
if (Collator::operator==(that))
return TRUE;
if (getDynamicClassID() != that.getDynamicClassID())
if (typeid(*this) != typeid(that))
return FALSE; /* not the same class */
RuleBasedCollator& thatAlias = (RuleBasedCollator&)that;

View File

@ -35,6 +35,8 @@
* available IDs code. Misc. cleanup.
*********************************************************************************/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#include "unicode/ustring.h"
@ -382,7 +384,7 @@ TimeZone::operator=(const TimeZone &right)
UBool
TimeZone::operator==(const TimeZone& that) const
{
return getDynamicClassID() == that.getDynamicClassID() &&
return typeid(*this) == typeid(that) &&
fID == that.fID;
}

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2008, Google, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2008-2010, Google, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/tmunit.h"
#if !UCONFIG_NO_FORMATTING
@ -95,7 +97,7 @@ TimeUnit::operator=(const TimeUnit& other) {
UBool
TimeUnit::operator==(const UObject& other) const {
return (other.getDynamicClassID() == TimeUnit::getStaticClassID()
return (typeid(*this) == typeid(other)
&& fTimeUnitField == ((TimeUnit*)&other)->fTimeUnitField);
}

View File

@ -5,6 +5,7 @@
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/tmutfmt.h"
@ -172,7 +173,7 @@ TimeUnitFormat::operator=(const TimeUnitFormat& other) {
UBool
TimeUnitFormat::operator==(const Format& other) const {
if (other.getDynamicClassID() == TimeUnitFormat::getStaticClassID()) {
if (typeid(*this) == typeid(other)) {
TimeUnitFormat* fmt = (TimeUnitFormat*)&other;
UBool ret = ( (fNumberFormat && fmt->fNumberFormat &&
*fNumberFormat == *fmt->fNumberFormat ||
@ -203,8 +204,8 @@ TimeUnitFormat::format(const Formattable& obj, UnicodeString& toAppendTo,
}
if (obj.getType() == Formattable::kObject) {
const UObject* formatObj = obj.getObject();
if (formatObj->getDynamicClassID() == TimeUnitAmount::getStaticClassID()){
TimeUnitAmount* amount = (TimeUnitAmount*)formatObj;
const TimeUnitAmount* amount = dynamic_cast<const TimeUnitAmount*>(formatObj);
if (amount != NULL){
Hashtable* countToPattern = fTimeUnitToCountToPatterns[amount->getTimeUnitField()];
double number;
const Formattable& amtNumber = amount->getNumber();

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1999-2009, International Business Machines
* Copyright (C) 1999-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Date Name Description
@ -8,6 +8,8 @@
**********************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_TRANSLITERATION
@ -1100,7 +1102,7 @@ Transliterator::createFromRules(const UnicodeString& ID,
UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i);
if (!idBlock->isEmpty()) {
Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status);
if (temp != NULL && temp->getDynamicClassID() != NullTransliterator::getStaticClassID())
if (temp != NULL && typeid(*temp) != typeid(NullTransliterator))
transliterators.addElement(temp, status);
else
delete temp;
@ -1156,18 +1158,15 @@ UnicodeString& Transliterator::toRules(UnicodeString& rulesSource,
}
int32_t Transliterator::countElements() const {
return (this->getDynamicClassID() ==
CompoundTransliterator::getStaticClassID()) ?
((const CompoundTransliterator*) this)->getCount() : 0;
const CompoundTransliterator* ct = dynamic_cast<const CompoundTransliterator*>(this);
return ct != NULL ? ct->getCount() : 0;
}
const Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec) const {
if (U_FAILURE(ec)) {
return *this;
}
const CompoundTransliterator* cpd =
(this->getDynamicClassID() == CompoundTransliterator::getStaticClassID()) ?
(const CompoundTransliterator*) this : 0;
const CompoundTransliterator* cpd = dynamic_cast<const CompoundTransliterator*>(this);
int32_t n = (cpd == NULL) ? 1 : cpd->getCount();
if (index < 0 || index >= n) {
ec = U_INDEX_OUTOFBOUNDS_ERROR;
@ -1180,13 +1179,11 @@ const Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec)
UnicodeSet& Transliterator::getSourceSet(UnicodeSet& result) const {
handleGetSourceSet(result);
if (filter != NULL) {
UnicodeSet* filterSet;
UnicodeSet* filterSet = dynamic_cast<UnicodeSet*>(filter);
UBool deleteFilterSet = FALSE;
// Most, but not all filters will be UnicodeSets. Optimize for
// the high-runner case.
if (filter->getDynamicClassID() == UnicodeSet::getStaticClassID()) {
filterSet = (UnicodeSet*) filter;
} else {
if (filterSet == NULL) {
filterSet = new UnicodeSet();
// Check null pointer
if (filterSet == NULL) {

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2007-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -52,7 +54,7 @@ TimeZoneRule::operator=(const TimeZoneRule& right) {
UBool
TimeZoneRule::operator==(const TimeZoneRule& that) const {
return ((this == &that) ||
(getDynamicClassID() == that.getDynamicClassID() &&
(typeid(*this) == typeid(that) &&
fName == that.fName &&
fRawOffset == that.fRawOffset &&
fDSTSavings == that.fDSTSavings));
@ -82,7 +84,7 @@ TimeZoneRule::getDSTSavings(void) const {
UBool
TimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
return ((this == &other) ||
(getDynamicClassID() == other.getDynamicClassID() &&
(typeid(*this) == typeid(other) &&
fRawOffset == other.fRawOffset &&
fDSTSavings == other.fDSTSavings));
}
@ -119,7 +121,7 @@ InitialTimeZoneRule::operator=(const InitialTimeZoneRule& right) {
UBool
InitialTimeZoneRule::operator==(const TimeZoneRule& that) const {
return ((this == &that) ||
(getDynamicClassID() == that.getDynamicClassID() &&
(typeid(*this) == typeid(that) &&
TimeZoneRule::operator==(that)));
}
@ -133,8 +135,7 @@ InitialTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
if (this == &other) {
return TRUE;
}
if (getDynamicClassID() != other.getDynamicClassID() ||
TimeZoneRule::isEquivalentTo(other) == FALSE) {
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
return FALSE;
}
return TRUE;
@ -228,7 +229,7 @@ AnnualTimeZoneRule::operator==(const TimeZoneRule& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()) {
if (typeid(*this) != typeid(that)) {
return FALSE;
}
AnnualTimeZoneRule *atzr = (AnnualTimeZoneRule*)&that;
@ -320,8 +321,7 @@ AnnualTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
if (this == &other) {
return TRUE;
}
if (getDynamicClassID() != other.getDynamicClassID() ||
TimeZoneRule::isEquivalentTo(other) == FALSE) {
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
return FALSE;
}
AnnualTimeZoneRule* that = (AnnualTimeZoneRule*)&other;
@ -448,8 +448,7 @@ TimeArrayTimeZoneRule::operator==(const TimeZoneRule& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()
|| TimeZoneRule::operator==(that) == FALSE) {
if (typeid(*this) != typeid(that) || TimeZoneRule::operator==(that) == FALSE) {
return FALSE;
}
TimeArrayTimeZoneRule *tatzr = (TimeArrayTimeZoneRule*)&that;
@ -497,8 +496,7 @@ TimeArrayTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
if (this == &other) {
return TRUE;
}
if (getDynamicClassID() != other.getDynamicClassID()
|| TimeZoneRule::isEquivalentTo(other) == FALSE) {
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
return FALSE;
}
TimeArrayTimeZoneRule* that = (TimeArrayTimeZoneRule*)&other;

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -64,7 +66,7 @@ TimeZoneTransition::operator==(const TimeZoneTransition& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()) {
if (typeid(*this) != typeid(that)) {
return FALSE;
}
if (fTime != that.fTime) {

View File

@ -5,6 +5,8 @@
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -83,8 +85,9 @@ ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
int32_t result = 0;
TimeZone* zone = _createTimeZone(zoneID, -1, ec);
if (U_SUCCESS(*ec)) {
if (zone->getDynamicClassID() == SimpleTimeZone::getStaticClassID()) {
result = ((SimpleTimeZone*) zone)->getDSTSavings();
SimpleTimeZone* stz = dynamic_cast<SimpleTimeZone*>(zone);
if (stz != NULL) {
result = stz->getDSTSavings();
} else {
// Since there is no getDSTSavings on TimeZone, we use a
// heuristic: Starting with the current time, march
@ -244,11 +247,15 @@ ucal_setGregorianChange(UCalendar *cal, UDate date, UErrorCode *pErrorCode) {
return;
}
Calendar *cpp_cal = (Calendar *)cal;
if(cpp_cal->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
GregorianCalendar *gregocal = dynamic_cast<GregorianCalendar *>(cpp_cal);
// Not if(gregocal == NULL) {
// because we really want to work only with a GregorianCalendar, not with
// its subclasses like BuddhistCalendar.
if(typeid(*cpp_cal) != typeid(GregorianCalendar)) {
*pErrorCode = U_UNSUPPORTED_ERROR;
return;
}
((GregorianCalendar *)cpp_cal)->setGregorianChange(date, *pErrorCode);
gregocal->setGregorianChange(date, *pErrorCode);
}
U_CAPI UDate U_EXPORT2
@ -256,12 +263,15 @@ ucal_getGregorianChange(const UCalendar *cal, UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return (UDate)0;
}
Calendar *cpp_cal = (Calendar *)cal;
if(cpp_cal->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
const Calendar *cpp_cal = (const Calendar *)cal;
const GregorianCalendar *gregocal = dynamic_cast<const GregorianCalendar *>(cpp_cal);
// Not if(gregocal == NULL) {
// see comments in ucal_setGregorianChange().
if(typeid(*cpp_cal) != typeid(GregorianCalendar)) {
*pErrorCode = U_UNSUPPORTED_ERROR;
return (UDate)0;
}
return ((GregorianCalendar *)cpp_cal)->getGregorianChange();
return gregocal->getGregorianChange();
}
U_CAPI int32_t U_EXPORT2

View File

@ -32,8 +32,8 @@ U_NAMESPACE_USE
* @param status error code, will be set to failure if there is a familure or the fmt is NULL.
*/
static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
if(!U_FAILURE(*status) &&
((DateFormat*)fmt)->getDynamicClassID()!=SimpleDateFormat::getStaticClassID()) {
if(U_SUCCESS(*status) &&
dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
}
}
@ -337,13 +337,16 @@ udat_toPattern( const UDateFormat *fmt,
res.setTo(result, 0, resultLength);
}
if ( ((DateFormat*)fmt)->getDynamicClassID()==SimpleDateFormat::getStaticClassID() ) {
const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt);
const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df);
const RelativeDateFormat *reldtfmt;
if (sdtfmt!=NULL) {
if(localized)
((SimpleDateFormat*)fmt)->toLocalizedPattern(res, *status);
sdtfmt->toLocalizedPattern(res, *status);
else
((SimpleDateFormat*)fmt)->toPattern(res);
} else if ( !localized && ((DateFormat*)fmt)->getDynamicClassID()==RelativeDateFormat::getStaticClassID() ) {
((RelativeDateFormat*)fmt)->toPattern(res, *status);
sdtfmt->toPattern(res);
} else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) {
reldtfmt->toPattern(res, *status);
} else {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return -1;
@ -896,8 +899,8 @@ udat_getLocaleByType(const UDateFormat *fmt,
* @param status error code, will be set to failure if there is a familure or the fmt is NULL.
*/
static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
if(!U_FAILURE(*status) &&
((DateFormat*)fmt)->getDynamicClassID()!=RelativeDateFormat::getStaticClassID()) {
if(U_SUCCESS(*status) &&
dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
}
}

View File

@ -240,20 +240,6 @@ public:
Formattable& result,
UErrorCode& status) const;
/**
* Returns a unique class ID POLYMORPHICALLY. Pure virtual method.
* This method is to implement a simple version of RTTI, since not all
* C++ compilers support genuine RTTI. Polymorphic operator==() and
* clone() methods call this method.
* Concrete subclasses of Format must implement getDynamicClassID()
*
* @return The class ID for this object. All objects of a
* given class have the same class ID. Objects of
* other classes have different class IDs.
* @stable ICU 2.0
*/
virtual UClassID getDynamicClassID() const = 0;
/** Get the locale for this format object. You can choose between valid and actual locale.
* @param type type of the locale we're looking for (valid or actual)
* @param status error code for the operation

View File

@ -96,18 +96,6 @@ public:
*/
UBool next(FieldPosition& fp);
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
* @draft ICU 4.4
*/
static UClassID U_EXPORT2 getStaticClassID();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
* @draft ICU 4.4
*/
virtual UClassID getDynamicClassID() const;
private:
friend class FieldPositionIteratorHandler;
@ -120,6 +108,9 @@ private:
UVector32 *data;
int32_t pos;
// No ICU "poor man's RTTI" for this class nor its subclasses.
virtual UClassID getDynamicClassID() const;
};
U_NAMESPACE_END

View File

@ -169,12 +169,9 @@ public:
virtual UnicodeString& keyValueDisplayName(const char* key, const char* value,
UnicodeString& result) const = 0;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
* @returns a UClassID for this class.
* @internal ICU 4.4 // TODO @draft ICU 4.6
*/
static UClassID U_EXPORT2 getStaticClassID();
private:
// No ICU "poor man's RTTI" for this class nor its subclasses.
virtual UClassID getDynamicClassID() const;
};
inline LocaleDisplayNames::~LocaleDisplayNames() {

View File

@ -165,11 +165,14 @@ unum_clone(const UNumberFormat *fmt,
return 0;
Format *res = 0;
if (((const NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
res = ((const DecimalFormat*)fmt)->clone();
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL) {
res = df->clone();
} else {
U_ASSERT(((const NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
res = ((const RuleBasedNumberFormat*)fmt)->clone();
const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
res = rbnf->clone();
}
if(res == 0) {
@ -376,9 +379,9 @@ unum_parseDoubleCurrency(const UNumberFormat* fmt,
Formattable res;
parseRes(res, fmt, text, textLength, parsePos, TRUE, status);
currency[0] = 0;
const CurrencyAmount* c;
if (res.getType() == Formattable::kObject &&
res.getObject()->getDynamicClassID() == CurrencyAmount::getStaticClassID()) {
const CurrencyAmount* c = (const CurrencyAmount*) res.getObject();
(c = dynamic_cast<const CurrencyAmount*>(res.getObject())) != NULL) {
u_strcpy(currency, c->getISOCurrency());
}
return res.getDouble(*status);
@ -400,8 +403,9 @@ U_CAPI int32_t U_EXPORT2
unum_getAttribute(const UNumberFormat* fmt,
UNumberFormatAttribute attr)
{
if (((const NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
const DecimalFormat* df = (const DecimalFormat*) fmt;
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL) {
switch(attr) {
case UNUM_PARSE_INT_ONLY:
return df->isParseIntegerOnly();
@ -464,10 +468,11 @@ unum_getAttribute(const UNumberFormat* fmt,
break;
}
} else {
U_ASSERT(((const NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
if (attr == UNUM_LENIENT_PARSE) {
#if !UCONFIG_NO_COLLATION
return ((const RuleBasedNumberFormat*)fmt)->isLenient();
return rbnf->isLenient();
#endif
}
}
@ -480,8 +485,9 @@ unum_setAttribute( UNumberFormat* fmt,
UNumberFormatAttribute attr,
int32_t newValue)
{
if (((NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
DecimalFormat* df = (DecimalFormat*) fmt;
NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL) {
switch(attr) {
case UNUM_PARSE_INT_ONLY:
df->setParseIntegerOnly(newValue!=0);
@ -563,10 +569,11 @@ unum_setAttribute( UNumberFormat* fmt,
break;
}
} else {
U_ASSERT(((NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
if (attr == UNUM_LENIENT_PARSE) {
#if !UCONFIG_NO_COLLATION
((RuleBasedNumberFormat*)fmt)->setLenient((UBool)newValue);
rbnf->setLenient((UBool)newValue);
#endif
}
}
@ -576,9 +583,10 @@ U_CAPI double U_EXPORT2
unum_getDoubleAttribute(const UNumberFormat* fmt,
UNumberFormatAttribute attr)
{
if (((const NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID() &&
attr == UNUM_ROUNDING_INCREMENT) {
return ((const DecimalFormat*)fmt)->getRoundingIncrement();
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) {
return df->getRoundingIncrement();
} else {
return -1.0;
}
@ -589,9 +597,10 @@ unum_setDoubleAttribute( UNumberFormat* fmt,
UNumberFormatAttribute attr,
double newValue)
{
if (((NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID() &&
attr == UNUM_ROUNDING_INCREMENT) {
((DecimalFormat*)fmt)->setRoundingIncrement(newValue);
NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) {
df->setRoundingIncrement(newValue);
}
}
@ -612,8 +621,9 @@ unum_getTextAttribute(const UNumberFormat* fmt,
res.setTo(result, 0, resultLength);
}
if (((const NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
const DecimalFormat* df = (const DecimalFormat*) fmt;
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL) {
switch(tag) {
case UNUM_POSITIVE_PREFIX:
df->getPositivePrefix(res);
@ -644,8 +654,8 @@ unum_getTextAttribute(const UNumberFormat* fmt,
return -1;
}
} else {
U_ASSERT(((const NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
const RuleBasedNumberFormat* rbnf = (const RuleBasedNumberFormat*)fmt;
const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
if (tag == UNUM_DEFAULT_RULESET) {
res = rbnf->getDefaultRuleSetName();
} else if (tag == UNUM_PUBLIC_RULESETS) {
@ -672,12 +682,12 @@ unum_setTextAttribute( UNumberFormat* fmt,
{
if(U_FAILURE(*status))
return;
int32_t len = (newValueLength == -1 ? u_strlen(newValue) : newValueLength);
const UnicodeString val((UChar*)newValue, len, len);
if (((NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
DecimalFormat* df = (DecimalFormat*) fmt;
NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL) {
switch(tag) {
case UNUM_POSITIVE_PREFIX:
df->setPositivePrefix(val);
@ -708,11 +718,12 @@ unum_setTextAttribute( UNumberFormat* fmt,
break;
}
} else {
U_ASSERT(((NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
if (tag == UNUM_DEFAULT_RULESET) {
((RuleBasedNumberFormat*)fmt)->setDefaultRuleSet(newValue, *status);
rbnf->setDefaultRuleSet(newValue, *status);
} else {
*status = U_UNSUPPORTED_ERROR;
*status = U_UNSUPPORTED_ERROR;
}
}
}
@ -734,15 +745,17 @@ unum_toPattern( const UNumberFormat* fmt,
pat.setTo(result, 0, resultLength);
}
if (((const NumberFormat*)fmt)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
const DecimalFormat* df = (const DecimalFormat*) fmt;
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL) {
if(isPatternLocalized)
df->toLocalizedPattern(pat);
else
df->toPattern(pat);
} else {
U_ASSERT(((const NumberFormat*)fmt)->getDynamicClassID() == RuleBasedNumberFormat::getStaticClassID());
pat = ((const RuleBasedNumberFormat*)fmt)->getRules();
const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
U_ASSERT(rbnf != NULL);
pat = rbnf->getRules();
}
return pat.extract(result, resultLength, *status);
}
@ -757,18 +770,18 @@ unum_getSymbol(const UNumberFormat *fmt,
if(status==NULL || U_FAILURE(*status)) {
return 0;
}
if(fmt==NULL || (uint16_t)symbol>=UNUM_FORMAT_SYMBOL_COUNT) {
*status=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
if (((const NumberFormat*)fmt)->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
const NumberFormat *nf = reinterpret_cast<const NumberFormat *>(fmt);
const DecimalFormat *dcf = dynamic_cast<const DecimalFormat *>(nf);
if (dcf == NULL) {
*status = U_UNSUPPORTED_ERROR;
return 0;
}
return ((const DecimalFormat *)fmt)->
return dcf->
getDecimalFormatSymbols()->
getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol).
extract(buffer, size, *status);
@ -784,25 +797,25 @@ unum_setSymbol(UNumberFormat *fmt,
if(status==NULL || U_FAILURE(*status)) {
return;
}
if(fmt==NULL || (uint16_t)symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL || length<-1) {
*status=U_ILLEGAL_ARGUMENT_ERROR;
return;
}
if (((NumberFormat*)fmt)->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
NumberFormat *nf = reinterpret_cast<NumberFormat *>(fmt);
DecimalFormat *dcf = dynamic_cast<DecimalFormat *>(nf);
if (dcf == NULL) {
*status = U_UNSUPPORTED_ERROR;
return;
}
DecimalFormatSymbols symbols(*((DecimalFormat *)fmt)->getDecimalFormatSymbols());
DecimalFormatSymbols symbols(*dcf->getDecimalFormatSymbols());
symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol,
UnicodeString(value, length)); /* UnicodeString can handle the case when length = -1. */
((DecimalFormat *)fmt)->setDecimalFormatSymbols(symbols);
dcf->setDecimalFormatSymbols(symbols);
}
U_CAPI void U_EXPORT2
unum_applyPattern( UNumberFormat *format,
unum_applyPattern( UNumberFormat *fmt,
UBool localized,
const UChar *pattern,
int32_t patternLength,
@ -822,13 +835,15 @@ unum_applyPattern( UNumberFormat *format,
int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
const UnicodeString pat((UChar*)pattern, len, len);
// Verify if the object passed is a DecimalFormat object
if (((NumberFormat*)format)->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL) {
if(localized) {
((DecimalFormat*)format)->applyLocalizedPattern(pat,*parseError, *status);
df->applyLocalizedPattern(pat,*parseError, *status);
} else {
((DecimalFormat*)format)->applyPattern(pat,*parseError, *status);
df->applyPattern(pat,*parseError, *status);
}
} else {
*status = U_UNSUPPORTED_ERROR;

View File

@ -1,10 +1,12 @@
/*
*******************************************************************************
* Copyright (C) 2007-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2007-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
@ -1033,8 +1035,7 @@ VTimeZone::operator==(const TimeZone& that) const {
if (this == &that) {
return TRUE;
}
if (getDynamicClassID() != that.getDynamicClassID()
|| !BasicTimeZone::operator==(that)) {
if (typeid(*this) != typeid(that) || !BasicTimeZone::operator==(that)) {
return FALSE;
}
VTimeZone *vtz = (VTimeZone*)&that;
@ -1563,8 +1564,9 @@ VTimeZone::parse(UErrorCode& status) {
for (n = 0; n < rules->size(); n++) {
TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
if (r->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()) {
if (((AnnualTimeZoneRule*)r)->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
AnnualTimeZoneRule *atzrule = dynamic_cast<AnnualTimeZoneRule *>(r);
if (atzrule != NULL) {
if (atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
finalRuleCount++;
finalRuleIdx = n;
}
@ -1920,12 +1922,13 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz,
Grego::timeToFields(tzt.getTime() + fromOffset, year, month, dom, dow, doy, mid);
int32_t weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
UBool sameRule = FALSE;
const AnnualTimeZoneRule *atzrule;
if (isDst) {
if (finalDstRule == NULL
&& tzt.getTo()->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()) {
if (((AnnualTimeZoneRule*)tzt.getTo())->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
finalDstRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
}
&& (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
&& atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
) {
finalDstRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
}
if (dstCount > 0) {
if (year == dstStartYear + dstCount
@ -1973,10 +1976,10 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz,
}
} else {
if (finalStdRule == NULL
&& tzt.getTo()->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()) {
if (((AnnualTimeZoneRule*)tzt.getTo())->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
finalStdRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
}
&& (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
&& atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
) {
finalStdRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
}
if (stdCount > 0) {
if (year == stdStartYear + stdCount

View File

@ -1333,10 +1333,10 @@ ZoneStringFormat::getGenericString(const Calendar &cal, UBool isShort, UBool com
// Check if the zone actually uses daylight saving time around the time
TimeZone *tmptz = tz.clone();
BasicTimeZone *btz = NULL;
if (tmptz->getDynamicClassID() == OlsonTimeZone::getStaticClassID()
|| tmptz->getDynamicClassID() == SimpleTimeZone::getStaticClassID()
|| tmptz->getDynamicClassID() == RuleBasedTimeZone::getStaticClassID()
|| tmptz->getDynamicClassID() == VTimeZone::getStaticClassID()) {
if (dynamic_cast<OlsonTimeZone *>(tmptz) != NULL
|| dynamic_cast<SimpleTimeZone *>(tmptz) != NULL
|| dynamic_cast<RuleBasedTimeZone *>(tmptz) != NULL
|| dynamic_cast<VTimeZone *>(tmptz) != NULL) {
btz = (BasicTimeZone*)tmptz;
}

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1999-2004, International Business Machines Corporation and
* Copyright (c) 1999-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -113,7 +113,8 @@ setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &
// check that the formatter is a DecimalFormat instance
// necessary because we will cast to the DecimalFormat subclass to set
// the currency symbol
if(nf.getDynamicClassID()!=DecimalFormat::getStaticClassID()) {
DecimalFormat *dnf=dynamic_cast<DecimalFormat *>(&nf);
if(dnf==NULL) {
errorCode=U_ILLEGAL_ARGUMENT_ERROR;
return;
}
@ -168,12 +169,11 @@ setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &
nf.setMinimumFractionDigits(currencyMap[i].fractionDigits);
nf.setMaximumFractionDigits(currencyMap[i].fractionDigits);
DecimalFormat &dnf=(DecimalFormat &)nf;
dnf.setRoundingIncrement(currencyMap[i].roundingIncrement);
dnf->setRoundingIncrement(currencyMap[i].roundingIncrement);
DecimalFormatSymbols symbols(*dnf.getDecimalFormatSymbols());
DecimalFormatSymbols symbols(*dnf->getDecimalFormatSymbols());
symbols.setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencyMap[i].symbol);
dnf.setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889
dnf->setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889
}
/*

View File

@ -2034,7 +2034,7 @@ static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode
adopt->clear();
adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
UDate ret = adopt->getTime(status);
isGregorian = (adopt->getDynamicClassID() == GregorianCalendar::getStaticClassID());
isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL;
delete adopt;
return ret;
}

View File

@ -1,6 +1,6 @@
/****************************************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2006, International Business Machines Corporation and
* Copyright (c) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved.
* Modification History:
*
@ -9,6 +9,8 @@
****************************************************************************************/
#include <string.h>
#include <typeinfo> // for 'typeid' to work
#include "unicode/chariter.h"
#include "unicode/ustring.h"
#include "unicode/unistr.h"
@ -1081,7 +1083,7 @@ public:
virtual UBool operator==(const ForwardCharacterIterator &that) const {
return
this==&that ||
getDynamicClassID()==that.getDynamicClassID() && pos==((SubCharIter &)that).pos;
(typeid(*this)==typeid(that) && pos==((SubCharIter &)that).pos);
}
virtual int32_t hashCode() const {

View File

@ -108,10 +108,11 @@ void IntlTestDateFormatAPI::TestEquals(void)
if (!(*a == *b))
errln("FAIL: DateFormat objects created at different times are unequal.");
if (b->getDynamicClassID() == SimpleDateFormat::getStaticClassID())
SimpleDateFormat *sdtfmt = dynamic_cast<SimpleDateFormat *>(b);
if (sdtfmt != NULL)
{
double ONE_YEAR = 365*24*60*60*1000.0;
((SimpleDateFormat*)b)->set2DigitYearStart(start + 50*ONE_YEAR, status);
sdtfmt->set2DigitYearStart(start + 50*ONE_YEAR, status);
if (U_FAILURE(status))
errln("FAIL: setTwoDigitStartDate failed.");
else if (*a == *b)

View File

@ -401,8 +401,9 @@ void DateFormatTest::TestFieldPosition() {
// String str;
DateFormat* df = dateFormats[j];
df->setTimeZone(*PT);
if (df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
logln(" Pattern = " + ((SimpleDateFormat*) df)->toPattern(buf.remove()));
SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
if (sdtfmt != NULL) {
logln(" Pattern = " + sdtfmt->toPattern(buf.remove()));
} else {
logln(" Pattern = ? (not a SimpleDateFormat)");
}

View File

@ -1,12 +1,12 @@
/**
*******************************************************************************
* Copyright (C) 2001-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Copyright (C) 2001-2010, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_SERVICE
@ -85,7 +85,7 @@ class Integer : public UObject {
virtual UBool operator==(const UObject& other) const
{
return other.getDynamicClassID() == getStaticClassID() &&
return typeid(*this) == typeid(other) &&
_val == ((Integer&)other)._val;
}
@ -116,8 +116,9 @@ class TestIntegerService : public ICUService {
virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status)
{
if (U_SUCCESS(status) && obj && obj->getDynamicClassID() == Integer::getStaticClassID()) {
return new SimpleFactory((Integer*)obj, id, visible);
Integer* i;
if (U_SUCCESS(status) && obj && (i = dynamic_cast<Integer*>(obj)) != NULL) {
return new SimpleFactory(i, id, visible);
}
return NULL;
}
@ -156,13 +157,15 @@ UnicodeString append(UnicodeString& result, const UObject* obj)
if (obj == NULL) {
result.append("NULL");
} else {
UClassID id = obj->getDynamicClassID();
if (id == UnicodeString::getStaticClassID()) {
result.append(*(UnicodeString*)obj);
} else if (id == Locale::getStaticClassID()) {
result.append(((Locale*)obj)->getName());
} else if (id == Integer::getStaticClassID()) {
sprintf(buffer, "%d", (int)((Integer*)obj)->_val);
const UnicodeString* s;
const Locale* loc;
const Integer* i;
if ((s = dynamic_cast<const UnicodeString*>(obj)) != NULL) {
result.append(*s);
} else if ((loc = dynamic_cast<const Locale*>(obj)) != NULL) {
result.append(loc->getName());
} else if ((i = dynamic_cast<const Integer*>(obj)) != NULL) {
sprintf(buffer, "%d", (int)i->_val);
result.append(buffer);
} else {
sprintf(buffer, "%p", (const void*)obj);
@ -478,7 +481,7 @@ public:
// have to implement cloneInstance. Otherwise we could just tell the service
// what the object type is when we create it, and the default implementation
// could handle everything for us. Phooey.
if (obj && obj->getDynamicClassID() == UnicodeString::getStaticClassID()) {
if (obj && dynamic_cast<UnicodeString*>(obj) != NULL) {
return ICUService::createSimpleFactory(obj, id, visible, status);
}
return NULL;
@ -497,8 +500,9 @@ class TestStringService : public ICUService {
virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& /* status */)
{
if (obj && obj->getDynamicClassID() == UnicodeString::getStaticClassID()) {
return new SimpleFactory((UnicodeString*)obj, id, visible);
UnicodeString* s;
if (obj && (s = dynamic_cast<UnicodeString*>(obj)) != NULL) {
return new SimpleFactory(s, id, visible);
}
return NULL;
}

View File

@ -123,7 +123,7 @@ operator+(const UnicodeString& left,
#if !UCONFIG_NO_FORMATTING
/**
* Return a string display for for this, without surrounding braces.
* Return a string display for this, without surrounding braces.
*/
UnicodeString _toString(const Formattable& f) {
UnicodeString s;
@ -170,15 +170,15 @@ UnicodeString _toString(const Formattable& f) {
}
}
break;
case Formattable::kObject:
if (f.getObject()->getDynamicClassID() ==
CurrencyAmount::getStaticClassID()) {
const CurrencyAmount& c = (const CurrencyAmount&) *f.getObject();
s = _toString(c.getNumber()) + " " + UnicodeString(c.getISOCurrency());
case Formattable::kObject: {
const CurrencyAmount* c = dynamic_cast<const CurrencyAmount*>(f.getObject());
if (c != NULL) {
s = _toString(c->getNumber()) + " " + UnicodeString(c->getISOCurrency());
} else {
s = UnicodeString("Unknown UObject");
}
break;
}
default:
s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
break;

View File

@ -44,23 +44,9 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &
{
if (exec) logln("TestSuite Utilities: ");
switch (index) {
CASE(0, MultithreadTest);
CASE(1, StringTest);
CASE(2, UnicodeStringTest);
CASE(3, LocaleTest);
CASE(4, CharIterTest);
CASE(5, UnicodeTest);
CASE(6, ResourceBundleTest);
CASE(7, NewResourceBundleTest);
CASE(8, PUtilTest);
CASE(9, UObjectTest);
CASE(10, UVector32Test);
CASE(11, UVectorTest);
CASE(12, UTextTest);
CASE(13, LocaleAliasTest);
CASE(14, UnicodeSetTest);
CASE(15, ErrorCodeTest);
case 16:
CASE(0, UObjectTest);
CASE(1, ErrorCodeTest);
case 2:
name = "LocalPointerTest";
if (exec) {
logln("TestSuite LocalPointerTest---"); logln();
@ -68,6 +54,20 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &
callTest(*test, par);
}
break;
CASE(3, StringTest);
CASE(4, UnicodeStringTest);
CASE(5, CharIterTest);
CASE(6, UTextTest);
CASE(7, UnicodeSetTest);
CASE(8, UnicodeTest);
CASE(9, UVector32Test);
CASE(10, UVectorTest);
CASE(11, PUtilTest);
CASE(12, LocaleTest);
CASE(13, ResourceBundleTest);
CASE(14, NewResourceBundleTest);
CASE(15, LocaleAliasTest);
CASE(16, MultithreadTest);
default: name = ""; break; //needed to end loop
}
}

View File

@ -1835,12 +1835,12 @@ void LocaleTest::TestGetLocale(void) {
// DecimalFormat, DecimalFormatSymbols
#if !UCONFIG_NO_FORMATTING
req = "fr_FR_NICE";
DecimalFormat* dec = (DecimalFormat*)
NumberFormat::createInstance(Locale::createFromName(req), ec);
NumberFormat* nf = NumberFormat::createInstance(Locale::createFromName(req), ec);
if (U_FAILURE(ec)) {
dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec));
} else {
if (dec->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat* dec = dynamic_cast<DecimalFormat*>(nf);
if (dec == NULL) {
errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
return;
}
@ -1865,20 +1865,21 @@ void LocaleTest::TestGetLocale(void) {
_checklocs("DecimalFormatSymbols", req, valid, actual);
}
}
delete dec;
delete nf;
#endif
// DateFormat, DateFormatSymbols
#if !UCONFIG_NO_FORMATTING
req = "de_CH_LUCERNE";
SimpleDateFormat* dat = (SimpleDateFormat*)
DateFormat* df =
DateFormat::createDateInstance(DateFormat::kDefault,
Locale::createFromName(req));
if (dat == 0){
if (df == 0){
dataerrln("Error calling DateFormat::createDateInstance()");
} else {
if (dat->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) {
errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
SimpleDateFormat* dat = dynamic_cast<SimpleDateFormat*>(df);
if (dat == NULL) {
errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
return;
}
valid = dat->getLocale(ULOC_VALID_LOCALE, ec);
@ -1902,7 +1903,7 @@ void LocaleTest::TestGetLocale(void) {
_checklocs("DateFormatSymbols", req, valid, actual);
}
}
delete dat;
delete df;
#endif
// BreakIterator

View File

@ -1,6 +1,6 @@
/***********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2009, International Business Machines Corporation
* Copyright (c) 1997-2010, International Business Machines Corporation
* and others. All Rights Reserved.
***********************************************************************/
@ -182,15 +182,16 @@ NumberFormatRoundTripTest::test(NumberFormat *fmt)
// I'll get around this by dividing by the multiplier to make sure
// the double will stay in range.
//if(fmt->getMultipler() == 1)
if(fmt->getDynamicClassID() == DecimalFormat::getStaticClassID())
DecimalFormat *df = dynamic_cast<DecimalFormat *>(fmt);
if(df != NULL)
{
#if !defined(OS390) && !defined(OS400)
/* DBL_MAX/2 is here because randomDouble does a *2 in the math */
test(fmt, randomDouble(DBL_MAX/2.0) / ((DecimalFormat*)fmt)->getMultiplier());
test(fmt, randomDouble(DBL_MAX/2.0) / df->getMultiplier());
#elif IEEE_754
test(fmt, randomDouble(1e75) / ((DecimalFormat*)fmt)->getMultiplier());
test(fmt, randomDouble(1e75) / df->getMultiplier());
#else
test(fmt, randomDouble(1e65) / ((DecimalFormat*)fmt)->getMultiplier()); /*OS390*/
test(fmt, randomDouble(1e65) / df->getMultiplier()); /*OS390*/
#endif
}
@ -229,8 +230,9 @@ void
NumberFormatRoundTripTest::test(NumberFormat *fmt, const Formattable& value)
{
fmt->setMaximumFractionDigits(999);
if(fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
((DecimalFormat *)fmt)->setRoundingIncrement(0.0);
DecimalFormat *df = dynamic_cast<DecimalFormat *>(fmt);
if(df != NULL) {
df->setRoundingIncrement(0.0);
}
UErrorCode status = U_ZERO_ERROR;
UnicodeString s, s2, temp;

View File

@ -1438,8 +1438,8 @@ void NumberFormatTest::TestCurrencyPatterns(void) {
}
// Make sure EURO currency formats have exactly 2 fraction digits
if (nf->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
DecimalFormat* df = (DecimalFormat*) nf;
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL) {
if (u_strcmp(EUR, df->getCurrency()) == 0) {
if (min != 2 || max != 2) {
UnicodeString a;
@ -2816,6 +2816,7 @@ NumberFormatTest::TestCurrencyFormatForMixParsing() {
"US dollars1,234.56",
"1,234.56 US dollars"
};
const CurrencyAmount* curramt;
for (uint32_t i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
UnicodeString stringToBeParsed = ctou(formats[i]);
Formattable result;
@ -2824,15 +2825,16 @@ NumberFormatTest::TestCurrencyFormatForMixParsing() {
if (U_FAILURE(status)) {
errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status));
} else if (result.getType() != Formattable::kObject ||
result.getObject()->getDynamicClassID() != CurrencyAmount::getStaticClassID() ||
((CurrencyAmount*)result.getObject())->getNumber().getDouble() != 1234.56 ||
UnicodeString(((CurrencyAmount*)result.getObject())->getISOCurrency()).compare(ISO_CURRENCY_USD)) {
(curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL ||
curramt->getNumber().getDouble() != 1234.56 ||
UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD)
) {
errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
if (((CurrencyAmount*)result.getObject())->getNumber().getDouble() != 1234.56) {
errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + ((CurrencyAmount*)result.getObject())->getNumber().getDouble());
if (curramt->getNumber().getDouble() != 1234.56) {
errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble());
}
if (((CurrencyAmount*)result.getObject())->getISOCurrency() != ISO_CURRENCY_USD) {
errln((UnicodeString)"wong currency, expect: USD" + ", got: " + ((CurrencyAmount*)result.getObject())->getISOCurrency());
if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
}
}
}

View File

@ -503,15 +503,14 @@ void NumberFormatRegressionTest::Test4086575(void)
return;
}
failure(status, "NumberFormat::createInstance", Locale::getFrance());
// C++ workaround to make sure cast works
// Wouldn't dynamic_cast<DecimalFormat*> be great?
if(nf1->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1);
if(nf == NULL) {
errln("NumberFormat::createInstance returned incorrect type.");
return;
}
DecimalFormat *nf = (DecimalFormat*) nf1;
UnicodeString temp;
logln("nf toPattern1: " + nf->toPattern(temp));
logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp));
@ -842,11 +841,11 @@ void NumberFormatRegressionTest::Test4087244 (void) {
delete nf;
return;
}
if (nf->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
if(df == NULL) {
errln("expected DecimalFormat!");
return;
}
DecimalFormat *df = (DecimalFormat*) nf;
const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols();
UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
@ -1907,12 +1906,12 @@ void NumberFormatRegressionTest::Test4145457() {
delete nff;
return;
};
if(nff->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff);
if(nf == NULL) {
errln("DecimalFormat needed to continue");
return;
}
DecimalFormat *nf = (DecimalFormat*)nff;
DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols();
sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027);
nf->setDecimalFormatSymbols(*sym);
@ -2184,11 +2183,11 @@ void NumberFormatRegressionTest::Test4170798(void) {
delete nf;
return;
};
if(nf->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
if(df == NULL) {
errln("DecimalFormat needed to continue");
return;
}
DecimalFormat *df = (DecimalFormat*) nf;
df->setParseIntegerOnly(TRUE);
Formattable n;
ParsePosition pos(0);

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2009, International Business Machines Corporation and
* Copyright (c) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -182,11 +182,11 @@ void ParsePositionTest::TestFieldPosition_example()
return;
};
if(nf->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
DecimalFormat *fmt = dynamic_cast<DecimalFormat *>(nf);
if(fmt == NULL) {
errln("NumberFormat::createInstance returned unexpected class type");
return;
}
DecimalFormat *fmt = (DecimalFormat*) nf;
fmt->setDecimalSeparatorAlwaysShown(TRUE);
const int tempLen = 20;

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1999-2009, International Business Machines Corporation and
* Copyright (c) 1999-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/************************************************************************
@ -9,6 +9,8 @@
* 01/12/2000 Madhu Updated for changed API and added new tests
************************************************************************/
#include <typeinfo> // for 'typeid' to work
#include "unicode/utypes.h"
#if !UCONFIG_NO_BREAK_ITERATION
@ -752,8 +754,8 @@ void RBBITest::TestTrieDict() {
goto cleanup;
}
if (enumer1->getDynamicClassID() == enumer2->getDynamicClassID()) {
errln("CompactTrieEnumeration and MutableTrieEnumeration ClassIDs are the same");
if (typeid(*enumer1) == typeid(*enumer2)) {
errln("CompactTrieEnumeration and MutableTrieEnumeration typeids are the same");
}
delete enumer1;
enumer1 = NULL;

View File

@ -1093,10 +1093,7 @@ TimeZoneRegressionTest::TestJDK12API()
return;
}
SimpleTimeZone *cst = 0;
if(cst1->getDynamicClassID() == SimpleTimeZone::getStaticClassID())
cst = (SimpleTimeZone*) cst1;
SimpleTimeZone *cst = dynamic_cast<SimpleTimeZone *>(cst1);
if(pst->hasSameRules(*cst)) {
errln("FAILURE: PST and CST have same rules");

View File

@ -35,7 +35,7 @@
// *****************************************************************************
// TODO: We should probably read following data at runtime, so we can update
// the these values every release with necessary data changes.
// these values every release with necessary data changes.
const int32_t TimeZoneTest::REFERENCE_YEAR = 2009;
const char * TimeZoneTest::REFERENCE_DATA_VERSION = "2009d";
@ -955,7 +955,7 @@ void TimeZoneTest::TestCustomParse()
TimeZone *zone = TimeZone::createTimeZone(id);
UnicodeString itsID, temp;
if (zone->getDynamicClassID() == OlsonTimeZone::getStaticClassID()) {
if (dynamic_cast<OlsonTimeZone *>(zone) != NULL) {
logln(id + " -> Olson time zone");
} else {
zone->getID(itsID);

View File

@ -5,16 +5,27 @@
* Copyright (C) 2010 , Yahoo! Inc.
********************************************************************/
#include <stdio.h>
#include <string.h>
#include <typeinfo> // for 'typeid' to work
#include "uobjtest.h"
#include "cmemory.h" // UAlignedMemory
#include <string.h>
#include <stdio.h>
/**
*
* Test for UObject, currently only the classID.
*
* Usage
* TESTCLASSID_NONE_DEFAULT(Foo)
* -- Foo is expected to not support "poor man's RTTI".
* Beginning with ICU 4.6, we only use compiler RTTI in new class hierarchies.
*
* TESTCLASSID_NONE_CTOR(Foo, (1, 2, 3, status))
* -- Combines TESTCLASSID_NONE_DEFAULT() and TESTCLASSID_CTOR().
*
* TESTCLASSID_NONE_FACTORY(Foo, (1, 2, 3, status))
* -- Combines TESTCLASSID_NONE_DEFAULT() and TESTCLASSID_FACTORY().
*
* TESTCLASSID_ABSTRACT(Bar)
* -- Bar is expected to be abstract. Only the static ID will be tested.
*
@ -33,13 +44,55 @@
* 'status' will be tested & reset. This only tests uniqueness.
*/
#define TESTCLASSID_FACTORY(c, f) { delete testClass(f, #c, #f, c ::getStaticClassID()); if(U_FAILURE(status)) { dataerrln(UnicodeString(#c " - " #f " - got err status ") + UnicodeString(u_errorName(status))); status = U_ZERO_ERROR; } }
#define TESTCLASSID_TRANSLIT(c, t) { delete testClass(Transliterator::createInstance(UnicodeString(t), UTRANS_FORWARD,parseError,status), #c, "Transliterator: " #t, c ::getStaticClassID()); if(U_FAILURE(status)) { dataerrln(UnicodeString(#c " - Transliterator: " #t " - got err status ") + UnicodeString(u_errorName(status))); status = U_ZERO_ERROR; } }
#define TESTCLASSID_CTOR(c, x) { delete testClass(new c x, #c, "new " #c #x, c ::getStaticClassID()); if(U_FAILURE(status)) { dataerrln(UnicodeString(#c " - new " #x " - got err status ") + UnicodeString(u_errorName(status))); status = U_ZERO_ERROR; } }
#define TESTCLASSID_DEFAULT(c) delete testClass(new c, #c, "new " #c , c::getStaticClassID())
#define TESTCLASSID_ABSTRACT(c) testClass(NULL, #c, NULL, c::getStaticClassID())
#define TESTCLASSID_FACTORY_HIDDEN(c, f) {UObject *objVar = f; delete testClass(objVar, #c, #f, objVar!=NULL? objVar->getDynamicClassID(): NULL); if(U_FAILURE(status)) { dataerrln(UnicodeString(#c " - " #f " - got err status ") + UnicodeString(u_errorName(status))); status = U_ZERO_ERROR; } }
#define TESTCLASSID_NONE_DEFAULT(c) \
delete testClassNoClassID(new c, #c, "new " #c)
#define TESTCLASSID_NONE_CTOR(c, x) { \
delete testClassNoClassID(new c x, #c, "new " #c #x); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - new " #x " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define TESTCLASSID_NONE_FACTORY(c, f) { \
delete testClassNoClassID(f, #c, #f); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - " #f " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define TESTCLASSID_FACTORY(c, f) { \
delete testClass(f, #c, #f, c ::getStaticClassID()); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - " #f " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define TESTCLASSID_TRANSLIT(c, t) { \
delete testClass(Transliterator::createInstance(UnicodeString(t), UTRANS_FORWARD,parseError,status), #c, "Transliterator: " #t, c ::getStaticClassID()); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - Transliterator: " #t " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define TESTCLASSID_CTOR(c, x) { \
delete testClass(new c x, #c, "new " #c #x, c ::getStaticClassID()); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - new " #x " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define TESTCLASSID_DEFAULT(c) \
delete testClass(new c, #c, "new " #c , c::getStaticClassID())
#define TESTCLASSID_ABSTRACT(c) \
testClass(NULL, #c, NULL, c::getStaticClassID())
#define TESTCLASSID_FACTORY_HIDDEN(c, f) { \
UObject *objVar = f; \
delete testClass(objVar, #c, #f, objVar!=NULL? objVar->getDynamicClassID(): NULL); \
if(U_FAILURE(status)) { \
dataerrln(UnicodeString(#c " - " #f " - got err status ") + UnicodeString(u_errorName(status))); \
status = U_ZERO_ERROR; \
} \
}
#define MAX_CLASS_ID 200
@ -117,6 +170,30 @@ UObject *UObjectTest::testClass(UObject *obj,
return obj;
}
UObject *UObjectTest::testClassNoClassID(UObject *obj, const char *className, const char *factory)
{
UnicodeString what = UnicodeString(className) + " * x= " + UnicodeString(factory?factory:" ABSTRACT ") + "; ";
UClassID dynamicID = obj->getDynamicClassID();
{
char tmp[500];
sprintf(tmp, " [dynamic=%p] ", dynamicID);
logln(what + tmp);
}
if(factory != NULL) { /* NULL factory means: abstract */
if(!obj) {
dataerrln( "FAIL: ==NULL! " + what);
return obj;
}
if(dynamicID != NULL) {
errln("FAIL: dynamicID != NULL! for non-poor-man's-RTTI " + what);
}
}
return obj;
}
// begin actual #includes for things to be tested
//
@ -186,9 +263,11 @@ UObject *UObjectTest::testClass(UObject *obj,
#include "unicode/fmtable.h"
#include "unicode/format.h"
#include "unicode/gregocal.h"
#include "unicode/locdspnm.h"
#include "unicode/locid.h"
#include "unicode/msgfmt.h"
#include "unicode/normlzr.h"
#include "unicode/normalizer2.h"
#include "unicode/numfmt.h"
#include "unicode/parsepos.h"
#include "unicode/plurrule.h"
@ -240,6 +319,11 @@ void UObjectTest::testIDs()
#if !UCONFIG_NO_NORMALIZATION
UnicodeString emptyString;
TESTCLASSID_CTOR(Normalizer, (emptyString, UNORM_NONE));
const Normalizer2 *noNormalizer2 = NULL;
UnicodeSet emptySet;
TESTCLASSID_NONE_CTOR(FilteredNormalizer2, (*noNormalizer2, emptySet));
TESTCLASSID_FACTORY(CanonicalIterator, new CanonicalIterator(UnicodeString("abc"), status));
#endif
//TESTCLASSID_DEFAULT(CollationElementIterator);
@ -268,6 +352,7 @@ void UObjectTest::testIDs()
TESTCLASSID_DEFAULT(Formattable);
TESTCLASSID_CTOR(CurrencyAmount, (1.0, SMALL_STR, status));
TESTCLASSID_CTOR(CurrencyUnit, (SMALL_STR, status));
TESTCLASSID_NONE_FACTORY(LocaleDisplayNames, LocaleDisplayNames::createInstance("de"));
TESTCLASSID_FACTORY_HIDDEN(CurrencyFormat, MeasureFormat::createCurrencyFormat(Locale::getUS(), status));
TESTCLASSID_FACTORY(GregorianCalendar, Calendar::createInstance(Locale("@calendar=gregorian"), status));
TESTCLASSID_FACTORY(BuddhistCalendar, Calendar::createInstance(Locale("@calendar=buddhist"), status));
@ -324,8 +409,6 @@ void UObjectTest::testIDs()
TESTCLASSID_FACTORY(Locale, new Locale("123"));
TESTCLASSID_FACTORY_HIDDEN(KeywordEnumeration, Locale("@a=b").createKeywords(status));
//TESTCLASSID_DEFAULT(Normalizer);
//TESTCLASSID_DEFAULT(NumeratorSubstitution);
@ -463,18 +546,35 @@ void UObjectTest::TestMFCCompatibility() {
#endif
}
void UObjectTest::TestCompilerRTTI() {
UErrorCode errorCode = U_ZERO_ERROR;
NumberFormat *nf = NumberFormat::createInstance("de", errorCode);
if (U_FAILURE(errorCode)) {
errln("NumberFormat::createInstance(de) failed - %s", u_errorName(errorCode));
return;
}
if (dynamic_cast<DecimalFormat *>(nf) == NULL || dynamic_cast<ChoiceFormat *>(nf) != NULL) {
errln("dynamic_cast<>(NumberFormat) failed");
}
UnicodeSet emptySet;
if (&typeid(*nf) == NULL || typeid(*nf) == typeid(UObject) || typeid(*nf) == typeid(Format) ||
typeid(*nf) != typeid(DecimalFormat) || typeid(*nf) == typeid(ChoiceFormat) ||
typeid(*nf) == typeid(emptySet)
) {
errln("typeid(NumberFormat) failed");
}
}
/* --------------- */
#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
void UObjectTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /* par */ )
{
switch (index) {
CASE(0, testIDs);
CASE(1, testUMemory);
CASE(2, TestMFCCompatibility);
TESTCASE(0, testIDs);
TESTCASE(1, testUMemory);
TESTCASE(2, TestMFCCompatibility);
TESTCASE(3, TestCompilerRTTI);
default: name = ""; break; //needed to end loop
}

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 2002-2005, International Business Machines Corporation and
* Copyright (c) 2002-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -21,6 +21,7 @@ private:
void testIDs();
void testUMemory();
void TestMFCCompatibility();
void TestCompilerRTTI();
//helper
@ -35,7 +36,8 @@ private:
const char *className, const char *factory,
UClassID staticID);
UObject *testClassNoClassID(UObject *obj,
const char *className, const char *factory);
};
#endif

View File

@ -715,8 +715,9 @@ UXMLElement::appendText(UnicodeString &text, UBool recurse) const {
int32_t i, count=fChildren.size();
for(i=0; i<count; ++i) {
node=(const UObject *)fChildren.elementAt(i);
if(node->getDynamicClassID()==UnicodeString::getStaticClassID()) {
text.append(*(const UnicodeString *)node);
const UnicodeString *s=dynamic_cast<const UnicodeString *>(node);
if(s!=NULL) {
text.append(*s);
} else if(recurse) /* must be a UXMLElement */ {
((const UXMLElement *)node)->appendText(text, recurse);
}
@ -766,7 +767,7 @@ const UObject *
UXMLElement::getChild(int32_t i, UXMLNodeType &type) const {
if(0<=i && i<fChildren.size()) {
const UObject *node=(const UObject *)fChildren.elementAt(i);
if(node->getDynamicClassID()==UXMLElement::getStaticClassID()) {
if(dynamic_cast<const UXMLElement *>(node)!=NULL) {
type=UXML_NODE_TYPE_ELEMENT;
} else {
type=UXML_NODE_TYPE_STRING;
@ -787,10 +788,9 @@ UXMLElement::nextChildElement(int32_t &i) const {
int32_t count=fChildren.size();
while(i<count) {
node=(const UObject *)fChildren.elementAt(i++);
// TODO: see if ICU can use C++ instanceof instead of its own poor man's RTTI
// if(node instanceof UXMLElement) {
if(node->getDynamicClassID()==UXMLElement::getStaticClassID()) {
return (const UXMLElement *)node;
const UXMLElement *elem=dynamic_cast<const UXMLElement *>(node);
if(elem!=NULL) {
return elem;
}
}
return NULL;
@ -809,8 +809,8 @@ UXMLElement::getChildElement(const UnicodeString &name) const {
int32_t i, count=fChildren.size();
for(i=0; i<count; ++i) {
node=(const UObject *)fChildren.elementAt(i);
if(node->getDynamicClassID()==UXMLElement::getStaticClassID()) {
const UXMLElement *elem=(const UXMLElement *)node;
const UXMLElement *elem=dynamic_cast<const UXMLElement *>(node);
if(elem!=NULL) {
if(p==elem->fName) {
return elem;
}