Line data Source code
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 0 : 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 0 : TimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField,
60 : UErrorCode& status) {
61 0 : if (U_FAILURE(status)) {
62 0 : return NULL;
63 : }
64 0 : if (timeUnitField < 0 || timeUnitField >= UTIMEUNIT_FIELD_COUNT) {
65 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
66 0 : return NULL;
67 : }
68 0 : return new TimeUnit(timeUnitField);
69 : }
70 :
71 :
72 0 : TimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) {
73 0 : fTimeUnitField = timeUnitField;
74 0 : switch (fTimeUnitField) {
75 : case UTIMEUNIT_YEAR:
76 0 : initTime("year");
77 0 : break;
78 : case UTIMEUNIT_MONTH:
79 0 : initTime("month");
80 0 : break;
81 : case UTIMEUNIT_DAY:
82 0 : initTime("day");
83 0 : break;
84 : case UTIMEUNIT_WEEK:
85 0 : initTime("week");
86 0 : break;
87 : case UTIMEUNIT_HOUR:
88 0 : initTime("hour");
89 0 : break;
90 : case UTIMEUNIT_MINUTE:
91 0 : initTime("minute");
92 0 : break;
93 : case UTIMEUNIT_SECOND:
94 0 : initTime("second");
95 0 : break;
96 : default:
97 0 : U_ASSERT(false);
98 : break;
99 : }
100 0 : }
101 :
102 0 : TimeUnit::TimeUnit(const TimeUnit& other)
103 0 : : MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
104 0 : }
105 :
106 : UObject*
107 0 : TimeUnit::clone() const {
108 0 : return new TimeUnit(*this);
109 : }
110 :
111 : TimeUnit&
112 0 : TimeUnit::operator=(const TimeUnit& other) {
113 0 : if (this == &other) {
114 0 : return *this;
115 : }
116 0 : MeasureUnit::operator=(other);
117 0 : fTimeUnitField = other.fTimeUnitField;
118 0 : return *this;
119 : }
120 :
121 : TimeUnit::UTimeUnitFields
122 0 : TimeUnit::getTimeUnitField() const {
123 0 : return fTimeUnitField;
124 : }
125 :
126 0 : TimeUnit::~TimeUnit() {
127 0 : }
128 :
129 :
130 : U_NAMESPACE_END
131 :
132 : #endif
|