00001 //# ArrayColumn.h: access to an array table column with arbitrary data type 00002 //# Copyright (C) 1994,1995,1996,1997,1998,2001 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: ArrayColumn.h 21521 2014-12-10 08:06:42Z gervandiepen $ 00027 00028 #ifndef TABLES_ARRAYCOLUMN_H 00029 #define TABLES_ARRAYCOLUMN_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/casa/Arrays/Vector.h> 00035 #include <casacore/tables/Tables/TableColumn.h> 00036 #include <casacore/tables/Tables/TableError.h> 00037 00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00039 00040 //# Forward Declarations 00041 class RefRows; 00042 template<class T> class Array; 00043 template<class T> class BaseSlicesFunctor; 00044 class IPosition; 00045 class Slice; 00046 class Slicer; 00047 class ColumnSlicer; 00048 class String; 00049 00050 00051 // <summary> 00052 // Read and write access to an array table column with arbitrary data type 00053 // </summary> 00054 00055 // <use visibility=export> 00056 00057 // <reviewed reviewer="dschieb" date="1994/08/10" tests="none"> 00058 // </reviewed> 00059 00060 // <prerequisite> 00061 // <li> Table 00062 // <li> TableColumn 00063 // </prerequisite> 00064 00065 // <etymology> 00066 // ArrayColumn<T> gives read and write access to an column in a table 00067 // containing an array with data type T. 00068 // </etymology> 00069 00070 // <synopsis> 00071 // The class ArrayColumn allows readonly access to a column 00072 // containing arrays with an arbitrary data type. It can handle direct 00073 // as well as indirect arrays. 00074 // It is possible to get the data in an individual cell (i.e. table row); 00075 // either the whole array or a slice of the array can be accessed. 00076 // It is also possible to get the column as a whole if the arrays 00077 // in all cells of the column have the same shape (which is always true 00078 // for direct arrays). As in the case of individual cells it is possible 00079 // to get the entire arrays or a slice of the arrays. 00080 // 00081 // A default constructor is defined to allow construction of an array 00082 // of ArrayColumn objects. However, this constructs an object not 00083 // referencing a column. Functions like get, etc. will fail (i.e. result 00084 // in a segmentation fault) when used on such objects. The functions 00085 // isNull and throwIfNull can be used to test on this. 00086 // The functions attach and reference can fill in the object. 00087 // 00088 // The assignment operator is not defined for this class, because it was 00089 // felt it would be too confusing. Instead the function reference can 00090 // be used to do assignment with reference semantics. An assignment 00091 // with copy semantics makes no sense for a readonly column. 00092 // </synopsis> 00093 00094 // <templating arg=T> 00095 // <li> Default constructor 00096 // <li> Copy constructor 00097 // <li> Assignment operator 00098 // </templating> 00099 00100 // <example> 00101 // See module <linkto module="Tables#open">Tables</linkto>. 00102 // </example> 00103 00104 00105 template<class T> 00106 class ArrayColumn : public TableColumn 00107 { 00108 public: 00109 00110 // The default constructor creates a null object, i.e. it 00111 // does not reference a table column. 00112 // The sole purpose of this constructor is to allow construction 00113 // of an array of ArrayColumn objects. 00114 // The functions reference and attach can be used to make a null object 00115 // reference a column. 00116 // Note that get functions, etc. will cause a segmentation fault 00117 // when operating on a null object. It was felt it was too expensive 00118 // to test on null over and over again. The user should use the isNull 00119 // or throwIfNull function in case of doubt. 00120 ArrayColumn(); 00121 00122 // Construct for the given column in the given table. 00123 ArrayColumn (const Table&, const String& columnName); 00124 00125 // Construct from the given table column. 00126 // This constructor is useful if first a table column was constructed, 00127 // its type is determined and thereafter used to construct the 00128 // correct column object. 00129 explicit ArrayColumn (const TableColumn&); 00130 00131 // Copy constructor (reference semantics). 00132 ArrayColumn (const ArrayColumn<T>&); 00133 00134 ~ArrayColumn(); 00135 00136 // Clone the object. 00137 virtual TableColumn* clone() const; 00138 00139 // Assignment uses reference semantics, thus works the same 00140 // as function reference. 00141 ArrayColumn<T>& operator= (const ArrayColumn<T>&); 00142 00143 // Change the reference to another column. 00144 // This is in fact an assignment operator with reference semantics. 00145 // It removes the reference to the current column and creates 00146 // a reference to the column referenced in the other object. 00147 // It will handle null objects correctly. 00148 void reference (const ArrayColumn<T>&); 00149 00150 // Attach a column to the object. 00151 // This is in fact only a shorthand for 00152 // <br><src> reference (ArrayColumn<T> (table, columnName)); </src> 00153 void attach (const Table& table, const String& columnName) 00154 { reference (ArrayColumn<T> (table, columnName)); } 00155 00156 // Get the #dimensions of an array in a particular cell. 00157 // If the cell does not contain an array, 0 is returned. 00158 // Use the function isDefined to test if the cell contains an array. 00159 uInt ndim (uInt rownr) const 00160 { TABLECOLUMNCHECKROW(rownr); return baseColPtr_p->ndim (rownr); } 00161 00162 // Get the shape of an array in a particular cell. 00163 // If the cell does not contain an array, a 0-dim shape is returned. 00164 // Use the function isDefined to test if the cell contains an array. 00165 IPosition shape (uInt rownr) const 00166 { TABLECOLUMNCHECKROW(rownr); return baseColPtr_p->shape (rownr); } 00167 00168 // Get the array value in a particular cell (i.e. table row). 00169 // The row numbers count from 0 until #rows-1. 00170 // <group> 00171 // According to the assignment rules of class Array, the destination 00172 // array must be empty or its shape must conform the table array shape. 00173 // However, if the resize flag is set the destination array will be 00174 // resized if not conforming. 00175 void get (uInt rownr, Array<T>& array, Bool resize = False) const; 00176 Array<T> get (uInt rownr) const; 00177 Array<T> operator() (uInt rownr) const; 00178 // </group> 00179 00180 // Get a slice of an N-dimensional array in a particular cell 00181 // (i.e. table row). 00182 // The row numbers count from 0 until #rows-1. 00183 // The dimensionality of the slice must match the dimensionality 00184 // of the table array and the slice definition should not exceed 00185 // the shape of the table array. 00186 // <group> 00187 // According to the assignment rules of class Array, the destination 00188 // array must be empty or its shape must conform the shape of the 00189 // table array slice. 00190 // However, if the resize flag is set the destination array will be 00191 // resized if not conforming. 00192 void getSlice (uInt rownr, const Slicer& arraySection, Array<T>& array, 00193 Bool resize = False) const; 00194 Array<T> getSlice (uInt rownr, const Slicer& arraySection) const; 00195 // </group> 00196 00197 // Get an irregular slice of an N-dimensional array in a particular cell 00198 // (i.e. table row) as given by the vectors of Slice objects. 00199 // The outer vector represents the array axes. 00200 // A missing or empty axis means the entire axis. 00201 // The inner vector represents the slices to take for each axis. 00202 // For example, to get slices from 2-dim arrays: 00203 // <srcblock> 00204 // Vector<Vector<Slice> > slices(2); // 2-dim 00205 // slices[1].resize (3); // 3 slices in 2nd dim 00206 // slices[1][0] = Slice(100,20); 00207 // slices[1][1] = Slice(200,18); 00208 // slices[1][2] = Slice(538,30,2); 00209 // // Get data. Vector of first axis is empty, thus entire axis is read. 00210 // Array<Complex> data = dataCol.getColumn (slices); 00211 // </srcblock> 00212 // If the column contains n-dim arrays, the resulting array is (n+1)-dim. 00213 // with the last dimension representing the number of rows and the 00214 // other dimensions representing the shape of the slice. 00215 // The arrays in the column must have the same shape in all cells. 00216 // <group> 00217 // According to the assignment rules of class Array, the destination 00218 // array must be empty or its shape must conform the resulting (n+1)-dim 00219 // array. 00220 // However, if the resize flag is set the destination array will be 00221 // resized if not conforming. 00222 void getSlice (uInt rownr, 00223 const Vector<Vector<Slice> >& arraySlices, 00224 Array<T>& arr, Bool resize = False) const; 00225 Array<T> getSlice (uInt rownr, 00226 const Vector<Vector<Slice> >& arraySlices) const; 00227 // </group> 00228 00229 // Get the array of all values in a column. 00230 // If the column contains n-dim arrays, the resulting array is (n+1)-dim 00231 // with the last dimension representing the number of rows. 00232 // The arrays in the column must have the same shape in all cells. 00233 // <group> 00234 // According to the assignment rules of class Array, the destination 00235 // array must be empty or its shape must conform the resulting (n+1)-dim 00236 // array. 00237 // However, if the resize flag is set the destination array will be 00238 // resized if not conforming. 00239 void getColumn (Array<T>& array, Bool resize = False) const; 00240 Array<T> getColumn() const; 00241 // </group> 00242 00243 // Get regular slices from all arrays in the column. 00244 // If the column contains n-dim arrays, the resulting array is (n+1)-dim. 00245 // with the last dimension representing the number of rows and the 00246 // other dimensions representing the shape of the slice. 00247 // The arrays in the column must have the same shape in all cells. 00248 // <group> 00249 // According to the assignment rules of class Array, the destination 00250 // array must be empty or its shape must conform the resulting (n+1)-dim 00251 // array. 00252 // However, if the resize flag is set the destination array will be 00253 // resized if not conforming. 00254 void getColumn (const Slicer& arraySection, Array<T>& array, 00255 Bool resize = False) const; 00256 Array<T> getColumn (const Slicer& arraySection) const; 00257 // </group> 00258 00259 // Get irregular slices from all arrays in the column as given by the 00260 // vectors of Slice objects. The outer vector represents the array axes. 00261 // A missing or empty axis means the entire axis. 00262 // The inner vector represents the slices to take for each axis. 00263 // For example, to get slices from 2-dim arrays: 00264 // <srcblock> 00265 // Vector<Vector<Slice> > slices(2); // 2-dim 00266 // slices[1].resize (3); // 3 slices in 2nd dim 00267 // slices[1][0] = Slice(100,20); 00268 // slices[1][1] = Slice(200,18); 00269 // slices[1][2] = Slice(538,30,2); 00270 // // Get data. Vector of first axis is empty, thus entire axis is read. 00271 // Array<Complex> data = dataCol.getColumn (slices); 00272 // </srcblock> 00273 // If the column contains n-dim arrays, the resulting array is (n+1)-dim. 00274 // with the last dimension representing the number of rows and the 00275 // other dimensions representing the shape of the slice. 00276 // The arrays in the column must have the same shape in all cells. 00277 // <group> 00278 // According to the assignment rules of class Array, the destination 00279 // array must be empty or its shape must conform the resulting (n+1)-dim 00280 // array. 00281 // However, if the resize flag is set the destination array will be 00282 // resized if not conforming. 00283 void getColumn (const Vector<Vector<Slice> >& arraySection, Array<T>& array, 00284 Bool resize = False) const; 00285 Array<T> getColumn (const Vector<Vector<Slice> >& arraySection) const; 00286 // </group> 00287 00288 // Get the array of some values in a column. 00289 // The Slicer object can be used to specify start, end (or length), 00290 // and stride of the rows to get. 00291 // If the column contains n-dim arrays, the resulting array is (n+1)-dim 00292 // with the last dimension representing the number of rows in the slicer. 00293 // The arrays in the column must have the same shape in all those cells. 00294 // According to the assignment rules of class Array, the destination 00295 // array must be empty or its shape must conform the resulting (n+1)-dim 00296 // array. 00297 // However, if the resize flag is set the destination array will be 00298 // resized if not conforming. 00299 // <group> 00300 void getColumnRange (const Slicer& rowRange, Array<T>& arr, 00301 Bool resize = False) const; 00302 Array<T> getColumnRange (const Slicer& rowRange) const; 00303 void getColumnCells (const RefRows& rownrs, Array<T>& arr, 00304 Bool resize = False) const; 00305 Array<T> getColumnCells (const RefRows& rownrs) const; 00306 // </group> 00307 00308 // Get slices from some arrays in a column. 00309 // The first Slicer object can be used to specify start, end (or length), 00310 // and stride of the rows to get. The second Slicer object can be 00311 // used to specify the slice to take from each array. 00312 // If the column contains n-dim arrays, the resulting array is (n+1)-dim 00313 // with the last dimension representing the number of rows in the slicer. 00314 // The arrays in the column must have the same shape in all those cells. 00315 // According to the assignment rules of class Array, the destination 00316 // array must be empty or its shape must conform the resulting (n+1)-dim 00317 // array. 00318 // However, if the resize flag is set the destination array will be 00319 // resized if not conforming. 00320 // <group> 00321 void getColumnRange (const Slicer& rowRange, 00322 const Slicer& arraySection, Array<T>& arr, 00323 Bool resize = False) const; 00324 Array<T> getColumnRange (const Slicer& rowRange, 00325 const Slicer& arraySection) const; 00326 void getColumnCells (const RefRows& rownrs, 00327 const Slicer& arraySection, Array<T>& arr, 00328 Bool resize = False) const; 00329 Array<T> getColumnCells (const RefRows& rownrs, 00330 const Slicer& arraySection) const; 00331 // </group> 00332 00333 // Similar to getColumn (arraySlices, arr, resize) except it 00334 // gets the slices for the given rows instead of all rows. 00335 void getColumnCells (const RefRows& rows, 00336 const ColumnSlicer & slicerSet, 00337 Array<T>& destination, 00338 Bool resize = False) const; 00339 00340 // The get() function like above which does not check shapes, etc. 00341 // It is faster and can be used for performance reasons if one 00342 // knows for sure that the arguments are correct. 00343 // E.g. it is used internally in virtual column engines. 00344 void baseGet (uInt rownr, Array<T>& array) const 00345 { baseColPtr_p->get (rownr, &array); } 00346 00347 // Set the shape of the array in the given row. 00348 // Setting the shape is needed if the array is put in slices, 00349 // otherwise the table system would not know the shape. 00350 // <group> 00351 void setShape (uInt rownr, const IPosition& shape); 00352 00353 // Try to store the array in a tiled way using the given tile shape. 00354 void setShape (uInt rownr, const IPosition& shape, 00355 const IPosition& tileShape); 00356 // </group> 00357 00358 // Put the array in a particular cell (i.e. table row). 00359 // The row numbers count from 0 until #rows-1. 00360 // If the shape of the table array in that cell has not already been 00361 // defined, it will be defined implicitly. 00362 void put (uInt rownr, const Array<T>& array); 00363 00364 // Copy the value of a cell of that column to a cell of this column. 00365 // This function uses a generic TableColumn object as input. 00366 // The data types of both columns must be the same, otherwise an 00367 // exception is thrown. 00368 // <group> 00369 // Use the same row numbers for both cells. 00370 void put (uInt rownr, const TableColumn& that, 00371 Bool preserveTileShape=False) 00372 { put (rownr, that, rownr, preserveTileShape); } 00373 // Use possibly different row numbers for that (i.e. input) and 00374 // and this (i.e. output) cell. 00375 void put (uInt thisRownr, const TableColumn& that, uInt thatRownr, 00376 Bool preserveTileShape=False); 00377 // </group> 00378 00379 // Put into a slice of an N-dimensional array in a particular cell. 00380 // The row numbers count from 0 until #rows-1. 00381 // The shape of the table array must have been defined. 00382 // The dimensionality of the slice must match the dimensionality 00383 // of the table array and the slice definition should not exceed 00384 // the shape of the table array. 00385 void putSlice (uInt rownr, const Slicer& arraySection, 00386 const Array<T>& array); 00387 00388 void putSlice (uInt rownr, const Vector<Vector<Slice> >& arraySlices, 00389 const Array<T>& arr); 00390 00391 // Put the array of all values in the column. 00392 // If the column contains n-dim arrays, the source array must be (n+1)-dim 00393 // with the last dimension representing the number of rows. 00394 void putColumn (const Array<T>& array); 00395 00396 // Put into subsections of the table arrays in the entire column. 00397 // If the column contains n-dim arrays, the source array is (n+1)-dim 00398 // with the last dimension representing the number of rows and 00399 // other dimensions representing the shape of the slice. 00400 // The dimensionality of the slice must match the dimensionality 00401 // of the table array, thus must be n-dim. Also the slice definition 00402 // should not exceed the shape of the table arrays. 00403 void putColumn (const Slicer& arraySection, const Array<T>& array); 00404 00405 void putColumn (const Vector<Vector<Slice> >& arraySlices, 00406 const Array<T>& arr); 00407 00408 // Put the array of some values in the column. 00409 // The Slicer object can be used to specify start, end (or length), 00410 // and stride of the rows to put. 00411 // If the column contains n-dim arrays, the source array must be (n+1)-dim 00412 // with the last dimension representing the number of rows in the slicer. 00413 // <group> 00414 void putColumnRange (const Slicer& rowRange, const Array<T>& arr); 00415 void putColumnCells (const RefRows& rownrs, const Array<T>& arr); 00416 // </group> 00417 00418 // Put into subsection of the table arrays in some rows of the column. 00419 // The first Slicer object can be used to specify start, end (or length), 00420 // and stride of the rows to put. The second Slicer object can be 00421 // used to specify the slice to take from each array. 00422 // If the column contains n-dim arrays, the source array must be (n+1)-dim 00423 // with the last dimension representing the number of rows in the slicer. 00424 // <group> 00425 void putColumnRange (const Slicer& rowRange, 00426 const Slicer& arraySection, const Array<T>& arr); 00427 void putColumnCells (const RefRows& rownrs, 00428 const Slicer& arraySection, const Array<T>& arr); 00429 // </group> 00430 00431 // Same as putColumn(arraySlices, arr) except that it puts for the given 00432 // rows instead of all rows. 00433 // <group> 00434 void putColumnCells (const RefRows& rows, 00435 const Vector<Vector<Slice> >& arraySlices, 00436 const Array<T>& arr); 00437 void putSliceFromRows (const RefRows& rows, 00438 const Vector<Vector<Slice> >& arraySlices, 00439 const Array<T>& source) 00440 { putColumnCells (rows, arraySlices, source); } 00441 void putColumnCells (const RefRows& rows, 00442 const ColumnSlicer & columnSlicer, 00443 const Array<T>& source); 00444 // </group> 00445 00446 // Put the same value in all cells of the column. 00447 void fillColumn (const Array<T>& value); 00448 00449 // Put the contents of a column with the same data type into this column. 00450 // To put the contents of a column with a different data type into 00451 // this column, the function TableColumn::putColumn can be used 00452 // (provided the data type promotion is possible). 00453 // In fact, this function is an assignment operator with copy semantics. 00454 void putColumn (const ArrayColumn<T>& that); 00455 00456 // The put() function like above which does not check shapes, etc. 00457 // It is faster and can be used for performance reasons if one 00458 // knows for sure that the arguments are correct. 00459 // E.g. it is used internally in virtual column engines. 00460 void basePut (uInt rownr, const Array<T>& array) 00461 { baseColPtr_p->put (rownr, &array); } 00462 00463 private: 00464 // Check if the data type matches the column data type. 00465 void checkDataType() const; 00466 00467 // Check the shape of the array. If the array is empty or if 00468 // <src>resize=True</src>, the array is resized if needed. 00469 // An exception is thrown if not conforming. 00470 void checkShape (const IPosition& shp, 00471 Array<T>& arr, Bool resize, 00472 const String& where) const; 00473 void checkShape (const IPosition& shp, 00474 Array<T>& arr, Bool resize, 00475 const char * where) const; 00476 00477 protected: 00478 // A common function used by all functions that can get or put irregular 00479 // array slices. The functor performs the get or put operation. 00480 void handleSlices (const Vector<Vector<Slice> >& slices, 00481 BaseSlicesFunctor<T>& functor, 00482 const Slicer& slicer, 00483 IPosition& arrEnd, 00484 Array<T>& array) const; 00485 00486 // Keep switches to determine if a slice or an entire column can 00487 // be accessed or the change of an array can be changed. 00488 // True = yes; False = no. 00489 mutable Bool canAccessSlice_p; 00490 mutable Bool canAccessColumn_p; 00491 mutable Bool canAccessColumnSlice_p; 00492 // Keep switches to know if access knowledge is permanent or has 00493 // to be asked again the next time. 00494 mutable Bool reaskAccessSlice_p; 00495 mutable Bool reaskAccessColumn_p; 00496 mutable Bool reaskAccessColumnSlice_p; 00497 }; 00498 00499 class ColumnSlicer { 00500 00501 public: 00502 00503 // Create a ColumnSlicer for use in one of the overloads of ArrayColumn::getColumnCells. That method 00504 // takes a potentially complex select of data out of a column cell (e.g., multiple slices along each 00505 // axis) and then puts them into a selection of a destination array. This is most easily represnted 00506 // as a set of source,destination slicers where one is applied to the cell and the other to the 00507 // destination array. 00508 // 00509 // The shape paramter is the shape of the destination excluding the row axis. 00510 // 00511 // 00512 // 00513 // The Slicer objects provided (by pointer) will be owned by the ColumnSlicer object which will 00514 // delete them in its destructor. 00515 00516 00517 ColumnSlicer (const IPosition & shape, Vector<Slicer *> dataSlicers, Vector<Slicer *> destinationSlicers) 00518 : dataSlicers_p (dataSlicers), 00519 destinationSlicers_p (destinationSlicers), 00520 shape_p (shape) 00521 { 00522 String message = validateParameters (); 00523 if (! message.empty()){ 00524 00525 freeSlicers(); // Call gave them to us; set them free. 00526 00527 throw AipsError (String ("ColumnSlicer (ctor):: ") + message); 00528 } 00529 } 00530 00531 // Kill off the Slicer objects. 00532 00533 ~ColumnSlicer (){ 00534 00535 freeSlicers(); 00536 } 00537 00538 // Accessor that returns the dataSlicers. 00539 00540 const Vector <Slicer *> & getDataSlicers () const 00541 { 00542 return dataSlicers_p; 00543 } 00544 00545 // Accessor that returns the desintation slicers 00546 00547 const Vector <Slicer *> & getDestinationSlicers () const 00548 { 00549 return destinationSlicers_p; 00550 } 00551 00552 // Accessor that returns the shape. 00553 00554 const IPosition & shape () const 00555 { 00556 return shape_p; 00557 } 00558 00559 private: 00560 00561 void freeSlicers () 00562 { 00563 // The two Vectors contain pointers to objects so they need to be freed. 00564 // They should have the same length normally, but during validation it's 00565 // possible that they have different lengths. 00566 00567 for (uInt i = 0; i < dataSlicers_p.size(); i++){ 00568 delete dataSlicers_p [i]; 00569 } 00570 00571 for (uInt i = 0; i < destinationSlicers_p.size(); i++){ 00572 delete destinationSlicers_p [i]; 00573 } 00574 } 00575 00576 String validateParameters () 00577 { 00578 // Validate the contruction parameters to see if they are consistent. 00579 00580 if (dataSlicers_p.size() != destinationSlicers_p.size()){ 00581 return String::format ("Number of data slicers (%d) and destination slicers (%d) " 00582 "must match", dataSlicers_p.size(), destinationSlicers_p.size()); 00583 } 00584 00585 if (dataSlicers_p.size() == 0){ 00586 return String::format ("At least one destination and one data slicer required."); 00587 } 00588 00589 for (uInt i = 0; i < dataSlicers_p.size(); i++){ 00590 00591 if (dataSlicers_p[i]->length() != destinationSlicers_p[i]->length()){ 00592 00593 return String::format ("Length of data slicer[%d] (%s) and " 00594 "destination slicer [%d] (%s) must be equal", 00595 i, dataSlicers_p[i]->length().toString().c_str(), 00596 i, destinationSlicers_p[i]->length().toString().c_str()); 00597 } 00598 } 00599 00600 return String(); 00601 } 00602 00603 Vector<Slicer *> dataSlicers_p; 00604 Vector<Slicer *> destinationSlicers_p; 00605 IPosition shape_p; 00606 }; 00607 00608 00609 //# Explicitly instantiate these templates in ArrayColumn_tmpl.cc 00610 #ifdef AIPS_CXX11 00611 extern template class ArrayColumn<Bool>; 00612 extern template class ArrayColumn<Char>; 00613 extern template class ArrayColumn<Short>; 00614 extern template class ArrayColumn<uShort>; 00615 extern template class ArrayColumn<Int>; 00616 extern template class ArrayColumn<uInt>; 00617 extern template class ArrayColumn<Float>; 00618 extern template class ArrayColumn<Double>; 00619 extern template class ArrayColumn<Complex>; 00620 extern template class ArrayColumn<DComplex>; 00621 extern template class ArrayColumn<String>; 00622 #endif 00623 00624 00625 } //# NAMESPACE CASACORE - END 00626 00627 00628 //# Make old name ROArrayColumn still available. 00629 #define ROArrayColumn ArrayColumn 00630 00631 00632 #ifndef CASACORE_NO_AUTO_TEMPLATES 00633 #include <casacore/tables/Tables/ArrayColumn.tcc> 00634 #endif //# CASACORE_NO_AUTO_TEMPLATES 00635 #endif