ICU-6483 remove useless origin parameter from handleFailure()

X-SVN-Rev: 25550
This commit is contained in:
Markus Scherer 2009-03-11 17:57:24 +00:00
parent 794f261f6a
commit af61e26bf0
3 changed files with 45 additions and 38 deletions

View File

@ -19,17 +19,6 @@
U_NAMESPACE_BEGIN
ErrorCode::~ErrorCode() {}
/* Logically
if(isFailure()) {
handleFailure(kDestructor);
}
but in the destructor, even if it's virtual, this does not call
the subclass' handleFailure(), and our own handleFailure()
does not do anything.
The subclass must have this code.
*/
UErrorCode ErrorCode::reset() {
UErrorCode code = errorCode;
errorCode = U_ZERO_ERROR;
@ -37,7 +26,9 @@ UErrorCode ErrorCode::reset() {
}
void ErrorCode::check() const {
if(isFailure()) { handleFailure(kCheck); }
if(isFailure()) {
handleFailure();
}
}
U_NAMESPACE_END

View File

@ -42,10 +42,31 @@ U_NAMESPACE_BEGIN
* removing one common source of errors.
* - Same use in C APIs taking a UErrorCode * (pointer)
* and C++ taking UErrorCode & (reference) via conversion operators.
* - Automatic checking for success when it goes out of scope.
* - Possible automatic checking for success when it goes out of scope.
*
* Code sample, using an appropriate IcuErrorCode subclass:
* Note: For automatic checking for success in the destructor, a subclass
* must implement such logic in its own destructor because the base class
* destructor cannot call a subclass function (like handleFailure()).
* The ErrorCode base class destructor does nothing.
*
* Note also: While it is possible for a destructor to throw an exception,
* it is generally unsafe to do so. This means that in a subclass the destructor
* and the handleFailure() function may need to take different actions.
*
* Sample code:
* \code
* class IcuErrorCode: public icu::ErrorCode {
* public:
* virtual ~IcuErrorCode() {
* // Safe because our handleFailure() does not throw exceptions.
* if(isFailure()) { handleFailure(); }
* }
* protected:
* virtual handleFailure() {
* log_failure(u_errorName(errorCode));
* exit(errorCode);
* }
* };
* IcuErrorCode error_code;
* UConverter *cnv = ucnv_open("Shift-JIS", error_code);
* length = ucnv_fromUChars(dest, capacity, src, length, error_code);
@ -62,13 +83,8 @@ public:
* @draft ICU 4.2
*/
ErrorCode() : errorCode(U_ZERO_ERROR) {}
/**
* Destructor, does nothing.
* A subclass destructor should do
* if(isFailure()) { handleFailure(kDestructor); }
* @draft ICU 4.2
*/
virtual ~ErrorCode();
/** Destructor, does nothing. See class documentation for details. @draft ICU 4.2 */
virtual ~ErrorCode() {}
/** Conversion operator, returns a reference. @draft ICU 4.2 */
operator UErrorCode & () { return errorCode; }
/** Conversion operator, returns a pointer. @draft ICU 4.2 */
@ -85,17 +101,26 @@ public:
UErrorCode reset();
/**
* Checks for a failure code:
* if(isFailure()) { handleFailure(kCheck); }
* \code
* if(isFailure()) { handleFailure(); }
* \endcode
* @draft ICU 4.2
*/
void check() const;
protected:
/**
* Internal UErrorCode, accessible to subclasses.
* @draft ICU 4.2
*/
UErrorCode errorCode;
enum EOrigin { kCheck, kDestructor };
// Note: A C++ class destructor must not throw an exception.
// Use the origin parameter to avoid this if necessary.
virtual void handleFailure(EOrigin origin) const {}
/**
* Called by check() if isFailure() is true.
* A subclass should override this function to deal with a failure code:
* Throw an exception, log an error, terminate the program, or similar.
* @draft ICU 4.2
*/
virtual void handleFailure() const {}
};
U_NAMESPACE_END

View File

@ -106,21 +106,12 @@ public:
: checks(countChecks), dests(countDests) {}
~MyErrorCode() {
if(isFailure()) {
handleFailure(kDestructor);
++dests;
}
}
private:
virtual void handleFailure(EOrigin origin) const {
switch(origin) {
case kCheck:
++checks;
break;
case kDestructor:
++dests;
break;
default:
break;
}
virtual void handleFailure() const {
++checks;
}
int32_t &checks;
int32_t &dests;