casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
VSCEngine.h
Go to the documentation of this file.
00001 //# VSCEngine.h: Base virtual column for a scalar column with any type
00002 //# Copyright (C) 1994,1995,1996,1999,2000
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: VSCEngine.h 21051 2011-04-20 11:46:29Z gervandiepen $
00027 
00028 #ifndef TABLES_VSCENGINE_H
00029 #define TABLES_VSCENGINE_H
00030 
00031 //# Includes
00032 #include <tables/Tables/VirtColEng.h>
00033 #include <tables/Tables/VirtScaCol.h>
00034 
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 // <summary>
00039 // Base virtual column for a scalar column with any type
00040 // </summary>
00041 
00042 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00043 // </reviewed>
00044 
00045 // <use visibility=export>
00046 
00047 // <prerequisite>
00048 //# Classes you should understand before using this one.
00049 //   <li> VirtualColumnEngine
00050 //   <li> VirtualScalarColumn
00051 // </prerequisite>
00052 
00053 // <etymology>
00054 // VSCEngine stands for Virtual Scalar Column Engine, i.e. a class
00055 // handling a virtual table column containing scalar values.
00056 // </etymology>
00057 
00058 // <synopsis> 
00059 // VSCEngine is a base virtual column engine to handle a column
00060 // with an arbitrary type.
00061 // Data of columns with standard data types can directly be stored
00062 // in a Table using a storage manager, but data of column with non-standard
00063 // types have to be stored in another way.
00064 // The way to do this is to split the object with the non-standard
00065 // type into its individual elements, which are subsequently put into the
00066 // appropriate columns.
00067 //
00068 // A virtual column engine has to be implemented for each non-standard
00069 // data type, which has to be stored in a table. This engine has to get
00070 // and put the individual parts the object.
00071 // VSCEngine is the base class for such engines, so the actual
00072 // engine quite simple to implement. The example shows the implementation
00073 // of an engine AVSCEngine handling a data type A.
00074 //
00075 // In principle the name of the engine class is free, but it is strongly
00076 // recommended to use the name <src><dataTypeId>VSCEngine</src>, where VSC
00077 // stands for Virtual Scalar Column (e.g. <src>AVSCEngine</src> for class A).
00078 // In this way the default data manager name supplied by the class and by
00079 // class ScalarColumnDesc can be used.
00080 // </synopsis> 
00081 
00082 // <example>
00083 // This example shows the implementation of an engine class AVSCEngine,
00084 // which stores the data of a class A.
00085 // The data objects A are stored in a column called the source column.
00086 // The user has to associate two target columns with it. The engine stores
00087 // the data parts x and y in the target columns.
00088 // The names of the target columns are stored as keywords in the source
00089 // column. In this way the engine can reconstruct itself when the table
00090 // is read back.
00091 //
00092 // In the example all AVSCEngine functions are shown inline, but they
00093 // should be implemented out-of-line in a separate .cc file.
00094 // <srcblock>
00095 //  //# AVSCEngine.h: Example virtual column engine to handle data type A
00096 //
00097 //  #if !defined(AIPS_AVSCENGINE_H)
00098 //  #define AIPS_AVSCENGINE_H
00099 //
00100 //  //# Includes
00101 //  #include <tables/Tables/VSCEngine.h>
00102 //  #include <tables/Tables/ScalarColumn.h>
00103 //
00104 //  // Define the class A.
00105 //  class A
00106 //  {
00107 //  public:
00108 //      A(): x_p(0), y_p(0) {}
00109 //      A(Int x, float y) : x_p(x), y_p(y) {}
00110 //      A(const A& that): x_p(that.x_p), y_p(that.y_p) {}
00111 //      static String dataTypeId()
00112 //          { return "A"; }
00113 //      Int x() const
00114 //          { return x_p; }
00115 //      float y() const
00116 //          { return y_p; }
00117 //      Int& x()
00118 //          { return x_p; }
00119 //      float& y()
00120 //          { return y_p; }
00121 //      int operator== (const A& that) const
00122 //          { return x_p==that.x_p && y_p==that.y_p; }
00123 //      int operator< (const A& that) const
00124 //          { return x_p<that.x_p || (x_p==that.x_p && y_p<that.y_p); }
00125 //  private:
00126 //      Int   x_p;
00127 //      float y_p;
00128 //  };
00129 //
00130 //  // Now define the engine to handle objects of type A.
00131 //  class AVSCEngine : public VSCEngine<A>
00132 //  {
00133 //  public:
00134 //
00135 //      // The default constructor is required for reconstruction of the
00136 //      // engine when a table is read back.
00137 //      AVSCEngine()
00138 //      {}
00139 //
00140 //      // Construct the engine for the given source column and storing
00141 //      // the result in the given target columns for the data members
00142 //      // x and y of class A.
00143 //      AVSCEngine (const String& sourceColumnName,
00144 //                  const String& xTargetColumnName,
00145 //                  const String& yTargetColumnname)
00146 //      : VSCEngine<A>  (sourceColumnName),
00147 //        xTargetName_p (xTargetColumnName),
00148 //        yTargetName_p (yTargetColumnName)
00149 //      {}
00150 //
00151 //      // Destructor is mandatory.
00152 //      virtual ~AVSCEngine()
00153 //      {}
00154 //
00155 //      // Clone the object.
00156 //      virtual DataManager* clone() const
00157 //      {
00158 //          DataManager* dmPtr = new AVSCEngine (sourceColumnName(),
00159 //                                       xTargetName_p, yTargetName_p);
00160 //          return dmPtr;
00161 //      }
00162 //
00163 //      // Store the target column names in the source column keywords.
00164 //      virtual void create (uInt)
00165 //      {
00166 //          TableColumn src (table(), sourceColumnName());
00167 //          src.keywordSet().keysString()("_xTargetName") = xTargetName_p;
00168 //          src.keywordSet().keysString()("_yTargetName") = yTargetName_p;
00169 //      }
00170 //
00171 //      // Prepare the engine by allocating column objects
00172 //      // for the target columns.
00173 //      virtual void prepare()
00174 //      {
00175 //          ROTableColumn src (table(), sourceColumnName());
00176 //          xTargetName_p = src.keywordSet().asString ("_xTargetName");
00177 //          yTargetName_p = src.keywordSet().asString ("_yTargetName");
00178 //          rocolx.attach (table(), xTargetName_p);
00179 //          rocoly.attach (table(), yTargetName_p);
00180 //          if (table().isWritable()) {
00181 //              colx.attach (table(), xTargetName_p);
00182 //              coly.attach (table(), yTargetName_p);
00183 //          }
00184 //      }
00185 //
00186 //      // Get the data from a row.
00187 //      virtual void get (uInt rownr, A& value)
00188 //      {
00189 //          rocolx.get (rownr, value.x());
00190 //          rocoly.get (rownr, value.y());
00191 //      }
00192 //
00193 //      // Put the data in a row.
00194 //      virtual void put (uInt rownr, const A& value)
00195 //      {
00196 //          colx.put (rownr, value.x());
00197 //          coly.put (rownr, value.y());
00198 //      }
00199 //
00200 //      // Register the class name and the static makeObject "constructor".
00201 //      // This will make the engine known to the table system.
00202 //      static void registerClass()
00203 //      {
00204 //          DataManager::registerCtor ("AVSCEngine", makeObject);
00205 //      }
00206 //
00207 //  private:
00208 //      // Copy constructor is only used by clone().
00209 //      // (so it is made private).
00210 //      AVSCEngine (const AVSCEngine&)
00211 //      : VSCEngine<A>  (that),
00212 //        xTargetName_p (that.xTargetName_p),
00213 //        yTargetName_p (that.yTargetName_p)
00214 //      {}
00215 //
00216 //      // Assignment is not needed and therefore forbidden
00217 //      // (so it is made private and is not implemented).
00218 //      AVSCEngine& operator= (const AVSCEngine&);
00219 //
00220 //
00221 //      // The target column names.
00222 //      String xTargetName_p;
00223 //      String yTargetName_p;
00224 //      // Objects for the target columns.
00225 //      ScalarColumn<Int>     colx;       // used by put
00226 //      ROScalarColumn<Int>   rocolx;     // used by get
00227 //      ScalarColumn<float>   coly;       // used by put
00228 //      ROScalarColumn<float> rocoly;     // used by get
00229 //
00230 //  public:
00231 //      // Define the "constructor" to construct this engine when a
00232 //      // table is read back.
00233 //      // This "constructor" has to be registered by the user of the engine.
00234 //      // Function registerClass() is doing that.
00235 //      static DataManager* makeObject (const String& dataManagerType)
00236 //      {
00237 //          DataManager* dmPtr = new AVSCEngine();
00238 //          return dmPtr;
00239 //      }
00240 //  };
00241 //
00242 //  #endif
00243 // </srcblock>
00244 //
00245 // User code using this engine to create a new table could look like:
00246 // <srcblock>
00247 //   // Register the engine.
00248 //   // This is not needed if the engine is registered as part
00249 //   // of the general DataManager::registerAllCtor function.
00250 //   AVSCEngine::registerClass();
00251 //   // Create the table description.
00252 //   TableDesc td;
00253 //   td.addColumn (ScalarColumnDesc<A>("source"));
00254 //   td.addColumn (ScalarColumnDesc<Int>("xTarget"));
00255 //   td.addColumn (ScalarColumnDesc<Int>("yTarget"));
00256 //   SetupNewTable setup ("table.name", td, Table::New);
00257 //   // Define the engine for column "source".
00258 //   AVSCEngine engine ("source", "xTarget", "yTarget");
00259 //   Table tab (setup, 10);
00260 //   // Put data into column "source".
00261 //   ScalarColumn<A> col (tab, "source");
00262 //   for (uInt i=0; i<10; i++) {
00263 //       col.put (i, someA);     // writes indirectly xTarget and yTarget
00264 //   }
00265 // </srcblock>
00266 // </example>
00267 //
00268 // <motivation>
00269 // This class makes it easier for the user to implement the engine.
00270 // It supplies several default functions.
00271 // </motivation>
00272 
00273 // <templating arg=T>
00274 //  <li> Default constructor    T();
00275 //  <li> Copy constructor       T(const T&);
00276 //  <li> Assignment operator    T& operator= (const T&);
00277 //  <li> comparison operator    int operator== (const T&) const;
00278 //  <li> comparison operator    int operator<  (const T&) const; 
00279 //  <li> identification         <src>static String dataTypeId();</src>
00280 //       This should return the (unique) name of the class, thus
00281 //       when T is templated in its turn, the name should contain the
00282 //       template argument name.
00283 // </templating>
00284 
00285 
00286 template<class T>
00287 class VSCEngine : public VirtualColumnEngine,
00288                   public VirtualScalarColumn<T>
00289 {
00290   //# Make members of parent class known.
00291 public:
00292   using VirtualScalarColumn<T>::dataTypeId;
00293 
00294 public:
00295     // The default constructor is required for reconstruction of the
00296     // engine when a table is read back.
00297     // It is also used to construct an engine, which does not check
00298     // the source column name.
00299     VSCEngine();
00300 
00301     // Construct an engine to handle a column with an arbitrary data type.
00302     // Later it will check if the source column name is correct.
00303     VSCEngine (const String& sourceColumnName);
00304 
00305     // Destructor is mandatory.
00306     ~VSCEngine();
00307 
00308     // Return the data manager type name.
00309     // This defaults to the data type ID followed by VSCEngine
00310     // (meaning Virtual Scalar Column Engine).
00311     String dataManagerType() const;
00312 
00313     // Get the name of the source column.
00314     const String& sourceColumnName() const
00315         { return sourceName_p; }
00316 
00317 protected:
00318 
00319     // Copy constructor is only used by clone().
00320     // (so it is made protected).
00321     VSCEngine (const VSCEngine<T>&);
00322 
00323 private:
00324     // Assignment is not needed and therefore forbidden
00325     // (so it is made private).
00326     VSCEngine<T>& operator= (const VSCEngine<T>&);
00327 
00328     // The column is in principle writable.
00329     // This does not mean it is actually writable, because that
00330     // depends on the fact if the table is writable.
00331     Bool isWritable() const;
00332 
00333     // Create the column object for the scalar column in this engine.
00334     // It will check if the given column name matches the source
00335     // column name. This assures that the engine is bound to the
00336     // correct column.
00337     DataManagerColumn* makeScalarColumn (const String& columnName,
00338                                          int dataType,
00339                                          const String& dataTypeID);
00340 
00341 
00342     //# Now define the data members.
00343     String         sourceName_p;           //# source column name
00344 };
00345 
00346 
00347 
00348 } //# NAMESPACE CASA - END
00349 
00350 #ifndef CASACORE_NO_AUTO_TEMPLATES
00351 #include <tables/Tables/VSCEngine.tcc>
00352 #endif //# CASACORE_NO_AUTO_TEMPLATES
00353 #endif