casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ExprNodeSet.h
Go to the documentation of this file.
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