casacore
RecordField.h
Go to the documentation of this file.
1//# RecordField.h: Access to an individual field in a record
2//# Copyright (C) 1995,1996,1997
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_RECORDFIELD_H
31#define CASA_RECORDFIELD_H
32
33//# Includes
34#include <casacore/casa/aips.h>
35#include <casacore/casa/Containers/Record.h>
36#include <casacore/casa/Utilities/Notice.h>
37
38namespace casacore { //# NAMESPACE CASACORE - BEGIN
39
40//# Forward Declarations
41class TableRecord;
42class Table;
43
44
45// <summary>
46// Access to an individual field in a record.
47// </summary>
48
49// <use visibility=export>
50// <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecord">
51// </reviewed>
52
53// <prerequisite>
54// <li> <linkto class="RecordInterface">RecordInterface</linkto>.
55// </prerequisite>
56
57// <etymology>
58// RecordFieldPtr indicates that an object of this type is
59// pointing to a field in a record.
60// </etymology>
61
62// <synopsis>
63// RecordFieldPtr allows access to the fields in a record object.
64// A record object is an object of a class derived from
65// <linkto class=RecordInterface>RecordInterface</linkto>.
66// <src>RecordFieldPtr<T></src> objects can only be instantiated for types `T'
67// which are valid fields of a record object (e.g. Int, float, String,
68// Record, TableRecord). It can, however, NOT be instantiated for
69// a Table field, because Table fields are accessed indirectly via a
70// TableKeyword object. Table fields have to be accessed directly
71// through the <linkto class=TableRecord>TableRecord</linkto> interface.
72// <p>
73// The RecordFieldPtr is pointer-like in the sense that it points to an
74// object that is physically inside of another object (the enclosing
75// record object).
76// Access to the value is obtained via the dereference operator
77// (<src>operator*()</src>) to emphasize the pointer like nature of these
78// classes.
79// <br>
80// An alternative way to get access to the values is using the
81// functions define and get. Note that in
82// <srcblock>
83// RecordFieldPtr<Array<Int> > field (record, fieldNumber);
84// Array<Int> value;
85// *field = value;
86// field.define (value);
87// </srcblock>
88// the assignment (in line 3) and define (in line 4) are not equivalent.
89// The assignment uses the normal Array assignment, thus it takes the
90// Array conformance rules into account (an assign is only possible when
91// the new array value conforms the current array value or when the current
92// array value is empty).
93// On the other hand, define does not take the current array value into
94// account. Thus an array value can always be redefined.
95// <br>
96// However, note that if the field is defined with a non-fixed shape in
97// the record description, a value must always conform that shape (in
98// case of assignment as well as in case of define).
99// <p>
100// RecordFieldPtr is derived from NoticeTarget to get messages from
101// the mother record class when it changes. For example, when the
102// record is destructed, all RecordFieldPtr's pointing to that record
103// will automatically be detached.
104// </synopsis>
105
106// <example>
107// See the example in the <linkto class="Record">Record</linkto> class.
108// </example>
109
110// <motivation>
111// RecordFieldPtr provides a fast way to access the data in a record.
112// </motivation>
113
114//# <todo asof="1995/06/15">
115//# </todo>
116
117
118template<class T> class RecordFieldPtr : public NoticeTarget
119{
120public:
121 // This object does not point to any field, i.e.
122 // <src>this->isAttached() == False;</src>
124
125 // Attach this field pointer to the given field. If it does not exist
126 // an exception is thrown.
127 // <group>
128 RecordFieldPtr (RecordInterface& record, Int whichField);
130 // </group>
131
132 // After calling, this and other point to the same field, i.e. it
133 // uses reference semantics.
134 // <group>
137 // </group>
138
140
141 // Change our pointer to the supplied field. If it doesn't exist an
142 // exception is thrown.
143 // <group>
144 void attachToRecord (RecordInterface& record, Int whichField);
146 // </group>
147
148 // Point to no field in any Record.
149 void detach();
150
151 // Provide access to the field's value.
152 // <note>
153 // To be sure a const function is called, it is best to use get().
154 // For a non-const object, a non-const function is called, even if
155 // used as an rvalue.
156 // </note>
157 // <group>
159 const T& operator*() const {return *fieldPtr_p;}
160 const T& get() const {return *fieldPtr_p;}
161 // </group>
162
163 // Store a value in the field using redefinition.
164 // Define differs from assignment w.r.t. arrays.
165 // For define a variable shaped array is deleted first with the
166 // effect that array conformance rules are not applied for them.
167 void define (const T& value);
168
169 // Get the comment of this field.
170 const String& comment() const;
171
172 // Set the comment for this field.
173 void setComment (const String& comment);
174
175 // Return the fieldnumber of this field.
177 {return fieldNumber_p;}
178
179 // Return the name of the field.
180 String name() const
181 {return parent_p->name (fieldNumber_p);}
182
183 // Is this field pointer attached to a valid record? Operations which
184 // might cause it to become detached are:
185 // <ol>
186 // <li> Destruction of the Record
187 // <li> Restructuring of the record.
188 // <li> Explicit call of the detach() member.
189 // </ol>
190 //# This inherited function is shown for documentation purposes.
192 {return NoticeTarget::isAttached();}
193
194private:
198
199 // Not important for users - the mechanism by which field pointers are
200 // notified when there is a change in the record.
201 virtual void notify (const Notice& message);
202};
203
204
205// <summary>
206// Read-Only access to an individual field from a Record.
207// </summary>
208
209// <use visibility=export>
210// <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecord">
211// </reviewed>
212
213// <prerequisite>
214// <li> <linkto class="RecordFieldPtr">RecordRecordFieldPtr</linkto>.
215// </prerequisite>
216//
217// <synopsis>
218// This class is entirely like <linkto class="RecordFieldPtr">
219// RecordFieldPtr</linkto>, except that it only allows Read-Only
220// access to fields in a Record. The documentation for that class should
221// be consulted.
222// <p>
223// Note that RecordFieldPtr is not inherited from RORecordFieldPtr,
224// because that would give problems with the function attachToRecord.
225// It would allow RecordFieldPtr to attach to a const RecordInterface object.
226// </synopsis>
227
228template<class T> class RORecordFieldPtr
229{
230public:
232 RORecordFieldPtr (const RecordInterface& record, Int whichField)
233 : fieldPtr_p((RecordInterface&)record, whichField) {}
235 : fieldPtr_p((RecordInterface&)record, id) {}
237 : fieldPtr_p(other) {}
239 : fieldPtr_p(other.fieldPtr_p) {}
241 { fieldPtr_p = other.fieldPtr_p; return *this;}
242
244
245 void attachToRecord (const RecordInterface& record, Int whichField)
246 { fieldPtr_p.attachToRecord ((RecordInterface&)record, whichField); }
247 void attachToRecord (const RecordInterface& record, const RecordFieldId& id)
248 { fieldPtr_p.attachToRecord ((RecordInterface&)record, id); }
249
250 const T& operator*() const {return *fieldPtr_p;}
251 const T& get() const {return fieldPtr_p.get();}
252
253 const String& comment() const {return fieldPtr_p.comment();}
254
256 {return fieldPtr_p.fieldNumber();}
257
258 void detach() {fieldPtr_p.detach(); }
259 Bool isAttached() const {return fieldPtr_p.isAttached(); }
260
261private:
263};
264
265
266
267//# Define some global functions to specialize some FieldRecordPtr functions.
268//# Some compilers have problems with normal specializations.
269inline void defineRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
270 DataType type, const void* value)
271{
272 parent->defineDataField (fieldNumber, type, value);
273}
274inline void defineRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
275 DataType, const TableRecord* value)
276{
277 parent->defineDataField (fieldNumber, TpRecord, value);
278}
279
280// This function attaches a RecordFieldPtr object.
281// It is checked if the field type is correct.
282inline void* attachRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
283 DataType type, const void*)
284{
285 return parent->get_pointer (fieldNumber, type);
286}
287// Specialization for a Table field (which cannot be used).
288inline void* attachRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
289 DataType, const Table*)
290{
291 return parent->get_pointer (fieldNumber, TpOther);
292}
293// Specialization for a Record field.
294inline void* attachRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
295 DataType, const Record*)
296{
297 return parent->get_pointer (fieldNumber, TpRecord, "Record");
298}
299// Specialization for a TableRecord field.
300inline void* attachRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
301 DataType, const TableRecord*)
302{
303 return parent->get_pointer (fieldNumber, TpRecord, "TableRecord");
304}
305
306
307
308
309} //# NAMESPACE CASACORE - END
310
311#ifndef CASACORE_NO_AUTO_TEMPLATES
312#include <casacore/casa/Containers/RecordField.tcc>
313#endif //# CASACORE_NO_AUTO_TEMPLATES
314#endif
abstract base class for notice receptors
Definition: Notice.h:150
Bool isAttached() const
Returns a boolean value telling whether this NoticeTarget is still attached to a NoticeSource or not.
Definition: Notice.h:163
Read-Only access to an individual field from a Record.
Definition: RecordField.h:229
const T & get() const
Definition: RecordField.h:251
RORecordFieldPtr(const RecordInterface &record, const RecordFieldId &id)
Definition: RecordField.h:234
const String & comment() const
Definition: RecordField.h:253
const T & operator*() const
Definition: RecordField.h:250
void attachToRecord(const RecordInterface &record, const RecordFieldId &id)
Definition: RecordField.h:247
RORecordFieldPtr(const RORecordFieldPtr< T > &other)
Definition: RecordField.h:238
RORecordFieldPtr(const RecordInterface &record, Int whichField)
Definition: RecordField.h:232
RecordFieldPtr< T > fieldPtr_p
Definition: RecordField.h:262
RORecordFieldPtr< T > & operator=(const RORecordFieldPtr< T > &other)
Definition: RecordField.h:240
RORecordFieldPtr(const RecordFieldPtr< T > &other)
Definition: RecordField.h:236
void attachToRecord(const RecordInterface &record, Int whichField)
Definition: RecordField.h:245
const T & get() const
Definition: RecordField.h:160
void detach()
Point to no field in any Record.
RecordFieldPtr(RecordInterface &record, Int whichField)
Attach this field pointer to the given field.
RecordInterface * parent_p
Definition: RecordField.h:196
RecordFieldPtr()
This object does not point to any field, i.e.
void attachToRecord(RecordInterface &record, Int whichField)
Change our pointer to the supplied field.
void attachToRecord(RecordInterface &record, const RecordFieldId &)
virtual void notify(const Notice &message)
Not important for users - the mechanism by which field pointers are notified when there is a change i...
void define(const T &value)
Store a value in the field using redefinition.
RecordFieldPtr< T > & operator=(const RecordFieldPtr< T > &other)
RecordFieldPtr(RecordInterface &record, const RecordFieldId &)
Int fieldNumber() const
Return the fieldnumber of this field.
Definition: RecordField.h:176
void setComment(const String &comment)
Set the comment for this field.
const String & comment() const
Get the comment of this field.
T & operator*()
Provide access to the field's value.
RecordFieldPtr(const RecordFieldPtr< T > &other)
After calling, this and other point to the same field, i.e.
Bool isAttached() const
Is this field pointer attached to a valid record? Operations which might cause it to become detached ...
Definition: RecordField.h:191
String name() const
Return the name of the field.
Definition: RecordField.h:180
const T & operator*() const
Definition: RecordField.h:159
String name(const RecordFieldId &) const
Get the name of this field.
virtual void defineDataField(Int whichField, DataType type, const void *value)=0
Define a data field (for RecordFieldPtr).
virtual void * get_pointer(Int whichField, DataType type) const =0
Used by the RecordFieldPtr classes to attach to the correct field.
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
void * attachRecordFieldPtr(RecordInterface *parent, Int fieldNumber, DataType type, const void *)
This function attaches a RecordFieldPtr object.
Definition: RecordField.h:282
void defineRecordFieldPtr(RecordInterface *parent, Int fieldNumber, DataType type, const void *value)
Definition: RecordField.h:269
int Int
Definition: aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.