tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tmunit.cpp (4008B)


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