DataType.h

Classes

Global Functions -- Data types (primarily) in the table system (full description)

Data types (primarily) in the table system (source)

Types

enum DataType

TpBool
TpChar
TpUChar
TpShort
TpUShort
TpInt
TpUInt
TpFloat
TpDouble
TpComplex
TpDComplex
TpString
TpTable
TpArrayBool
TpArrayChar
TpArrayUChar
TpArrayShort
TpArrayUShort
TpArrayInt
TpArrayUInt
TpArrayFloat
TpArrayDouble
TpArrayComplex
TpArrayDComplex
TpArrayString
TpRecord
TpOther
TpQuantity
#// TpLDouble, #// TpArrayLDouble,
TpArrayQuantity
TpNumberOfTypes
Since we start at zero, this is the number of types in the enum.

Interface

ostream &operator<<(ostream &os, DataType type)
inline DataType whatType(const void *)
inline DataType whatType(const Bool *)
inline DataType whatType(const Char *)
inline DataType whatType(const uChar *)
inline DataType whatType(const Short*)
inline DataType whatType(const uShort*)
inline DataType whatType(const Int*)
inline DataType whatType(const uInt*)
inline DataType whatType(const float*)
inline DataType whatType(const double*)
inline DataType whatType(const Complex*)
inline DataType whatType(const DComplex*)
inline DataType whatType(const String*)
inline DataType whatType(const Table*)
inline DataType whatType(const Array<Bool> *)
inline DataType whatType(const Array<Char> *)
inline DataType whatType(const Array<uChar> *)
inline DataType whatType(const Array<Short>*)
inline DataType whatType(const Array<uShort> *)
inline DataType whatType(const Array<Int> *)
inline DataType whatType(const Array<uInt> *)
inline DataType whatType(const Array<float> *)
inline DataType whatType(const Array<double> *)
inline DataType whatType(const Array<Complex> *)
inline DataType whatType(const Array<DComplex> *)
inline DataType whatType(const Array<String> *)
inline DataType whatType(const Record *)
inline DataType whatType(const Quantum<Double> *)
inline DataType whatType(const Array<Quantum<Double> > *)
DataType asScalar(DataType type)
DataType asArray(DataType type)
Bool isScalar(DataType type)
Bool isArray(DataType type)
Bool isScalarFun(DataType type); //
Bool isReal(DataType type)
Bool isComplex(DataType type)
Bool isNumeric(DataType type)

Description

Review Status

Reviewed By:
Paul Shannon
Date Reviewed:
1995/05/01
Programs:
Tests:

Synopsis

DataType enumerates possible data types. While this enum is primarily used in the table system, some use of it is made elsewhere. Besides the enum itself, operator<< is defined for DataType; it prints a DataType in the form DataType=Bool.

Also, global functions are written which take a "const pointer to type" and return its DataType (TpOther if unknown). These functions can occasionally allow one to avoid a switch on type, and can be useful in constructing templated classes which are only valid for certain types.

Global functions are also provided which allow one to convert an array type to the equivalent scalar type and vice versa.

Warning New data types should be added just before TpNumberOfTypes, and after all the existing enumerations, to avoid changing the number of an existing type which would cause misinterpretation of data types stored in existing files. Note also that if any new scalar and array types are added that this will break the exising isScalar, isArray, asScalar and asArray functions.

Tip Data types long and unsigned long are not possible. The types Int and uInt are always 4 bytes, so long is not needed and may only cause confusion.

Example

The simplest uses of the DataType enumeration and functions are fairly obvious, for example:
    Double d;
    DataType type = whatType(&d);
    cout << type << endl;
    switch(type) {
    case TpChar:   ...
    ...
    case TpDouble: ...
    }

