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