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