• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ********************************************************************************
3 *   Copyright (C) 1997-2010, International Business Machines
4 *   Corporation and others.  All Rights Reserved.
5 ********************************************************************************
6 *
7 * File FMTABLE.H
8 *
9 * Modification History:
10 *
11 *   Date        Name        Description
12 *   02/29/97    aliu        Creation.
13 ********************************************************************************
14 */
15 #ifndef FMTABLE_H
16 #define FMTABLE_H
17 
18 #include "unicode/utypes.h"
19 #include "unicode/unistr.h"
20 #include "unicode/stringpiece.h"
21 
22 /**
23  * \file
24  * \brief C++ API: Formattable is a thin wrapper for primitive numeric types.
25  */
26 
27 #if !UCONFIG_NO_FORMATTING
28 
29 U_NAMESPACE_BEGIN
30 
31 class CharString;
32 class DigitList;
33 
34 /**
35  * Formattable objects can be passed to the Format class or
36  * its subclasses for formatting.  Formattable is a thin wrapper
37  * class which interconverts between the primitive numeric types
38  * (double, long, etc.) as well as UDate and UnicodeString.
39  *
40  * <p>Internally, a Formattable object is a union of primitive types.
41  * As such, it can only store one flavor of data at a time.  To
42  * determine what flavor of data it contains, use the getType method.
43  *
44  * <p>As of ICU 3.0, Formattable may also wrap a UObject pointer,
45  * which it owns.  This allows an instance of any ICU class to be
46  * encapsulated in a Formattable.  For legacy reasons and for
47  * efficiency, primitive numeric types are still stored directly
48  * within a Formattable.
49  *
50  * <p>The Formattable class is not suitable for subclassing.
51  */
52 class U_I18N_API Formattable : public UObject {
53 public:
54     /**
55      * This enum is only used to let callers distinguish between
56      * the Formattable(UDate) constructor and the Formattable(double)
57      * constructor; the compiler cannot distinguish the signatures,
58      * since UDate is currently typedefed to be either double or long.
59      * If UDate is changed later to be a bonafide class
60      * or struct, then we no longer need this enum.
61      * @stable ICU 2.4
62      */
63     enum ISDATE { kIsDate };
64 
65     /**
66      * Default constructor
67      * @stable ICU 2.4
68      */
69     Formattable(); // Type kLong, value 0
70 
71     /**
72      * Creates a Formattable object with a UDate instance.
73      * @param d the UDate instance.
74      * @param flag the flag to indicate this is a date. Always set it to kIsDate
75      * @stable ICU 2.0
76      */
77     Formattable(UDate d, ISDATE flag);
78 
79     /**
80      * Creates a Formattable object with a double number.
81      * @param d the double number.
82      * @stable ICU 2.0
83      */
84     Formattable(double d);
85 
86     /**
87      * Creates a Formattable object with a long number.
88      * @param l the long number.
89      * @stable ICU 2.0
90      */
91     Formattable(int32_t l);
92 
93     /**
94      * Creates a Formattable object with an int64_t number
95      * @param ll the int64_t number.
96      * @stable ICU 2.8
97      */
98     Formattable(int64_t ll);
99 
100 #if !UCONFIG_NO_CONVERSION
101     /**
102      * Creates a Formattable object with a char string pointer.
103      * Assumes that the char string is null terminated.
104      * @param strToCopy the char string.
105      * @stable ICU 2.0
106      */
107     Formattable(const char* strToCopy);
108 #endif
109 
110     /**
111      * Creates a Formattable object of an appropriate numeric type from a
112      * a decimal number in string form.  The Formattable will retain the
113      * full precision of the input in decimal format, even when it exceeds
114      * what can be represented by a double of int64_t.
115      *
116      * @param number  the unformatted (not localized) string representation
117      *                     of the Decimal number.
118      * @param status  the error code.  Possible errors include U_INVALID_FORMAT_ERROR
119      *                if the format of the string does not conform to that of a
120      *                decimal number.
121      * @stable ICU 4.4
122      */
123     Formattable(const StringPiece &number, UErrorCode &status);
124 
125     /**
126      * Creates a Formattable object with a UnicodeString object to copy from.
127      * @param strToCopy the UnicodeString string.
128      * @stable ICU 2.0
129      */
130     Formattable(const UnicodeString& strToCopy);
131 
132     /**
133      * Creates a Formattable object with a UnicodeString object to adopt from.
134      * @param strToAdopt the UnicodeString string.
135      * @stable ICU 2.0
136      */
137     Formattable(UnicodeString* strToAdopt);
138 
139     /**
140      * Creates a Formattable object with an array of Formattable objects.
141      * @param arrayToCopy the Formattable object array.
142      * @param count the array count.
143      * @stable ICU 2.0
144      */
145     Formattable(const Formattable* arrayToCopy, int32_t count);
146 
147     /**
148      * Creates a Formattable object that adopts the given UObject.
149      * @param objectToAdopt the UObject to set this object to
150      * @stable ICU 3.0
151      */
152     Formattable(UObject* objectToAdopt);
153 
154     /**
155      * Copy constructor.
156      * @stable ICU 2.0
157      */
158     Formattable(const Formattable&);
159 
160     /**
161      * Assignment operator.
162      * @param rhs   The Formattable object to copy into this object.
163      * @stable ICU 2.0
164      */
165     Formattable&    operator=(const Formattable &rhs);
166 
167     /**
168      * Equality comparison.
169      * @param other    the object to be compared with.
170      * @return        TRUE if other are equal to this, FALSE otherwise.
171      * @stable ICU 2.0
172      */
173     UBool          operator==(const Formattable &other) const;
174 
175     /**
176      * Equality operator.
177      * @param other    the object to be compared with.
178      * @return        TRUE if other are unequal to this, FALSE otherwise.
179      * @stable ICU 2.0
180      */
181     UBool          operator!=(const Formattable& other) const
182       { return !operator==(other); }
183 
184     /**
185      * Destructor.
186      * @stable ICU 2.0
187      */
188     virtual         ~Formattable();
189 
190     /**
191      * Clone this object.
192      * Clones can be used concurrently in multiple threads.
193      * If an error occurs, then NULL is returned.
194      * The caller must delete the clone.
195      *
196      * @return a clone of this object
197      *
198      * @see getDynamicClassID
199      * @stable ICU 2.8
200      */
201     Formattable *clone() const;
202 
203     /**
204      * Selector for flavor of data type contained within a
205      * Formattable object.  Formattable is a union of several
206      * different types, and at any time contains exactly one type.
207      * @stable ICU 2.4
208      */
209     enum Type {
210         /**
211          * Selector indicating a UDate value.  Use getDate to retrieve
212          * the value.
213          * @stable ICU 2.4
214          */
215         kDate,
216 
217         /**
218          * Selector indicating a double value.  Use getDouble to
219          * retrieve the value.
220          * @stable ICU 2.4
221          */
222         kDouble,
223 
224         /**
225          * Selector indicating a 32-bit integer value.  Use getLong to
226          * retrieve the value.
227          * @stable ICU 2.4
228          */
229         kLong,
230 
231         /**
232          * Selector indicating a UnicodeString value.  Use getString
233          * to retrieve the value.
234          * @stable ICU 2.4
235          */
236         kString,
237 
238         /**
239          * Selector indicating an array of Formattables.  Use getArray
240          * to retrieve the value.
241          * @stable ICU 2.4
242          */
243         kArray,
244 
245         /**
246          * Selector indicating a 64-bit integer value.  Use getInt64
247          * to retrieve the value.
248          * @stable ICU 2.8
249          */
250         kInt64,
251 
252         /**
253          * Selector indicating a UObject value.  Use getObject to
254          * retrieve the value.
255          * @stable ICU 3.0
256          */
257         kObject
258    };
259 
260     /**
261      * Gets the data type of this Formattable object.
262      * @return    the data type of this Formattable object.
263      * @stable ICU 2.0
264      */
265     Type            getType(void) const;
266 
267     /**
268      * Returns TRUE if the data type of this Formattable object
269      * is kDouble, kLong, kInt64 or kDecimalNumber.
270      * @return TRUE if this is a pure numeric object
271      * @stable ICU 3.0
272      */
273     UBool           isNumeric() const;
274 
275     /**
276      * Gets the double value of this object. If this object is not of type
277      * kDouble then the result is undefined.
278      * @return    the double value of this object.
279      * @stable ICU 2.0
280      */
getDouble(void)281     double          getDouble(void) const { return fValue.fDouble; }
282 
283     /**
284      * Gets the double value of this object. If this object is of type
285      * long, int64 or Decimal Number then a conversion is peformed, with
286      * possible loss of precision.  If the type is kObject and the
287      * object is a Measure, then the result of
288      * getNumber().getDouble(status) is returned.  If this object is
289      * neither a numeric type nor a Measure, then 0 is returned and
290      * the status is set to U_INVALID_FORMAT_ERROR.
291      * @param status the error code
292      * @return the double value of this object.
293      * @stable ICU 3.0
294      */
295     double          getDouble(UErrorCode& status) const;
296 
297     /**
298      * Gets the long value of this object. If this object is not of type
299      * kLong then the result is undefined.
300      * @return    the long value of this object.
301      * @stable ICU 2.0
302      */
getLong(void)303     int32_t         getLong(void) const { return (int32_t)fValue.fInt64; }
304 
305     /**
306      * Gets the long value of this object. If the magnitude is too
307      * large to fit in a long, then the maximum or minimum long value,
308      * as appropriate, is returned and the status is set to
309      * U_INVALID_FORMAT_ERROR.  If this object is of type kInt64 and
310      * it fits within a long, then no precision is lost.  If it is of
311      * type kDouble or kDecimalNumber, then a conversion is peformed, with
312      * truncation of any fractional part.  If the type is kObject and
313      * the object is a Measure, then the result of
314      * getNumber().getLong(status) is returned.  If this object is
315      * neither a numeric type nor a Measure, then 0 is returned and
316      * the status is set to U_INVALID_FORMAT_ERROR.
317      * @param status the error code
318      * @return    the long value of this object.
319      * @stable ICU 3.0
320      */
321     int32_t         getLong(UErrorCode& status) const;
322 
323     /**
324      * Gets the int64 value of this object. If this object is not of type
325      * kInt64 then the result is undefined.
326      * @return    the int64 value of this object.
327      * @stable ICU 2.8
328      */
getInt64(void)329     int64_t         getInt64(void) const { return fValue.fInt64; }
330 
331     /**
332      * Gets the int64 value of this object. If this object is of a numeric
333      * type and the magnitude is too large to fit in an int64, then
334      * the maximum or minimum int64 value, as appropriate, is returned
335      * and the status is set to U_INVALID_FORMAT_ERROR.  If the
336      * magnitude fits in an int64, then a casting conversion is
337      * peformed, with truncation of any fractional part.  If the type
338      * is kObject and the object is a Measure, then the result of
339      * getNumber().getDouble(status) is returned.  If this object is
340      * neither a numeric type nor a Measure, then 0 is returned and
341      * the status is set to U_INVALID_FORMAT_ERROR.
342      * @param status the error code
343      * @return    the int64 value of this object.
344      * @stable ICU 3.0
345      */
346     int64_t         getInt64(UErrorCode& status) const;
347 
348     /**
349      * Gets the Date value of this object. If this object is not of type
350      * kDate then the result is undefined.
351      * @return    the Date value of this object.
352      * @stable ICU 2.0
353      */
getDate()354     UDate           getDate() const { return fValue.fDate; }
355 
356     /**
357      * Gets the Date value of this object.  If the type is not a date,
358      * status is set to U_INVALID_FORMAT_ERROR and the return value is
359      * undefined.
360      * @param status the error code.
361      * @return    the Date value of this object.
362      * @stable ICU 3.0
363      */
364      UDate          getDate(UErrorCode& status) const;
365 
366     /**
367      * Gets the string value of this object. If this object is not of type
368      * kString then the result is undefined.
369      * @param result    Output param to receive the Date value of this object.
370      * @return          A reference to 'result'.
371      * @stable ICU 2.0
372      */
getString(UnicodeString & result)373     UnicodeString&  getString(UnicodeString& result) const
374       { result=*fValue.fString; return result; }
375 
376     /**
377      * Gets the string value of this object. If the type is not a
378      * string, status is set to U_INVALID_FORMAT_ERROR and a bogus
379      * string is returned.
380      * @param result    Output param to receive the Date value of this object.
381      * @param status    the error code.
382      * @return          A reference to 'result'.
383      * @stable ICU 3.0
384      */
385     UnicodeString&  getString(UnicodeString& result, UErrorCode& status) const;
386 
387     /**
388      * Gets a const reference to the string value of this object. If
389      * this object is not of type kString then the result is
390      * undefined.
391      * @return   a const reference to the string value of this object.
392      * @stable ICU 2.0
393      */
394     inline const UnicodeString& getString(void) const;
395 
396     /**
397      * Gets a const reference to the string value of this object.  If
398      * the type is not a string, status is set to
399      * U_INVALID_FORMAT_ERROR and the result is a bogus string.
400      * @param status    the error code.
401      * @return   a const reference to the string value of this object.
402      * @stable ICU 3.0
403      */
404     const UnicodeString& getString(UErrorCode& status) const;
405 
406     /**
407      * Gets a reference to the string value of this object. If this
408      * object is not of type kString then the result is undefined.
409      * @return   a reference to the string value of this object.
410      * @stable ICU 2.0
411      */
412     inline UnicodeString& getString(void);
413 
414     /**
415      * Gets a reference to the string value of this object. If the
416      * type is not a string, status is set to U_INVALID_FORMAT_ERROR
417      * and the result is a bogus string.
418      * @param status    the error code.
419      * @return   a reference to the string value of this object.
420      * @stable ICU 3.0
421      */
422     UnicodeString& getString(UErrorCode& status);
423 
424     /**
425      * Gets the array value and count of this object. If this object
426      * is not of type kArray then the result is undefined.
427      * @param count    fill-in with the count of this object.
428      * @return         the array value of this object.
429      * @stable ICU 2.0
430      */
getArray(int32_t & count)431     const Formattable* getArray(int32_t& count) const
432       { count=fValue.fArrayAndCount.fCount; return fValue.fArrayAndCount.fArray; }
433 
434     /**
435      * Gets the array value and count of this object. If the type is
436      * not an array, status is set to U_INVALID_FORMAT_ERROR, count is
437      * set to 0, and the result is NULL.
438      * @param count    fill-in with the count of this object.
439      * @param status the error code.
440      * @return         the array value of this object.
441      * @stable ICU 3.0
442      */
443     const Formattable* getArray(int32_t& count, UErrorCode& status) const;
444 
445     /**
446      * Accesses the specified element in the array value of this
447      * Formattable object. If this object is not of type kArray then
448      * the result is undefined.
449      * @param index the specified index.
450      * @return the accessed element in the array.
451      * @stable ICU 2.0
452      */
453     Formattable&    operator[](int32_t index) { return fValue.fArrayAndCount.fArray[index]; }
454 
455     /**
456      * Returns a pointer to the UObject contained within this
457      * formattable, or NULL if this object does not contain a UObject.
458      * @return a UObject pointer, or NULL
459      * @stable ICU 3.0
460      */
461     const UObject*  getObject() const;
462 
463     /**
464      * Returns a numeric string representation of the number contained within this
465      * formattable, or NULL if this object does not contain numeric type.
466      * For values obtained by parsing, the returned decimal number retains
467      * the full precision and range of the original input, unconstrained by
468      * the limits of a double floating point or a 64 bit int.
469      *
470      * This function is not thread safe, and therfore is not declared const,
471      * even though it is logically const.
472      *
473      * Possible errors include U_MEMORY_ALLOCATION_ERROR, and
474      * U_INVALID_STATE if the formattable object has not been set to
475      * a numeric type.
476      *
477      * @param status the error code.
478      * @return the unformatted string representation of a number.
479      * @stable ICU 4.4
480      */
481     StringPiece getDecimalNumber(UErrorCode &status);
482 
483      /**
484      * Sets the double value of this object and changes the type to
485      * kDouble.
486      * @param d    the new double value to be set.
487      * @stable ICU 2.0
488      */
489     void            setDouble(double d);
490 
491     /**
492      * Sets the long value of this object and changes the type to
493      * kLong.
494      * @param l    the new long value to be set.
495      * @stable ICU 2.0
496      */
497     void            setLong(int32_t l);
498 
499     /**
500      * Sets the int64 value of this object and changes the type to
501      * kInt64.
502      * @param ll    the new int64 value to be set.
503      * @stable ICU 2.8
504      */
505     void            setInt64(int64_t ll);
506 
507     /**
508      * Sets the Date value of this object and changes the type to
509      * kDate.
510      * @param d    the new Date value to be set.
511      * @stable ICU 2.0
512      */
513     void            setDate(UDate d);
514 
515     /**
516      * Sets the string value of this object and changes the type to
517      * kString.
518      * @param stringToCopy    the new string value to be set.
519      * @stable ICU 2.0
520      */
521     void            setString(const UnicodeString& stringToCopy);
522 
523     /**
524      * Sets the array value and count of this object and changes the
525      * type to kArray.
526      * @param array    the array value.
527      * @param count    the number of array elements to be copied.
528      * @stable ICU 2.0
529      */
530     void            setArray(const Formattable* array, int32_t count);
531 
532     /**
533      * Sets and adopts the string value and count of this object and
534      * changes the type to kArray.
535      * @param stringToAdopt    the new string value to be adopted.
536      * @stable ICU 2.0
537      */
538     void            adoptString(UnicodeString* stringToAdopt);
539 
540     /**
541      * Sets and adopts the array value and count of this object and
542      * changes the type to kArray.
543      * @stable ICU 2.0
544      */
545     void            adoptArray(Formattable* array, int32_t count);
546 
547     /**
548      * Sets and adopts the UObject value of this object and changes
549      * the type to kObject.  After this call, the caller must not
550      * delete the given object.
551      * @param objectToAdopt the UObject value to be adopted
552      * @stable ICU 3.0
553      */
554     void            adoptObject(UObject* objectToAdopt);
555 
556     /**
557      * Sets the the numeric value from a decimal number string, and changes
558      * the type to to a numeric type appropriate for the number.
559      * The syntax of the number is a "numeric string"
560      * as defined in the Decimal Arithmetic Specification, available at
561      * http://speleotrove.com/decimal
562      * The full precision and range of the input number will be retained,
563      * even when it exceeds what can be represented by a double or an int64.
564      *
565      * @param numberString  a string representation of the unformatted decimal number.
566      * @param status        the error code.  Set to U_INVALID_FORMAT_ERROR if the
567      *                      incoming string is not a valid decimal number.
568      * @stable ICU 4.4
569      */
570     void             setDecimalNumber(const StringPiece &numberString,
571                                       UErrorCode &status);
572 
573     /**
574      * ICU "poor man's RTTI", returns a UClassID for the actual class.
575      *
576      * @stable ICU 2.2
577      */
578     virtual UClassID getDynamicClassID() const;
579 
580     /**
581      * ICU "poor man's RTTI", returns a UClassID for this class.
582      *
583      * @stable ICU 2.2
584      */
585     static UClassID U_EXPORT2 getStaticClassID();
586 
587     /**
588      * Deprecated variant of getLong(UErrorCode&).
589      * @param status the error code
590      * @return the long value of this object.
591      * @deprecated ICU 3.0 use getLong(UErrorCode&) instead
592      */
593     inline int32_t getLong(UErrorCode* status) const;
594 
595     /**
596      * Internal function, do not use.
597      * TODO:  figure out how to make this be non-public.
598      *        NumberFormat::format(Formattable, ...
599      *        needs to get at the DigitList, if it exists, for
600      *        big decimal formatting.
601      *  @internal
602      */
getDigitList()603     DigitList *getDigitList() const { return fDecimalNum;};
604 
605     /**
606      *  Adopt, and set value from, a DigitList
607      *     Internal Function, do not use.
608      *  @param dl the Digit List to be adopted
609      *  @internal
610      */
611     void adoptDigitList(DigitList *dl);
612 
613 private:
614     /**
615      * Cleans up the memory for unwanted values.  For example, the adopted
616      * string or array objects.
617      */
618     void            dispose(void);
619 
620     /**
621      * Common initialization, for use by constructors.
622      */
623     void            init();
624 
625     UnicodeString* getBogus() const;
626 
627     union {
628         UObject*        fObject;
629         UnicodeString*  fString;
630         double          fDouble;
631         int64_t         fInt64;
632         UDate           fDate;
633         struct {
634           Formattable*  fArray;
635           int32_t       fCount;
636         }               fArrayAndCount;
637     } fValue;
638 
639     CharString           *fDecimalStr;
640     DigitList            *fDecimalNum;
641 
642     Type                fType;
643     UnicodeString       fBogus; // Bogus string when it's needed.
644 };
645 
getDate(UErrorCode & status)646 inline UDate Formattable::getDate(UErrorCode& status) const {
647     if (fType != kDate) {
648         if (U_SUCCESS(status)) {
649             status = U_INVALID_FORMAT_ERROR;
650         }
651         return 0;
652     }
653     return fValue.fDate;
654 }
655 
getString(void)656 inline const UnicodeString& Formattable::getString(void) const {
657     return *fValue.fString;
658 }
659 
getString(void)660 inline UnicodeString& Formattable::getString(void) {
661     return *fValue.fString;
662 }
663 
getLong(UErrorCode * status)664 inline int32_t Formattable::getLong(UErrorCode* status) const {
665     return getLong(*status);
666 }
667 
668 U_NAMESPACE_END
669 
670 #endif /* #if !UCONFIG_NO_FORMATTING */
671 
672 #endif //_FMTABLE
673 //eof
674