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