casa
$Rev:20696$
|
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