casa
$Rev:20696$
|
00001 //# ExprNodeSet.h: Classes representing a set in table select expression 00002 //# Copyright (C) 1997,2000,2001,2002,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: ExprNodeSet.h 21168 2012-01-04 08:11:03Z gervandiepen $ 00027 00028 #ifndef TABLES_EXPRNODESET_H 00029 #define TABLES_EXPRNODESET_H 00030 00031 //# Includes 00032 #include <tables/Tables/ExprNodeRep.h> 00033 #include <tables/Tables/ExprNodeArray.h> 00034 #include <casa/Containers/Block.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 //# Forward Declarations 00039 class TableExprNode; 00040 class IPosition; 00041 class Slicer; 00042 template<class T> class Vector; 00043 00044 00045 // <summary> 00046 // Class to hold the table expression nodes for an element in a set. 00047 // </summary> 00048 00049 // <use visibility=export> 00050 00051 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00052 // </reviewed> 00053 00054 // <prerequisite> 00055 //# Classes you should understand before using this one. 00056 // <li> TableExprNodeSet 00057 // <li> TableExprNodeRep 00058 // </prerequisite> 00059 00060 // <synopsis> 00061 // This class is used to assemble the table expression nodes 00062 // representing an element in a set. A set element can be of 3 types: 00063 // <ol> 00064 // <li> A single discrete value, which can be of any type. 00065 // It can be used for 3 purposes: 00066 // <br>- A function argument. 00067 // <br>- A single index in an array indexing operation. 00068 // <br>- A single value in a set (used with the IN operator). 00069 // This is in fact a bounded discrete interval (see below). 00070 // <li> A discrete interval consisting of start, end and increment. 00071 // Each of those has to be an int scalar. Increment defaults to 1. 00072 // It can be used for 2 purposes: 00073 // <br>- A slice in an array indexing operation. In that case start 00074 // defaults to the beginning of the dimension and end defaults to the end. 00075 // <br>- A discrete interval in a set. Start has to be given. 00076 // When end is not given, the result is an unbounded discrete interval. 00077 // For a discrete interval, the type of start and end can also be 00078 // a datetime scalar. 00079 // <li> A continuous interval, which can only be used in a set. 00080 // It consists of a start and/or an end scalar value of type int, double, 00081 // datetime, or string. The interval can be open or closed on one or 00082 // both sides. 00083 // </ol> 00084 // Note the difference between a discrete and a continuous interval. 00085 // E.g. the discrete interval 2,6 consists of the five values 2,3,4,5,6. 00086 // The continuous interval 2,6 consists of all values between them. 00087 // <br>Further note that a bounded discrete interval is automatically 00088 // converted to a vector, which makes it possible to apply array 00089 // functions to it. 00090 // </synopsis> 00091 00092 class TableExprNodeSetElem : public TableExprNodeRep 00093 { 00094 public: 00095 // Create the object for a single expression node. 00096 explicit TableExprNodeSetElem (const TableExprNode& node); 00097 00098 // Create the object for a discrete interval. 00099 // Each of the start, end, and incr pointers can be zero meaning 00100 // that they are not given (see the synopsis for an explanation). 00101 // Optionally the end is inclusive (C++ and Glish style) or exclusive 00102 // (Python style). 00103 TableExprNodeSetElem (const TableExprNode* start, 00104 const TableExprNode* end, 00105 const TableExprNode* incr, 00106 Bool isEndExcl = False); 00107 00108 // Create the object for a continuous bounded interval. It can be 00109 // open or closed on either side. 00110 TableExprNodeSetElem (Bool isLeftClosed, const TableExprNode& start, 00111 const TableExprNode& end, Bool isRightClosed); 00112 00113 // Create the object for a continuous left-bounded interval. 00114 TableExprNodeSetElem (Bool isLeftClosed, const TableExprNode& start); 00115 00116 // Create the object for a continuous right-bounded interval. 00117 TableExprNodeSetElem (const TableExprNode& end, Bool isRightClosed); 00118 00119 // Copy constructor (copy semantics). 00120 TableExprNodeSetElem (const TableExprNodeSetElem&); 00121 00122 ~TableExprNodeSetElem(); 00123 00124 // Show the node. 00125 void show (ostream& os, uInt indent) const; 00126 00127 // Is it a discrete set element. 00128 Bool isDiscrete() const; 00129 00130 // Is a single value given? 00131 Bool isSingle() const; 00132 00133 // Is the interval left or right closed? 00134 // <group> 00135 Bool isLeftClosed() const; 00136 Bool isRightClosed() const; 00137 // </group> 00138 00139 // Get the start, end or increment expression. 00140 // Note that the pointer returned can be zero indicating that that 00141 // value was not given. 00142 // <group> 00143 TableExprNodeRep* start() const; 00144 TableExprNodeRep* end() const; 00145 TableExprNodeRep* increment() const; 00146 // </group> 00147 00148 // Fill a vector with the value(s) from this element by appending them 00149 // at the end of the vector; the end is given by argument <src>cnt</src> 00150 // which gets incremented with the number of values appended. 00151 // This is used by the system to convert a set to a vector. 00152 // <group> 00153 void fillVector (Vector<Bool>& vec, uInt& cnt, 00154 const TableExprId& id) const; 00155 void fillVector (Vector<Int64>& vec, uInt& cnt, 00156 const TableExprId& id) const; 00157 void fillVector (Vector<Double>& vec, uInt& cnt, 00158 const TableExprId& id) const; 00159 void fillVector (Vector<DComplex>& vec, uInt& cnt, 00160 const TableExprId& id) const; 00161 void fillVector (Vector<String>& vec, uInt& cnt, 00162 const TableExprId& id) const; 00163 void fillVector (Vector<MVTime>& vec, uInt& cnt, 00164 const TableExprId& id) const; 00165 // </group> 00166 00167 // Set a flag in the match output array if the corresponding element 00168 // in the value array is included in this set element. 00169 // This is used by the system to implement the IN operator. 00170 // <br>Note that it does NOT set match values to False; it is assumed they 00171 // are initialized that way. 00172 // <group> 00173 void matchBool (Bool* match, const Bool* value, uInt nval, 00174 const TableExprId& id) const; 00175 void matchInt (Bool* match, const Int64* value, uInt nval, 00176 const TableExprId& id) const; 00177 void matchDouble (Bool* match, const Double* value, uInt nval, 00178 const TableExprId& id) const; 00179 void matchDComplex (Bool* match, const DComplex* value, uInt nval, 00180 const TableExprId& id) const; 00181 void matchString (Bool* match, const String* value, uInt nval, 00182 const TableExprId& id) const; 00183 void matchDate (Bool* match, const MVTime* value, uInt nval, 00184 const TableExprId& id) const; 00185 // </group> 00186 00187 // Evaluate the element for the given row and construct a new 00188 // (constant) element from it. 00189 // This is used by the system to implement a set in a GIVING clause. 00190 TableExprNodeSetElem* evaluate (const TableExprId& id) const; 00191 00192 // Get the table of a node and check if the children use the same table. 00193 void checkTable(); 00194 00195 // Let a set node convert itself to the given unit. 00196 virtual void adaptSetUnits (const Unit&); 00197 00198 private: 00199 // A copy of a TableExprNodeSetElem cannot be made. 00200 TableExprNodeSetElem& operator= (const TableExprNodeSetElem&); 00201 00202 // Construct an element from the given parts and take over their pointers. 00203 // It is used by evaluate to construct an element in a rather cheap way. 00204 TableExprNodeSetElem (const TableExprNodeSetElem& that, 00205 TableExprNodeRep* start, TableExprNodeRep* end, 00206 TableExprNodeRep* incr); 00207 00208 // Setup the object for a continuous interval. 00209 void setup (Bool isLeftClosed, const TableExprNode* start, 00210 const TableExprNode* end, Bool isRightClosed); 00211 00212 00213 TableExprNodeRep* itsStart; 00214 TableExprNodeRep* itsEnd; 00215 TableExprNodeRep* itsIncr; 00216 Bool itsEndExcl; 00217 Bool itsLeftClosed; 00218 Bool itsRightClosed; 00219 Bool itsDiscrete; 00220 Bool itsSingle; 00221 }; 00222 00223 00224 00225 inline Bool TableExprNodeSetElem::isDiscrete() const 00226 { 00227 return itsDiscrete; 00228 } 00229 inline Bool TableExprNodeSetElem::isSingle() const 00230 { 00231 return itsSingle; 00232 } 00233 inline Bool TableExprNodeSetElem::isLeftClosed() const 00234 { 00235 return itsLeftClosed; 00236 } 00237 inline Bool TableExprNodeSetElem::isRightClosed() const 00238 { 00239 return itsRightClosed; 00240 } 00241 inline TableExprNodeRep* TableExprNodeSetElem::start() const 00242 { 00243 return itsStart; 00244 } 00245 inline TableExprNodeRep* TableExprNodeSetElem::end() const 00246 { 00247 return itsEnd; 00248 } 00249 inline TableExprNodeRep* TableExprNodeSetElem::increment() const 00250 { 00251 return itsIncr; 00252 } 00253 00254 00255 00256 // <summary> 00257 // Class to hold multiple table expression nodes. 00258 // </summary> 00259 00260 // <use visibility=export> 00261 00262 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00263 // </reviewed> 00264 00265 // <prerequisite> 00266 //# Classes you should understand before using this one. 00267 // <li> TableExprNode 00268 // <li> TableExprNodeRep 00269 // <li> TableExprNodeBinary 00270 // </prerequisite> 00271 00272 // <synopsis> 00273 // This class is used to assemble several table expression nodes. 00274 // It is used for 3 purposes: 00275 // <ol> 00276 // <li> To hold the arguments of a function. 00277 // All set elements must be single. 00278 // <li> To hold the variables of an index for an array slice. 00279 // All set elements must be of type int scalar and they must 00280 // represent a discrete interval (which includes single). 00281 // <li> To hold the elements of a set used with the IN operator. 00282 // All set elements must be scalars of any type. 00283 // </ol> 00284 // The type of all set elements has to be the same. 00285 // The set consists of 00286 // <linkto class=TableExprNodeSetElem>TableExprNodeSetElem</linkto> 00287 // elements. The <src>add</src> function has to be used to 00288 // add an element to the set. 00289 // <p> 00290 // It is possible to construct the object directly from an 00291 // <linkto class=IPosition>IPosition</linkto> object. 00292 // In that case all elements are single. 00293 // Furthermore it is possible to construct it directly from a 00294 // <linkto class=Slicer>Slicer</linkto> object. 00295 // In that case all elements represent a discrete interval. 00296 // </synopsis> 00297 00298 class TableExprNodeSet : public TableExprNodeRep 00299 { 00300 public: 00301 // Construct an empty set. 00302 TableExprNodeSet(); 00303 00304 // Construct from an <src>IPosition</src>. 00305 // The number of elements in the set is the number of elements 00306 // in the <src>IPosition</src>. All set elements are single values. 00307 TableExprNodeSet (const IPosition&); 00308 00309 // Construct from a <src>Slicer</src>. 00310 // The number of elements in the set is the dimensionality 00311 // of the <src>Slicer</src>. All set elements are discrete intervals. 00312 // Their start and/or end is undefined if it is was not defined 00313 // (i.e. Slicer::MimicSource used) in the <src>Slicer</src> object. 00314 TableExprNodeSet (const Slicer&); 00315 00316 // Construct a set with n*set.nelements() elements where n is the number 00317 // of rows. 00318 // Element i is constructed by evaluating the input element 00319 // for row rownr[i]. 00320 TableExprNodeSet (const Vector<uInt>& rownrs, const TableExprNodeSet&); 00321 00322 TableExprNodeSet(const TableExprNodeSet&); 00323 00324 ~TableExprNodeSet(); 00325 00326 // Add an element to the set. 00327 void add (const TableExprNodeSetElem&); 00328 00329 // Show the node. 00330 void show (ostream& os, uInt indent) const; 00331 00332 // Check if the data type of the set elements are the same. 00333 // If not, an exception is thrown. 00334 //# Note that if itsCheckTypes is set, the data types are already 00335 //# known to be equal. 00336 void checkEqualDataTypes() const; 00337 00338 // Contains the set only single elements? 00339 // Single means that only single values are given (thus no end nor incr). 00340 Bool isSingle() const; 00341 00342 // Contains the set only discrete elements? 00343 // Discrete means that no continuous ranges are given, but discrete 00344 // ranges (using :) are possible. 00345 Bool isDiscrete() const; 00346 00347 // Is the set fully bounded (discrete and no undefined end values)? 00348 Bool isBounded() const; 00349 00350 // Get the number of elements. 00351 uInt nelements() const; 00352 00353 // Get the i-th element. 00354 const TableExprNodeSetElem& operator[] (uInt index) const; 00355 00356 // Contains the set array values? 00357 Bool hasArrays() const; 00358 00359 // Try to convert the set to an array. 00360 // If not possible, a copy of the set is returned. 00361 TableExprNodeRep* setOrArray() const; 00362 00363 // Convert the const set to an array. 00364 TableExprNodeRep* toArray() const; 00365 00366 // Get an array value for this bounded set in the given row. 00367 // <group> 00368 virtual Array<Bool> getArrayBool (const TableExprId& id); 00369 virtual Array<Int64> getArrayInt (const TableExprId& id); 00370 virtual Array<Double> getArrayDouble (const TableExprId& id); 00371 virtual Array<DComplex> getArrayDComplex (const TableExprId& id); 00372 virtual Array<String> getArrayString (const TableExprId& id); 00373 virtual Array<MVTime> getArrayDate (const TableExprId& id); 00374 // </group> 00375 00376 // Does a value occur in the set? 00377 // <group> 00378 virtual Bool hasBool (const TableExprId& id, Bool value); 00379 virtual Bool hasInt (const TableExprId& id, Int64 value); 00380 virtual Bool hasDouble (const TableExprId& id, Double value); 00381 virtual Bool hasDComplex (const TableExprId& id, const DComplex& value); 00382 virtual Bool hasString (const TableExprId& id, const String& value); 00383 virtual Bool hasDate (const TableExprId& id, const MVTime& value); 00384 virtual Array<Bool> hasArrayBool (const TableExprId& id, 00385 const Array<Bool>& value); 00386 virtual Array<Bool> hasArrayInt (const TableExprId& id, 00387 const Array<Int64>& value); 00388 virtual Array<Bool> hasArrayDouble (const TableExprId& id, 00389 const Array<Double>& value); 00390 virtual Array<Bool> hasArrayDComplex (const TableExprId& id, 00391 const Array<DComplex>& value); 00392 virtual Array<Bool> hasArrayString (const TableExprId& id, 00393 const Array<String>& value); 00394 virtual Array<Bool> hasArrayDate (const TableExprId& id, 00395 const Array<MVTime>& value); 00396 // </group> 00397 00398 // Let a set node convert itself to the given unit. 00399 virtual void adaptSetUnits (const Unit&); 00400 00401 private: 00402 // A copy of a TableExprNodeSet cannot be made. 00403 TableExprNodeSet& operator= (const TableExprNodeSet&); 00404 00405 // Delete all set elements in itsElems. 00406 void deleteElems(); 00407 00408 // Convert a bounded set to an Array. 00409 // <group> 00410 Array<Bool> toArrayBool (const TableExprId& id) const; 00411 Array<Int64> toArrayInt (const TableExprId& id) const; 00412 Array<Double> toArrayDouble (const TableExprId& id) const; 00413 Array<DComplex> toArrayDComplex (const TableExprId& id) const; 00414 Array<String> toArrayString (const TableExprId& id) const; 00415 Array<MVTime> toArrayDate (const TableExprId& id) const; 00416 // </group> 00417 00418 // Sort and combine intervals. 00419 // <group> 00420 void combineIntIntervals(); 00421 void combineDoubleIntervals(); 00422 void combineDateIntervals(); 00423 // </group> 00424 00425 // Define the functions to find a double, which depend on open/closed-ness. 00426 // In this way a test on open/closed is done only once. 00427 // <group> 00428 typedef Bool (TableExprNodeSet::* FindFuncPtr) (Double value); 00429 Bool findOpenOpen (Double value); 00430 Bool findOpenClosed (Double value); 00431 Bool findClosedOpen (Double value); 00432 Bool findClosedClosed (Double value); 00433 void setFindFunc (Bool isLeftClosed, Bool isRightClosed); 00434 // </group> 00435 00436 PtrBlock<TableExprNodeSetElem*> itsElems; 00437 Bool itsSingle; 00438 Bool itsDiscrete; 00439 Bool itsBounded; //# Set is discrete and all starts/ends are defined 00440 Bool itsCheckTypes; //# True = checking data types is not needed 00441 Bool itsAllIntervals; //# True = all elements are const intervals (sorted) 00442 Block<Double> itsStart; //# Start values of const intervals 00443 Block<Double> itsEnd; //# End values of const intervals 00444 FindFuncPtr itsFindFunc; //# Function to find a matching const interval 00445 }; 00446 00447 00448 inline Bool TableExprNodeSet::isSingle() const 00449 { 00450 return itsSingle; 00451 } 00452 inline Bool TableExprNodeSet::isDiscrete() const 00453 { 00454 return itsDiscrete; 00455 } 00456 inline Bool TableExprNodeSet::isBounded() const 00457 { 00458 return itsBounded; 00459 } 00460 inline uInt TableExprNodeSet::nelements() const 00461 { 00462 return itsElems.nelements(); 00463 } 00464 inline const TableExprNodeSetElem& 00465 TableExprNodeSet::operator[] (uInt index) const 00466 { 00467 return *(itsElems[index]); 00468 } 00469 00470 00471 00472 00473 } //# NAMESPACE CASA - END 00474 00475 #endif