& pt
gCache->get(locale, ptr, status);
}
-RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status) {
+RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status)
+ : ptr(NULL) {
getFromCache(Locale::getDefault().getName(), ptr, status);
}
-RelativeDateTimeFormatter::RelativeDateTimeFormatter(const Locale& locale, UErrorCode& status) {
+RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ const Locale& locale, UErrorCode& status) : ptr(NULL) {
getFromCache(locale.getName(), ptr, status);
}
RelativeDateTimeFormatter::RelativeDateTimeFormatter(
- const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status) {
+ const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status)
+ : ptr(NULL) {
getFromCache(locale.getName(), ptr, status);
if (U_FAILURE(status)) {
return;
}
- RelativeDateTimeData* wptr = ptr.readWrite();
+ RelativeDateTimeData* wptr = SharedObject::copyOnWrite(ptr);
if (wptr == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
@@ -685,23 +676,26 @@ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
}
}
-const NumberFormat& RelativeDateTimeFormatter::getNumberFormat() const {
- return *ptr->numberFormat;
+RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ const RelativeDateTimeFormatter& other) : ptr(other.ptr) {
+ ptr->addRef();
}
-RelativeDateTimeFormatter::RelativeDateTimeFormatter(const RelativeDateTimeFormatter& other) : ptr(other.ptr) {
-}
-
-RelativeDateTimeFormatter& RelativeDateTimeFormatter::operator=(const RelativeDateTimeFormatter& other) {
+RelativeDateTimeFormatter& RelativeDateTimeFormatter::operator=(
+ const RelativeDateTimeFormatter& other) {
if (this != &other) {
- ptr = other.ptr;
+ SharedObject::copyPtr(other.ptr, ptr);
}
return *this;
}
RelativeDateTimeFormatter::~RelativeDateTimeFormatter() {
+ ptr->removeRef();
}
+const NumberFormat& RelativeDateTimeFormatter::getNumberFormat() const {
+ return *ptr->numberFormat;
+}
UnicodeString& RelativeDateTimeFormatter::format(
double quantity, UDateDirection direction, UDateRelativeUnit unit,
@@ -719,12 +713,13 @@ UnicodeString& RelativeDateTimeFormatter::format(
if (decFmt != NULL) {
dec = decFmt->getFixedDecimal(quantity, status);
}
+ CharString buffer;
+ buffer.appendInvariantChars(ptr->pluralRules->select(dec), status);
if (U_FAILURE(status)) {
return appendTo;
}
- char buffer[256];
- int32_t pluralIndex = getPluralIndex(
- UnicodeString2Char(ptr->pluralRules->select(dec), buffer, 256));
+
+ int32_t pluralIndex = getPluralIndex(buffer.data());
if (pluralIndex == -1) {
pluralIndex = 0;
}
@@ -752,11 +747,9 @@ UnicodeString& RelativeDateTimeFormatter::format(
UnicodeString& RelativeDateTimeFormatter::combineDateAndTime(
const UnicodeString& relativeDateString, const UnicodeString& timeString,
UnicodeString& appendTo, UErrorCode& status) const {
- Formattable formattable[2];
- formattable[0].setString(timeString);
- formattable[1].setString(relativeDateString);
+ Formattable args[2] = {timeString, relativeDateString};
FieldPosition fpos(0);
- return ptr->combinedDateAndTime->format(formattable, 2, appendTo, fpos, status);
+ return ptr->combinedDateAndTime->format(args, 2, appendTo, fpos, status);
}
U_NAMESPACE_END
diff --git a/icu4c/source/i18n/unicode/reldatefmt.h b/icu4c/source/i18n/unicode/reldatefmt.h
index 0bf6ed630e4..6e9a98d647a 100644
--- a/icu4c/source/i18n/unicode/reldatefmt.h
+++ b/icu4c/source/i18n/unicode/reldatefmt.h
@@ -1,12 +1,12 @@
/*
-********************************************************************************
-* Copyright (C) 2013, International Business Machines Corporation and
+*****************************************************************************
+* Copyright (C) 2014, International Business Machines Corporation and
* others.
* All Rights Reserved.
-********************************************************************************
+*****************************************************************************
*
* File RELDATEFMT.H
-********************************************************************************
+*****************************************************************************
*/
#ifndef __RELDATEFMT_H
@@ -14,10 +14,14 @@
#include "unicode/utypes.h"
+/**
+ * \file
+ * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow"
+ */
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/locid.h"
-#include "sharedptr.h"
/**
@@ -234,7 +238,7 @@ class NumberFormat;
* caller's responsibility to handle cut-off logic such as deciding between
* displaying "in 7 days" or "in 1 week." This API supports relative dates
* involving one single unit. This API does not support relative dates
- * involving compound units.
+ * involving compound units,
* e.g "in 5 days and 4 hours" nor does it support parsing.
*
* This class is mostly thread safe and immutable with the following caveats:
@@ -327,7 +331,8 @@ public:
* Assignment operator.
* @draft ICU 53
*/
- RelativeDateTimeFormatter& operator=(const RelativeDateTimeFormatter& other);
+ RelativeDateTimeFormatter& operator=(
+ const RelativeDateTimeFormatter& other);
/**
* Destructor.
@@ -350,7 +355,12 @@ public:
* @return appendTo
* @draft ICU 53
*/
- UnicodeString& format(double quantity, UDateDirection direction, UDateRelativeUnit unit, UnicodeString& appendTo, UErrorCode& status) const;
+ UnicodeString& format(
+ double quantity,
+ UDateDirection direction,
+ UDateRelativeUnit unit,
+ UnicodeString& appendTo,
+ UErrorCode& status) const;
/**
* Formats a relative date without a quantity.
@@ -364,7 +374,11 @@ public:
* @return appendTo
* @draft ICU 53
*/
- UnicodeString& format(UDateDirection direction, UDateAbsoluteUnit unit, UnicodeString& appendTo, UErrorCode& status) const;
+ UnicodeString& format(
+ UDateDirection direction,
+ UDateAbsoluteUnit unit,
+ UnicodeString& appendTo,
+ UErrorCode& status) const;
/**
* Combines a relative date string and a time string in this object's
@@ -379,8 +393,10 @@ public:
* @draft ICU 53
*/
UnicodeString& combineDateAndTime(
- const UnicodeString& relativeDateString, const UnicodeString& timeString,
- UnicodeString& appendTo, UErrorCode& status) const;
+ const UnicodeString& relativeDateString,
+ const UnicodeString& timeString,
+ UnicodeString& appendTo,
+ UErrorCode& status) const;
/**
* Returns the NumberFormat this object is using.
@@ -391,7 +407,7 @@ public:
private:
RelativeDateTimeFormatter();
- SharedPtr ptr;
+ const RelativeDateTimeData* ptr;
};
U_NAMESPACE_END
diff --git a/icu4c/source/test/intltest/lrucachetest.cpp b/icu4c/source/test/intltest/lrucachetest.cpp
index de324f2f394..1c7a337fec9 100644
--- a/icu4c/source/test/intltest/lrucachetest.cpp
+++ b/icu4c/source/test/intltest/lrucachetest.cpp
@@ -1,6 +1,6 @@
/*
*******************************************************************************
-* Copyright (C) 2013, International Business Machines Corporation and *
+* Copyright (C) 2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@@ -11,25 +11,27 @@
#include "cstring.h"
#include "intltest.h"
#include "lrucache.h"
+#include "sharedptr.h"
-class CopyOnWriteForTesting : public UObject {
+class CopyOnWriteForTesting : public SharedObject {
public:
- CopyOnWriteForTesting() : localeNamePtr(), formatStrPtr(), length(0) {
+ CopyOnWriteForTesting() : SharedObject(), localeNamePtr(), formatStrPtr(), length(0) {
}
- UObject *clone() const {
- return new CopyOnWriteForTesting(*this);
- }
- virtual ~CopyOnWriteForTesting() {
- }
- SharedPtr localeNamePtr;
- SharedPtr formatStrPtr;
- int32_t length;
-private:
+
CopyOnWriteForTesting(const CopyOnWriteForTesting &other) :
+ SharedObject(other),
localeNamePtr(other.localeNamePtr),
formatStrPtr(other.formatStrPtr),
length(other.length) {
}
+
+ virtual ~CopyOnWriteForTesting() {
+ }
+
+ SharedPtr localeNamePtr;
+ SharedPtr formatStrPtr;
+ int32_t length;
+private:
CopyOnWriteForTesting &operator=(const CopyOnWriteForTesting &rhs);
};
@@ -41,7 +43,7 @@ public:
virtual ~LRUCacheForTesting() {
}
protected:
- virtual UObject *create(const char *localeId, UErrorCode &status);
+ virtual SharedObject *create(const char *localeId, UErrorCode &status);
private:
SharedPtr defaultFormatStr;
};
@@ -56,7 +58,7 @@ LRUCacheForTesting::LRUCacheForTesting(
defaultFormatStr.adoptInstead(new UnicodeString(dfs));
}
-UObject *LRUCacheForTesting::create(const char *localeId, UErrorCode &status) {
+SharedObject *LRUCacheForTesting::create(const char *localeId, UErrorCode &status) {
if (uprv_strcmp(localeId, "error") == 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
@@ -79,14 +81,13 @@ private:
void TestLRUCache();
void TestLRUCacheError();
void verifySharedPointer(
- const SharedPtr& ptr,
+ const CopyOnWriteForTesting* ptr,
const UnicodeString& name,
const UnicodeString& format);
void verifyString(
const UnicodeString &expected, const UnicodeString &actual);
- void verifyPtr(const void *expected, const void *actual);
void verifyReferences(
- const SharedPtr& ptr,
+ const CopyOnWriteForTesting* ptr,
int32_t count, int32_t nameCount, int32_t formatCount);
};
@@ -102,27 +103,28 @@ void LRUCacheTest::runIndexedTest(int32_t index, UBool exec, const char* &name,
void LRUCacheTest::TestSharedPointer() {
UErrorCode status = U_ZERO_ERROR;
LRUCacheForTesting cache(3, "little", status);
- SharedPtr ptr;
+ const CopyOnWriteForTesting* ptr = NULL;
cache.get("boo", ptr, status);
verifySharedPointer(ptr, "boo", "little");
- SharedPtr ptrCopy = ptr;
- verifyPtr(ptr.readOnly(), ptrCopy.readOnly());
+ const CopyOnWriteForTesting* ptrCopy = ptr;
+ ptrCopy->addRef();
{
- SharedPtr ptrCopy2(ptrCopy);
+ const CopyOnWriteForTesting* ptrCopy2(ptrCopy);
+ ptrCopy2->addRef();
verifyReferences(ptr, 4, 1, 2);
+ ptrCopy2->removeRef();
}
- // Test identity assignment
- ptr = ptr;
-
verifyReferences(ptr, 3, 1, 2);
- verifyReferences(ptrCopy, 3, 1, 2);
- *ptrCopy.readWrite()->localeNamePtr.readWrite() = UnicodeString("hi there");
- *ptrCopy.readWrite()->formatStrPtr.readWrite() = UnicodeString("see you");
+ CopyOnWriteForTesting *wPtrCopy = SharedObject::copyOnWrite(ptrCopy);
+ *wPtrCopy->localeNamePtr.readWrite() = UnicodeString("hi there");
+ *wPtrCopy->formatStrPtr.readWrite() = UnicodeString("see you");
verifyReferences(ptr, 2, 1, 2);
verifyReferences(ptrCopy, 1, 1, 1);
verifySharedPointer(ptr, "boo", "little");
verifySharedPointer(ptrCopy, "hi there", "see you");
+ ptrCopy->removeRef();
+ ptr->removeRef();
}
void LRUCacheTest::TestErrorCallingConstructor() {
@@ -133,11 +135,11 @@ void LRUCacheTest::TestErrorCallingConstructor() {
void LRUCacheTest::TestLRUCache() {
UErrorCode status = U_ZERO_ERROR;
LRUCacheForTesting cache(3, "little", status);
- SharedPtr ptr1;
- SharedPtr ptr2;
- SharedPtr ptr3;
- SharedPtr ptr4;
- SharedPtr ptr5;
+ const CopyOnWriteForTesting* ptr1 = NULL;
+ const CopyOnWriteForTesting* ptr2 = NULL;
+ const CopyOnWriteForTesting* ptr3 = NULL;
+ const CopyOnWriteForTesting* ptr4 = NULL;
+ const CopyOnWriteForTesting* ptr5 = NULL;
cache.get("foo", ptr1, status);
cache.get("bar", ptr2, status);
cache.get("baz", ptr3, status);
@@ -166,7 +168,8 @@ void LRUCacheTest::TestLRUCache() {
verifyReferences(ptr5, 3, 1, 5);
// This should delete foo data since it got evicted from cache.
- ptr1.clear();
+ ptr1->removeRef();
+ ptr1 = NULL;
// Reference count for little drops to 4 because foo data was deleted.
verifyReferences(ptr5, 3, 1, 4);
@@ -186,7 +189,8 @@ void LRUCacheTest::TestLRUCache() {
// Since bar was evicted, clearing its pointer should delete its data.
// Notice that the reference count to 'little' dropped from 5 to 4.
- ptr2.clear();
+ ptr2->removeRef();
+ ptr2 = NULL;
verifyReferences(ptr5, 2, 1, 4);
if (cache.contains("bar") || !cache.contains("full")) {
errln("Unexpected 'bar' in cache.");
@@ -199,7 +203,8 @@ void LRUCacheTest::TestLRUCache() {
verifyReferences(ptr5, 2, 1, 5);
// since "full" was evicted, clearing its pointer should delete its data.
- ptr4.clear();
+ ptr4->removeRef();
+ ptr4 = NULL;
verifyReferences(ptr5, 2, 1, 4);
if (cache.contains("full") || !cache.contains("baz")) {
errln("Unexpected 'full' in cache.");
@@ -212,17 +217,23 @@ void LRUCacheTest::TestLRUCache() {
verifyReferences(ptr5, 2, 1, 5);
// since "baz" was evicted, clearing its pointer should delete its data.
- ptr3.clear();
+ ptr3->removeRef();
+ ptr3 = NULL;
verifyReferences(ptr5, 2, 1, 4);
if (cache.contains("baz") || !cache.contains("new3")) {
errln("Unexpected 'baz' in cache.");
}
+ SharedObject::clearPtr(ptr1);
+ SharedObject::clearPtr(ptr2);
+ SharedObject::clearPtr(ptr3);
+ SharedObject::clearPtr(ptr4);
+ SharedObject::clearPtr(ptr5);
}
void LRUCacheTest::TestLRUCacheError() {
UErrorCode status = U_ZERO_ERROR;
LRUCacheForTesting cache(3, "little", status);
- SharedPtr ptr1;
+ const CopyOnWriteForTesting *ptr1;
cache.get("error", ptr1, status);
if (status != U_ILLEGAL_ARGUMENT_ERROR) {
errln("Expected an error.");
@@ -230,7 +241,7 @@ void LRUCacheTest::TestLRUCacheError() {
}
void LRUCacheTest::verifySharedPointer(
- const SharedPtr& ptr,
+ const CopyOnWriteForTesting* ptr,
const UnicodeString& name,
const UnicodeString& format) {
const UnicodeString *strPtr = ptr->localeNamePtr.readOnly();
@@ -245,14 +256,8 @@ void LRUCacheTest::verifyString(const UnicodeString &expected, const UnicodeStri
}
}
-void LRUCacheTest::verifyPtr(const void *expected, const void *actual) {
- if (expected != actual) {
- errln("Pointer mismatch.");
- }
-}
-
-void LRUCacheTest::verifyReferences(const SharedPtr& ptr, int32_t count, int32_t nameCount, int32_t formatCount) {
- int32_t actual = ptr.count();
+void LRUCacheTest::verifyReferences(const CopyOnWriteForTesting* ptr, int32_t count, int32_t nameCount, int32_t formatCount) {
+ int32_t actual = ptr->getRefCount();
if (count != actual) {
errln("Main reference count wrong: Expected %d, got %d", count, actual);
}