casacore
Loading...
Searching...
No Matches
RecordDesc.h
Go to the documentation of this file.
1//# RecordDesc.h: Description of the fields in a record object
2//# Copyright (C) 1995,1996,1998,2000,2001
3//# Associated Universities, Inc. Washington DC, USA.
4//#
5//# This library is free software; you can redistribute it and/or modify it
6//# under the terms of the GNU Library General Public License as published by
7//# the Free Software Foundation; either version 2 of the License, or (at your
8//# option) any later version.
9//#
10//# This library is distributed in the hope that it will be useful, but WITHOUT
11//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13//# License for more details.
14//#
15//# You should have received a copy of the GNU Library General Public License
16//# along with this library; if not, write to the Free Software Foundation,
17//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18//#
19//# Correspondence concerning AIPS++ should be addressed as follows:
20//# Internet email: aips2-request@nrao.edu.
21//# Postal address: AIPS++ Project Office
22//# National Radio Astronomy Observatory
23//# 520 Edgemont Road
24//# Charlottesville, VA 22903-2475 USA
25//#
26//#
27//# $Id$
28
29
30#ifndef CASA_RECORDDESC_H
31#define CASA_RECORDDESC_H
32
33
34//# Includes
35#include <casacore/casa/aips.h>
36#include <casacore/casa/Containers/RecordDescRep.h>
37#include <casacore/casa/Containers/RecordInterface.h>
38#include <casacore/casa/Utilities/COWPtr.h>
39#include <casacore/casa/iosfwd.h>
40
41namespace casacore { //# NAMESPACE CASACORE - BEGIN
42
43//# Forward Declarations
44class AipsIO;
45
46
47// <summary>
48// Description of the fields in a record object
49// </summary>
50
51// <use visibility=export>
52// <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecordDesc">
53// </reviewed>
54
55// <prerequisite>
56// <li> <linkto group="DataType.h#DataType">DataType</linkto>
57// <li> <linkto class="Record">Record</linkto>
58// </prerequisite>
59//
60// <etymology>
61// RecordStructure would perhaps have been the clearest possible name. However
62// it was decided to name it ``RecordDesc'' to use a compatible naming
63// convention with other classes in the system, such as TableDesc. This class
64// <em>Desc</em>ribes the structure of a Record.
65// </etymology>
66//
67// <synopsis>
68// RecordDesc describes the structure of <linkto class="Record">Record</linkto>
69// objects. A Record consists of a number of fields. A RecordDesc describes
70// those fields by assigning to each one:
71// <ul>
72// <li> A name for the field.
73// <li> A type from the <linkto group="DataType.h#DataType">DataType</linkto>
74// enum.
75// <li> A shape if the field is an array.
76// <li> A RecordDesc if the field is itself a Record (the Record is an
77// hierarchical structure).
78// </ul>
79// Only one field with a given name is allowed (although fields in subrecords
80// may have the same name as a field in a parent or child Record).
81//
82// Field indices are zero relative, i.e. they range from 0 to
83// <src>nfields()-1</src>.
84// </synopsis>
85//
86// <example>
87// See the example in the description of the
88// <linkto class="Record:example1">Record</linkto> class.
89// </example>
90//
91// <motivation>
92// It is useful to be able to create many new objects with the same structure
93// as some other, without necessarily cloning it by copying all the values.
94// A ``Description'' type is necessary to do this (e.g., shape for an Array).
95// </motivation>
96//
97//
98// <todo asof="1995/06/01">
99// <li> Should the strategy wrt. field names be changed (not used in
100// field description equality, must be unique at a given level?).
101// <li> Perhaps we should be able to more conveniently change the description
102// of an existing field.
103// </todo>
104
106{
107public:
108 // Writes/reads the RecordDesc to/from an output stream.
109 // <group name=io>
110 friend ostream& operator<< (ostream& os, const RecordDesc& desc);
111 friend AipsIO& operator<< (AipsIO& os, const RecordDesc& desc);
112 friend AipsIO& operator>> (AipsIO& os, RecordDesc& desc);
113 // </group>
114
115 // Create a description with no fields.
116 RecordDesc();
117
118 // Create a description which is a copy of other.
119 RecordDesc (const RecordDesc& other);
120
121 // Replace this description with other.
122 RecordDesc& operator= (const RecordDesc& other);
123
124 ~RecordDesc();
125
126 // Add scalar, array, sub-record, or table field.
127 // If of array type, the shape is set to [-1], which indicates a
128 // variable sized array.
129 // If of sub-record type, the sub-record is free format.
130 // Returns the number of fields in the description.
131 uInt addField (const String& fieldName, DataType dataType);
132
133 // Add an array field of the indicated type. The DataType is promoted
134 // from a scalar type to an array type if necessary, e.g.,
135 // <src>TpInt ->TpArrayInt</src>. Returns the number of fields in
136 // the description.
137 // A shape of [-1] indicates a variable shape.
138 uInt addField (const String& fieldName, DataType scalarOrArrayType,
139 const IPosition& shape);
140
141 // Add a Record field to the description. This allows hierarchical
142 // descriptions to be developed. Returns the number of fields in the
143 // description.
144 uInt addField (const String& fieldName, const RecordDesc& subDesc);
145
146 // Add a Table field to the description. The Table description has the
147 // given name. Returns the number of fields in the description.
148 // <br>
149 // When a table is put in a record field, it is checked if the name
150 // of its description matches this name. If this name is empty, it
151 // matches any table description.
152 // <note role=warning>
153 // Note that not all record types are able to instantiate a table field.
154 // E.g. <linkto class=TableRecord>TableRecord</linkto> can instantiate
155 // it, while <linkto class=Record>Record</linkto> cannot and throws an
156 // exception when a record description containing a table field is used.
157 // </note>
158 uInt addTable (const String& fieldName, const String& tableDescName);
159
160 // Get the comment for this field.
161 const String& comment (Int whichField) const;
162
163 // Set the comment for this field.
164 void setComment (Int whichField, const String& comment);
165
166 // Set the shape for this field.
167 // An exception will be thrown if the field is no array.
168 void setShape (Int whichField, const IPosition& shape);
169
170 // Merge a single field from other. If allowDuplicates is True, silently
171 // throw away fields if one with the same name and type already exists,
172 // otherwise an exception is thrown. Conflicting types always cause an
173 // exception. Returns the number of fields in the description.
174 uInt mergeField (const RecordDesc& other, Int whichFieldFromOther,
175 RecordInterface::DuplicatesFlag DuplicateAction
177
178 // Add all the fields from another RecordDesc to the current objects.
179 // It returns the new number of fields.
180 uInt merge (const RecordDesc& other,
181 RecordInterface::DuplicatesFlag DuplicateAction
183
184 // Remove the given field from the description.
185 // It returns the new number of fields.
186 uInt removeField (Int whichField);
187
188 // Rename the given field.
189 void renameField (const String& newName, Int whichField);
190
191 // Returns the index of the field named fieldName. Returns -1 if fieldName
192 // does not exist.
193 Int fieldNumber (const String& fieldName) const;
194
195 // Number of fields in the description.
196 uInt nfields() const;
197
198 // What is the type of the given field. Returns TpRecord if the field is
199 // a sub-Record.
200 DataType type (Int whichField) const;
201
202 // What is the name of the given field.
203 const String& name (Int whichField) const;
204
205 // Create a name for a field defined by index as *i (similar to glish).
206 // It takes care that the resulting name is unique by adding a suffix _j
207 // when needed.
208 String makeName (Int whichField) const;
209
210 // Make the given name unique by adding a suffix _j when needed.
211 // j is the minimal number needed to make it unique.
212 String uniqueName (const String& name) const;
213
214 // Returns True if whichField is an array.
215 Bool isArray (Int whichField) const;
216
217 // Returns True if whichField is a scalar.
218 Bool isScalar (Int whichField) const;
219
220 // Returns True if whichField is a sub-record.
221 Bool isSubRecord (Int whichField) const;
222
223 // Returns True if whichField is a table.
224 Bool isTable (Int whichField) const;
225
226 // What is the shape of the given field. Returns [1] if the field is a
227 // scalar, table or, sub-record, [-1] if it is a variable length array,
228 // and the actual shape for a fixed length array.
229 const IPosition& shape (Int whichField) const;
230
231 // What is the name of the table description.
232 // Returns an empty string when the field is no table.
233 const String& tableDescName (Int whichField) const;
234
235 // If whichField is a sub-record return its description.
236 // Otherwise an exception is thrown.
237 // The non-const version is named differently to prevent accidental
238 // use of the non-const version.
239 // <group>
240 const RecordDesc& subRecord (Int whichField) const;
241 RecordDesc& rwSubRecord (Int whichField);
242 // </group>
243
244 // This and other compare equal if the field types and shapes are identical
245 // (recursively if there are described sub-records).
246 // The field names are not used.
247 // <br>Use function isEqual if names are important, but order is not.
248 // <group>
249 Bool operator== (const RecordDesc& other) const;
250 Bool operator!= (const RecordDesc& other) const;
251 // </group>
252
253 // Test if this description conforms the other.
254 // It is NOT doing it recursively, thus is does not check if
255 // sub-records are conforming.
256 // <br>This is used by Record, to see if another record can be assigned
257 // to this record.
258 Bool conform (const RecordDesc& other) const;
259
260 // Test if this description equals another one.
261 // It is equal if the number of fields is equal and all field names in
262 // this description occur in the other too. The order of the fields
263 // is not important.
264 // <br>The flag equalDataTypes is set to True if the data types
265 // of all fields match.
266 // <br>Use function operator== if order and types are important,
267 // but names are not.
268 Bool isEqual (const RecordDesc& other, Bool& equalDataTypes) const;
269
270 // Test if this description is a subset of another one.
271 // It is similar to isEqual above.
272 Bool isSubset (const RecordDesc& other, Bool& equalDataTypes) const;
273
274 // Test if this description is a strict subset of another one, thus
275 // if it is a subset and not equal.
276 Bool isStrictSubset (const RecordDesc& other, Bool& equalDataTypes) const;
277
278 // Test if this description is a superset of another one.
279 Bool isSuperset (const RecordDesc& other, Bool& equalDataTypes) const;
280
281 // Test if this description is a strict superset of another one, thus
282 // if it is a superset and not equal.
283 Bool isStrictSuperset (const RecordDesc& other,
284 Bool& equalDataTypes) const;
285
286 // Test if the set of field names in this and other record description
287 // is disjoint (i.e. if they do not share names).
288 Bool isDisjoint (const RecordDesc& other) const;
289
290
291private:
292 // Writes/reads the RecordDesc to/from an output stream.
293 // <group>
294 ostream& put (ostream& os) const;
295 AipsIO& put (AipsIO& os) const;
297 // </group>
298
299 // Use a copy-on-write pointer to the RecordDescRep.
301};
302
303
304
306: desc_p (new RecordDescRep)
307{}
308
310: desc_p (other.desc_p)
311{}
312
314{
315 if (this != &other) {
316 desc_p = other.desc_p;
317 }
318 return *this;
319}
320
323
324inline uInt RecordDesc::addField (const String& fieldName, DataType dataType)
325{
326 return desc_p.rwRef().addField (fieldName, dataType);
327}
328
329inline uInt RecordDesc::addField (const String& fieldName,
330 DataType scalarOrArrayType,
331 const IPosition& shape)
332{
333 return desc_p.rwRef().addArray (fieldName, scalarOrArrayType, shape);
334}
335
336inline uInt RecordDesc::addField (const String& fieldName,
337 const RecordDesc& subDesc)
338{
339 return desc_p.rwRef().addRecord (fieldName, subDesc);
340}
341
342inline uInt RecordDesc::addTable (const String& fieldName,
343 const String& tableDescName)
344{
345 return desc_p.rwRef().addTable (fieldName, tableDescName);
346}
347
348inline const String& RecordDesc::comment (Int whichField) const
349{
350 return desc_p.ref().comment (whichField);
351}
352
353inline void RecordDesc::setComment (Int whichField, const String& comment)
354{
355 desc_p.rwRef().setComment (whichField, comment);
356}
357
358inline void RecordDesc::setShape (Int whichField, const IPosition& shape)
359{
360 desc_p.rwRef().setShape (whichField, shape);
361}
362
364 Int whichFieldFromOther,
365 RecordInterface::DuplicatesFlag duplicateAction)
366{
367 return desc_p.rwRef().mergeField (other.desc_p.ref(), whichFieldFromOther,
368 duplicateAction);
369}
370
371inline uInt RecordDesc::merge (const RecordDesc& other,
372 RecordInterface::DuplicatesFlag duplicateAction)
373{
374 return desc_p.rwRef().merge (other.desc_p.ref(), duplicateAction);
375}
376
378{
379 return desc_p.rwRef().removeField (whichField);
380}
381
382inline void RecordDesc::renameField (const String& newName, Int whichField)
383{
384 desc_p.rwRef().renameField (newName, whichField);
385}
386
387inline Int RecordDesc::fieldNumber (const String& fieldName) const
388{
389 return desc_p.ref().fieldNumber (fieldName);
390}
391
393{
394 return desc_p.ref().nfields();
395}
396
397inline DataType RecordDesc::type (Int whichField) const
398{
399 return desc_p.ref().type (whichField);
400}
401
402inline String RecordDesc::uniqueName (const String& name) const
403{
404 return desc_p.ref().uniqueName (name);
405}
406
407inline String RecordDesc::makeName (Int whichField) const
408{
409 return desc_p.ref().makeName (whichField);
410}
411
412inline const String& RecordDesc::name (Int whichField) const
413{
414 return desc_p.ref().name (whichField);
415}
416
417inline Bool RecordDesc::isArray (Int whichField) const
418{
419 return desc_p.ref().isArray (whichField);
420}
421
422inline Bool RecordDesc::isScalar (Int whichField) const
423{
424 return desc_p.ref().isScalar (whichField);
425}
426
427inline Bool RecordDesc::isSubRecord (Int whichField) const
428{
429 return desc_p.ref().isSubRecord (whichField);
430}
431
432inline Bool RecordDesc::isTable (Int whichField) const
433{
434 return desc_p.ref().isTable (whichField);
435}
436
437inline const IPosition& RecordDesc::shape (Int whichField) const
438{
439 return desc_p.ref().shape (whichField);
440}
441
442inline const String& RecordDesc::tableDescName (Int whichField) const
443{
444 return desc_p.ref().tableDescName (whichField);
445}
446
447inline const RecordDesc& RecordDesc::subRecord (Int whichField) const
448{
449 return desc_p.ref().subRecord (whichField);
450}
451
453{
454 return desc_p.rwRef().subRecord (whichField);
455}
456
457inline Bool RecordDesc::operator== (const RecordDesc& other) const
458{
459 return desc_p.ref() == other.desc_p.ref();
460}
461
462inline Bool RecordDesc::operator!= (const RecordDesc& other) const
463{
464 return desc_p.ref() != other.desc_p.ref();
465}
466inline Bool RecordDesc::conform (const RecordDesc& other) const
467{
468 return desc_p.ref().conform (other.desc_p.ref());
469}
470
472 Bool& equalDataTypes) const
473{
474 return desc_p.ref().isEqual (other.desc_p.ref(), equalDataTypes);
475}
477 Bool& equalDataTypes) const
478{
479 return desc_p.ref().isSubset (other.desc_p.ref(), equalDataTypes);
480}
482 Bool& equalDataTypes) const
483{
484 return desc_p.ref().isStrictSubset (other.desc_p.ref(), equalDataTypes);
485}
487 Bool& equalDataTypes) const
488{
489 return other.desc_p.ref().isSubset (desc_p.ref(), equalDataTypes);
490}
492 Bool& equalDataTypes) const
493{
494 return other.desc_p.ref().isStrictSubset (desc_p.ref(), equalDataTypes);
495}
496inline Bool RecordDesc::isDisjoint (const RecordDesc& other) const
497{
498 return desc_p.ref().isDisjoint (other.desc_p.ref());
499}
500
501
502inline ostream& operator<< (ostream& os, const RecordDesc& desc)
503{
504 return desc.put (os);
505}
506inline AipsIO& operator<< (AipsIO& os, const RecordDesc& desc)
507{
508 return desc.put (os);
509}
511{
512 return desc.get (os);
513}
514
515
516
517
518
519} //# NAMESPACE CASACORE - END
520
521#endif
Bool isSubRecord(Int whichField) const
Returns True if whichField is a sub-record.
Definition RecordDesc.h:427
RecordDesc & rwSubRecord(Int whichField)
Definition RecordDesc.h:452
Bool isStrictSubset(const RecordDesc &other, Bool &equalDataTypes) const
Test if this description is a strict subset of another one, thus if it is a subset and not equal.
Definition RecordDesc.h:481
COWPtr< RecordDescRep > desc_p
Use a copy-on-write pointer to the RecordDescRep.
Definition RecordDesc.h:300
Int fieldNumber(const String &fieldName) const
Returns the index of the field named fieldName.
Definition RecordDesc.h:387
uInt nfields() const
Number of fields in the description.
Definition RecordDesc.h:392
uInt merge(const RecordDesc &other, RecordInterface::DuplicatesFlag DuplicateAction=RecordInterface::ThrowOnDuplicates)
Add all the fields from another RecordDesc to the current objects.
Definition RecordDesc.h:371
void renameField(const String &newName, Int whichField)
Rename the given field.
Definition RecordDesc.h:382
uInt removeField(Int whichField)
Remove the given field from the description.
Definition RecordDesc.h:377
RecordDesc()
Create a description with no fields.
Definition RecordDesc.h:305
String makeName(Int whichField) const
Create a name for a field defined by index as *i (similar to glish).
Definition RecordDesc.h:407
Bool isEqual(const RecordDesc &other, Bool &equalDataTypes) const
Test if this description equals another one.
Definition RecordDesc.h:471
Bool isSubset(const RecordDesc &other, Bool &equalDataTypes) const
Test if this description is a subset of another one.
Definition RecordDesc.h:476
const String & comment(Int whichField) const
Get the comment for this field.
Definition RecordDesc.h:348
Bool conform(const RecordDesc &other) const
Test if this description conforms the other.
Definition RecordDesc.h:466
AipsIO & get(AipsIO &os)
uInt mergeField(const RecordDesc &other, Int whichFieldFromOther, RecordInterface::DuplicatesFlag DuplicateAction=RecordInterface::ThrowOnDuplicates)
Merge a single field from other.
Definition RecordDesc.h:363
const String & name(Int whichField) const
What is the name of the given field.
Definition RecordDesc.h:412
const RecordDesc & subRecord(Int whichField) const
If whichField is a sub-record return its description.
Definition RecordDesc.h:447
Bool isDisjoint(const RecordDesc &other) const
Test if the set of field names in this and other record description is disjoint (i....
Definition RecordDesc.h:496
void setComment(Int whichField, const String &comment)
Set the comment for this field.
Definition RecordDesc.h:353
friend AipsIO & operator>>(AipsIO &os, RecordDesc &desc)
Definition RecordDesc.h:510
String uniqueName(const String &name) const
Make the given name unique by adding a suffix _j when needed.
Definition RecordDesc.h:402
Bool operator!=(const RecordDesc &other) const
Definition RecordDesc.h:462
friend ostream & operator<<(ostream &os, const RecordDesc &desc)
Writes/reads the RecordDesc to/from an output stream.
Definition RecordDesc.h:502
void setShape(Int whichField, const IPosition &shape)
Set the shape for this field.
Definition RecordDesc.h:358
Bool isTable(Int whichField) const
Returns True if whichField is a table.
Definition RecordDesc.h:432
Bool isSuperset(const RecordDesc &other, Bool &equalDataTypes) const
Test if this description is a superset of another one.
Definition RecordDesc.h:486
Bool operator==(const RecordDesc &other) const
This and other compare equal if the field types and shapes are identical (recursively if there are de...
Definition RecordDesc.h:457
DataType type(Int whichField) const
What is the type of the given field.
Definition RecordDesc.h:397
Bool isStrictSuperset(const RecordDesc &other, Bool &equalDataTypes) const
Test if this description is a strict superset of another one, thus if it is a superset and not equal.
Definition RecordDesc.h:491
Bool isArray(Int whichField) const
Returns True if whichField is an array.
Definition RecordDesc.h:417
RecordDesc & operator=(const RecordDesc &other)
Replace this description with other.
Definition RecordDesc.h:313
ostream & put(ostream &os) const
Writes/reads the RecordDesc to/from an output stream.
uInt addTable(const String &fieldName, const String &tableDescName)
Add a Table field to the description.
Definition RecordDesc.h:342
AipsIO & put(AipsIO &os) const
Bool isScalar(Int whichField) const
Returns True if whichField is a scalar.
Definition RecordDesc.h:422
const String & tableDescName(Int whichField) const
What is the name of the table description.
Definition RecordDesc.h:442
uInt addField(const String &fieldName, DataType dataType)
Add scalar, array, sub-record, or table field.
Definition RecordDesc.h:324
const IPosition & shape(Int whichField) const
What is the shape of the given field.
Definition RecordDesc.h:437
DuplicatesFlag
Define the Duplicates flag for the function merge in the various record classes.
@ ThrowOnDuplicates
Throw an exception.
String: the storage and methods of handling collections of characters.
Definition String.h:225
this file contains all the compiler specific defines
Definition mainpage.dox:28
AipsIO & operator>>(AipsIO &os, Record &rec)
Definition Record.h:465
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
unsigned int uInt
Definition aipstype.h:51
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape.
Definition ExprNode.h:1987
int Int
Definition aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:42