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
29U_NAMESPACE_BEGIN
30
31class CharString;
32class 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 */
62class U_I18N_API Formattable : public UObject {
63public:
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
632private:
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
668inline 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
678inline const UnicodeString& Formattable::getString(void) const {
679    return *fValue.fString;
680}
681
682inline UnicodeString& Formattable::getString(void) {
683    return *fValue.fString;
684}
685
686#ifndef U_HIDE_DEPRECATED_API
687inline int32_t Formattable::getLong(UErrorCode* status) const {
688    return getLong(*status);
689}
690#endif
691
692
693U_NAMESPACE_END
694
695#endif /* #if !UCONFIG_NO_FORMATTING */
696
697#endif //_FMTABLE
698//eof
699