1 /* 2 ******************************************************************************* 3 * Copyright (C) 2008-2012, Google, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 8 #include "utypeinfo.h" // for 'typeid' to work 9 10 #include "unicode/tmunit.h" 11 12 #if !UCONFIG_NO_FORMATTING 13 14 U_NAMESPACE_BEGIN 15 16 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit) 17 18 19 /* 20 * There are only 7 time units. 21 * So, TimeUnit could be made as singleton 22 * (similar to uniset_props.cpp, or unorm.cpp, 23 * in which a static TimeUnit* array is created, and 24 * the creatInstance() returns a const TimeUnit*). 25 * But the constraint is TimeUnit is a data member of Measure. 26 * But Measure (which is an existing API) does not expect it's "unit" member 27 * as singleton. Meaure takes ownership of the "unit" member. 28 * In its constructor, it does not take a const "unit" pointer. 29 * Also, Measure can clone and destruct the "unit" pointer. 30 * In order to preserve the old behavior and let Measure handle singleton "unit", 31 * 1. a flag need to be added in Measure; 32 * 2. a new constructor which takes const "unit" as parameter need to be added, 33 * and this new constructor will set the flag on. 34 * 3. clone and destructor need to check upon this flag to distinguish on how 35 * to handle the "unit". 36 * 37 * Since TimeUnit is such a light weight object, comparing with the heavy weight 38 * format operation, we decided to avoid the above complication. 39 * 40 * So, both TimeUnit and CurrencyUnit (the 2 subclasses of MeasureUnit) are 41 * immutable and non-singleton. 42 * 43 * Currently, TimeUnitAmount and CurrencyAmount are immutable. 44 * If an application needs to create a long list of TimeUnitAmount on the same 45 * time unit but different number, for example, 46 * 1 hour, 2 hour, 3 hour, ................. 10,000 hour, 47 * there might be performance hit because 10,000 TimeUnit object, 48 * although all are the same time unit, will be created in heap and deleted. 49 * 50 * To address this performance issue, if there is any in the future, 51 * we should and need to change TimeUnitAmount and CurrencyAmount to be 52 * immutable by allowing a setter on the number. 53 * Or we need to add 2 parallel mutable classes in order to 54 * preserve the existing API. 55 * Or we can use freezable. 56 */ 57 TimeUnit* U_EXPORT2 58 TimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField, 59 UErrorCode& status) { 60 if (U_FAILURE(status)) { 61 return NULL; 62 } 63 if (timeUnitField < 0 || timeUnitField >= UTIMEUNIT_FIELD_COUNT) { 64 status = U_ILLEGAL_ARGUMENT_ERROR; 65 return NULL; 66 } 67 return new TimeUnit(timeUnitField); 68 } 69 70 71 TimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) { 72 fTimeUnitField = timeUnitField; 73 } 74 75 76 TimeUnit::TimeUnit(const TimeUnit& other) 77 : MeasureUnit(other) { 78 *this = other; 79 } 80 81 82 UObject* 83 TimeUnit::clone() const { 84 return new TimeUnit(*this); 85 } 86 87 88 TimeUnit& 89 TimeUnit::operator=(const TimeUnit& other) { 90 if (this == &other) { 91 return *this; 92 } 93 fTimeUnitField = other.fTimeUnitField; 94 return *this; 95 } 96 97 98 UBool 99 TimeUnit::operator==(const UObject& other) const { 100 return (typeid(*this) == typeid(other) 101 && fTimeUnitField == ((TimeUnit*)&other)->fTimeUnitField); 102 } 103 104 105 TimeUnit::UTimeUnitFields 106 TimeUnit::getTimeUnitField() const { 107 return fTimeUnitField; 108 } 109 110 111 TimeUnit::~TimeUnit() { 112 } 113 114 115 U_NAMESPACE_END 116 117 #endif 118