casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QuantumHolder.h
Go to the documentation of this file.
00001 //# QuantumHolder.h: A holder for Quantities to enable record conversions
00002 //# Copyright (C) 1998,1999,2000,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: QuantumHolder.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_QUANTUMHOLDER_H
00029 #define CASA_QUANTUMHOLDER_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <casa/Utilities/PtrHolder.h>
00034 #include <casa/Utilities/RecordTransformable.h>
00035 #include <casa/BasicSL/Complexfwd.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class QBase;
00041 class String;
00042 class RecordInterface;
00043 class Record;
00044 template <class Qtype> class Quantum;
00045 template <class T> class Vector;
00046 template <class T> class Array;
00047 
00048 // <summary> A holder for Quantums to enable record conversions </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tQuantumHolder" demos="">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //   <li> <linkto class=RecordInterface>RecordInterface</linkto> class
00057 //   <li> <linkto class=Quantum>Quantity</linkto> class
00058 // </prerequisite>
00059 //
00060 // <etymology>
00061 // A Holder of general Quantums
00062 // </etymology>
00063 //
00064 // <synopsis>
00065 // This class can be used to handle a heterogeneous list of Quantums, and
00066 // can handle toRecord() and fromRecord() conversions.
00067 // A QuantumHolder
00068 // is created empty, from a Quantum (e.g. a <src>Quantum<Double></src>) or a
00069 // <src>Quantum<Vector<Float> ></src>).
00070 //
00071 // The accepted range of Quantums is:
00072 // <ul>
00073 //  <li> <src>Quantum<Int>, Quantum<Float>, Quantum<Double> == Quantity</src>
00074 //  <li> <src>Quantum<Complex>, Quantum<DComplex></src>
00075 //  <li> <src>Quantum<Vector<Int> >, Quantum<Vector<Float> ></src>, 
00076 //       <src>Quantum<Vector<Double> ></src>
00077 //  <li> <src>Quantum<Vector<Complex> >, Quantum<Vector<DComplex> ></src>
00078 //  <li> <src>Quantum<Array<Int> >, Quantum<Array<Float> ></src>, 
00079 //       <src>Quantum<Array<Double> ></src>
00080 //  <li> <src>Quantum<Array<Complex> >, Quantum<Array<DComplex> ></src>
00081 // </ul>
00082 // Scalars in the same group can be converted to any in the same group (e.g.
00083 // Int to Double); Vectors of length 1 can be converted to scalars in the 
00084 // corresponding group; Scalars can always be converted to Vectors in the 
00085 // corresponding group. Real scalar values can be converted to Complex values.
00086 // Vectors cannot be converted to other type vectors.
00087 //
00088 // Checks on the contents can be made with functions like
00089 // <src>isQuantity</src> and the contents can be obtained with
00090 // functions like <src>asQuantity</src>. It is an error to try and
00091 // retrieve a Quantum of the wrong type and doing so will generate an
00092 // exception (AipsError).
00093 // </synopsis>
00094 //
00095 // <example>
00096 // <srcblock>
00097 //      TableRecord rec;                // an empty record
00098 //      Quantity x(12.5, "km/s");       // a Quantity
00099 //      String error;                   // an error message
00100 //      if (!QuantumHolder(x).toRecord(error, rec)) {  // make record
00101 //              cout << error << endl;
00102 //      };
00103 //      Record grec;                    // a Record
00104 //      if (!QuantumHolder(x).toRecord(error, grec)) {  // make record
00105 //              cout << error << endl;
00106 //      };
00107 // // Note that for GlishRecords use can be made of the
00108 // // GlishRecord::to/fromrecord() methods.
00109 // </srcblock>
00110 // </example>
00111 //
00112 // <motivation>
00113 // To make general conversions between Quantums and records, without knowing
00114 // the actual Quantum being converted.
00115 // </motivation>
00116 
00117 class QuantumHolder : public RecordTransformable {
00118 
00119 public:
00120 
00121 //# Friends
00122 
00123 //# Enumerations
00124 
00125 //# Constructors
00126   // Creates an empty holder
00127   QuantumHolder();
00128   // Create from a Quantum (copy semantics)
00129   QuantumHolder(const QBase &in);
00130   // Copy a holder (copy semantics)
00131   QuantumHolder(const QuantumHolder &other);
00132 //# Destructor
00133   ~QuantumHolder();
00134 
00135 //# Operators
00136   // Assignment (copy semantics)
00137   QuantumHolder &operator=(const QuantumHolder &other);
00138 
00139 //# Member Functions
00140   // Check if it holds a Quantity. Note that a Vector of length 1 will give
00141   // True to scalar questions.
00142   // <group>
00143   Bool isEmpty() const;
00144   Bool isQuantum() const;
00145   Bool isScalar() const;
00146   Bool isVector() const;
00147   Bool isArray() const;
00148   Bool isReal() const;
00149   Bool isComplex() const;
00150   Bool isQuantity() const;
00151   Bool isQuantumDouble() const;
00152   Bool isQuantumFloat() const;
00153   Bool isQuantumInt() const;
00154   Bool isQuantumComplex() const;
00155   Bool isQuantumDComplex() const;
00156   Bool isQuantumVectorDouble() const;
00157   Bool isQuantumVectorFloat() const;
00158   Bool isQuantumVectorInt() const;
00159   Bool isQuantumVectorComplex() const;
00160   Bool isQuantumVectorDComplex() const;
00161   Bool isQuantumArrayDouble() const;
00162   Bool isQuantumArrayFloat() const;
00163   Bool isQuantumArrayInt() const;
00164   Bool isQuantumArrayComplex() const;
00165   Bool isQuantumArrayDComplex() const;
00166   // </group>
00167   // Get number of numeric elements (1 if scalar, else
00168   // vector length) or dimensions (0 if scalar)
00169   // <thrown>
00170   //  <li> AipsError if holder empty
00171   // </thrown>
00172   // <group>
00173   Int nelements() const;
00174   Int ndim() const;
00175   // </group>
00176 
00177   // Get a Quantum from the holder (with lifetime as long 
00178   // as holder exists). Conversions done if necessary and as described in
00179   // introduction.
00180   // <thrown>
00181   // <li> AipsError if holder empty or no conversion possible
00182   // </thrown>
00183   // <group>
00184   const QBase &asQuantum() const;
00185   const Quantum<Double> &asQuantity() ;
00186   const Quantum<Double> &asQuantumDouble() ;
00187   const Quantum<Float> &asQuantumFloat() ;
00188   const Quantum<Int> &asQuantumInt() ;
00189   const Quantum<Complex> &asQuantumComplex() ;
00190   const Quantum<DComplex> &asQuantumDComplex() ;
00191   const Quantum<Vector<Double> > &asQuantumVectorDouble() ;
00192   const Quantum<Vector<Float> > &asQuantumVectorFloat() ;
00193   const Quantum<Vector<Int> > &asQuantumVectorInt() ;
00194   const Quantum<Vector<Complex> > &asQuantumVectorComplex() ;
00195   const Quantum<Vector<DComplex> > &asQuantumVectorDComplex() ;
00196   const Quantum<Array<Double> > &asQuantumArrayDouble() ;
00197   const Quantum<Array<Float> > &asQuantumArrayFloat() ;
00198   const Quantum<Array<Int> > &asQuantumArrayInt() ;
00199   const Quantum<Array<Complex> > &asQuantumArrayComplex() ;
00200   const Quantum<Array<DComplex> > &asQuantumArrayDComplex() ;
00201   // </group>
00202 
00203   // Create a Quantum from a record or a string.
00204   // A valid record will contain the following fields:
00205   // <ul>
00206   //  <li> value: contains a numeric value of Int, Float, Double, Complex,
00207   //            DComplex or a vector thereof
00208   //  <li> unit: a string with a valid unit string.
00209   // </ul>
00210   // A valid string will be one of the special time/angle formats or a
00211   // value with a valid unit string.
00212   // Illegal values or units will return False and write an error message.
00213   // <group>
00214   virtual Bool fromRecord(String &error, const RecordInterface &in);
00215   virtual Bool fromString(String &error, const String &in);
00216   // </group>
00217   // Create a record from a Quantum. A False return and an error message is
00218   // only generated if there is no valid Quantum in the holder.
00219   virtual Bool toRecord(String &error, RecordInterface &out) const;
00220   // this version throws an exception rather than returning false
00221   virtual void toRecord(RecordInterface &out) const;
00222   // this version throws an exception or returns the result Record.
00223   virtual Record toRecord() const;
00224 
00225 
00226   // Return identification
00227   virtual const String &ident() const;
00228 
00229 private:
00230 
00231 //# Data Members
00232   // Pointer to a Quantity
00233   PtrHolder<QBase> hold_p;
00234 
00235 //# General member functions
00236   // Convert to a different real scalar quantum
00237   void toReal(const uInt &tp);
00238   // Convert to a different complex scalar quantum
00239   void toComplex(const uInt &tp);
00240   // Convert scalar to Vector
00241   void toVector();
00242   // Convert scalar to Array
00243   void toArray();
00244 };
00245 
00246 
00247 } //# NAMESPACE CASA - END
00248 
00249 #endif