A less obvious use is for "attaching" a templated object or function to a non-templated object in a safe way. For example:

    class IntFloatContainer {
    public:
        Int intval;
        Float floatval;
        void *ptr(DataType type) {
            if (type == whatType(&intval))
                return &intval;
            else if (type == whatType(&floatval))
                return &floatval;
            else
                return 0; // Illegal type
        }
    };
    
    template<class T> class ValueAccessor {
    public:
        ValueAccessor(IntFloatContainer *container) : container_p(container) {
            if (container_p->ptr(whatType(static_cast<T *>(0))) == 0)
                throw(AipsError("Illegal type..."));
        }
        T &value() { return *((T*)container_p->ptr(whatType(static_cast<T *>(0)))); }
    private:
        IntFloatContainer *container_p;
    };
    

So, this example provides a typesafe interface to values of only a small number of types (and it fairly gracefully allows additional types to be added; in particular the accessor class needs no modification). Techniques such as this are appropriate for situations where one needs to deal with many (but finite) numbers of types. For example, with FITS.

To Do

Enumeration of the possible data types for keywords and table columns:

 enum DataType {TpBool,         TpChar,          TpUChar,
	        TpShort,        TpUShort,        TpInt,        TpUInt,
	        TpFloat,        TpDouble,   
	        TpComplex,      TpDComplex,      TpString,
	        TpTable,
	        TpArrayBool,    TpArrayChar,     TpArrayUChar,
	        TpArrayShort,   TpArrayUShort,   TpArrayInt,   TpArrayUInt,
	        TpArrayFloat,   TpArrayDouble,
	        TpArrayComplex, TpArrayDComplex, TpArrayString,
	        TpRecord, TpOther,
              TpNumberOfTypes
	         };

Member Description

enum DataType

ostream &operator<<(ostream &os, DataType type)

Write a formated representation (e.g., Type=Bool) of the given data type.

inline DataType whatType(const void *)
inline DataType whatType(const Bool *)
inline DataType whatType(const Char *)
inline DataType whatType(const uChar *)
inline DataType whatType(const Short*)
inline DataType whatType(const uShort*)
inline DataType whatType(const Int*)
inline DataType whatType(const uInt*)
inline DataType whatType(const float*)
inline DataType whatType(const double*)
inline DataType whatType(const Complex*)
inline DataType whatType(const DComplex*)
inline DataType whatType(const String*)
inline DataType whatType(const Table*)
inline DataType whatType(const Array<Bool> *)
inline DataType whatType(const Array<Char> *)
inline DataType whatType(const Array<uChar> *)
inline DataType whatType(const Array<Short>*)
inline DataType whatType(const Array<uShort> *)
inline DataType whatType(const Array<Int> *)
inline DataType whatType(const Array<uInt> *)
inline DataType whatType(const Array<float> *)
inline DataType whatType(const Array<double> *)
inline DataType whatType(const Array<Complex> *)
inline DataType whatType(const Array<DComplex> *)
inline DataType whatType(const Array<String> *)
inline DataType whatType(const Record *)
inline DataType whatType(const Quantum<Double> *)
inline DataType whatType(const Array<Quantum<Double> > *)

These (overloaded) functions return DataType that corresponds to to the type that is being pointed at. A pointer is used to avoid to avoid having to create the object if it is of Array or Table types. At least for CFront, it also avoids those types from being instantiated (they are forward declared). The void* function matches any type (if none other will), and returns TpOther.

DataType asScalar(DataType type)
DataType asArray(DataType type)

It is sometimes useful to discover what the corresponding scalar (or array) type is for a given array (or scalar) type. Calling these with TpOther, TpTable, and TpRecord results in an exception being thrown.

Bool isScalar(DataType type)
Bool isArray(DataType type)
Bool isScalarFun(DataType type); //

It is occasionally useful to discover whether or not a DataType represents an array or scalar value. Note that TpTable, TpRecord, and TpOther are neither scalar nor array types.

Bool isReal(DataType type)

It is sometimes useful to discover if a DataType represents a real numeric value (i.e., can it be cast to a Double?) This returns True for both real scalar and array type.

Bool isComplex(DataType type)

Returns True for Complex or DComplex scalar or array types

Bool isNumeric(DataType type)

Returns True if the type is either Real or Complex/DComplex