Home | History | Annotate | Download | only in i18n
      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