132 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| // © 2016 and later: Unicode, Inc. and others.
 | |
| // License & terms of use: http://www.unicode.org/copyright.html
 | |
| /*
 | |
|  *******************************************************************************
 | |
|  * Copyright (C) 2008-2014, Google, International Business Machines Corporation and
 | |
|  * others. All Rights Reserved.
 | |
|  *******************************************************************************
 | |
|  */
 | |
| 
 | |
| #include "unicode/tmunit.h"
 | |
| #include "uassert.h"
 | |
| 
 | |
| #if !UCONFIG_NO_FORMATTING
 | |
| 
 | |
| U_NAMESPACE_BEGIN
 | |
| 
 | |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit)
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * There are only 7 time units.
 | |
|  * So, TimeUnit could be made as singleton 
 | |
|  * (similar to uniset_props.cpp, or unorm.cpp,
 | |
|  * in which a static TimeUnit* array is created, and 
 | |
|  * the creatInstance() returns a const TimeUnit*).
 | |
|  * But the constraint is TimeUnit is a data member of Measure.
 | |
|  * But Measure (which is an existing API) does not expect it's "unit" member
 | |
|  * as singleton. Meaure takes ownership of the "unit" member.
 | |
|  * In its constructor, it does not take a const "unit" pointer.
 | |
|  * Also, Measure can clone and destruct the "unit" pointer.
 | |
|  * In order to preserve the old behavior and let Measure handle singleton "unit",  
 | |
|  * 1. a flag need to be added in Measure; 
 | |
|  * 2. a new constructor which takes const "unit" as parameter need to be added,
 | |
|  *    and this new constructor will set the flag on.
 | |
|  * 3. clone and destructor need to check upon this flag to distinguish on how
 | |
|  *    to handle the "unit". 
 | |
|  * 
 | |
|  * Since TimeUnit is such a light weight object, comparing with the heavy weight
 | |
|  * format operation, we decided to avoid the above complication.
 | |
|  * 
 | |
|  * So, both TimeUnit and CurrencyUnit (the 2 subclasses of MeasureUnit) are
 | |
|  * immutable and non-singleton.
 | |
|  *
 | |
|  * Currently, TimeUnitAmount and CurrencyAmount are immutable.
 | |
|  * If an application needs to create a long list of TimeUnitAmount on the same
 | |
|  * time unit but different number, for example,
 | |
|  * 1 hour, 2 hour, 3 hour, ................. 10,000 hour,
 | |
|  * there might be performance hit because 10,000 TimeUnit object, 
 | |
|  * although all are the same time unit, will be created in heap and deleted.
 | |
|  *
 | |
|  * To address this performance issue, if there is any in the future,
 | |
|  * we should and need to change TimeUnitAmount and CurrencyAmount to be 
 | |
|  * immutable by allowing a setter on the number.
 | |
|  * Or we need to add 2 parallel mutable classes in order to 
 | |
|  * preserve the existing API.
 | |
|  * Or we can use freezable.
 | |
|  */
 | |
| TimeUnit* U_EXPORT2 
 | |
| TimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField, 
 | |
|                          UErrorCode& status) {
 | |
|     if (U_FAILURE(status)) {
 | |
|         return NULL;
 | |
|     }
 | |
|     if (timeUnitField < 0 || timeUnitField >= UTIMEUNIT_FIELD_COUNT) {
 | |
|         status = U_ILLEGAL_ARGUMENT_ERROR;
 | |
|         return NULL;
 | |
|     }
 | |
|     return new TimeUnit(timeUnitField);
 | |
| }
 | |
| 
 | |
| 
 | |
| TimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) {
 | |
|     fTimeUnitField = timeUnitField;
 | |
|     switch (fTimeUnitField) {
 | |
|     case UTIMEUNIT_YEAR:
 | |
|         initTime("year");
 | |
|         break;
 | |
|     case UTIMEUNIT_MONTH:
 | |
|         initTime("month");
 | |
|         break;
 | |
|     case UTIMEUNIT_DAY:
 | |
|         initTime("day");
 | |
|         break;
 | |
|     case UTIMEUNIT_WEEK:
 | |
|         initTime("week");
 | |
|         break;
 | |
|     case UTIMEUNIT_HOUR:
 | |
|         initTime("hour");
 | |
|         break;
 | |
|     case UTIMEUNIT_MINUTE:
 | |
|         initTime("minute");
 | |
|         break;
 | |
|     case UTIMEUNIT_SECOND:
 | |
|         initTime("second");
 | |
|         break;
 | |
|     default:
 | |
|         UPRV_UNREACHABLE_EXIT;
 | |
|     }
 | |
| }
 | |
| 
 | |
| TimeUnit::TimeUnit(const TimeUnit& other) 
 | |
| :   MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
 | |
| }
 | |
| 
 | |
| TimeUnit* 
 | |
| TimeUnit::clone() const {
 | |
|     return new TimeUnit(*this);
 | |
| }
 | |
| 
 | |
| TimeUnit&
 | |
| TimeUnit::operator=(const TimeUnit& other) {
 | |
|     if (this == &other) {
 | |
|         return *this;
 | |
|     }
 | |
|     MeasureUnit::operator=(other);
 | |
|     fTimeUnitField = other.fTimeUnitField;
 | |
|     return *this;
 | |
| }
 | |
| 
 | |
| TimeUnit::UTimeUnitFields
 | |
| TimeUnit::getTimeUnitField() const {
 | |
|     return fTimeUnitField;
 | |
| }
 | |
| 
 | |
| TimeUnit::~TimeUnit() {
 | |
| }
 | |
| 
 | |
| 
 | |
| U_NAMESPACE_END
 | |
| 
 | |
| #endif
 |