casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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>
37 
38 namespace casacore { //# NAMESPACE CASACORE - BEGIN
39 
40 //# Forward Declarations
41 class TableRecord;
42 class 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 
118 template<class T> class RecordFieldPtr : public NoticeTarget
119 {
120 public:
121  // This object does not point to any field, i.e.
122  // <src>this->isAttached() == False;</src>
123  RecordFieldPtr();
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);
129  RecordFieldPtr (RecordInterface& record, const RecordFieldId&);
130  // </group>
131 
132  // After calling, this and other point to the same field, i.e. it
133  // uses reference semantics.
134  // <group>
135  RecordFieldPtr (const RecordFieldPtr<T>& other);
137  // </group>
138 
139  ~RecordFieldPtr();
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);
145  void attachToRecord (RecordInterface& record, const RecordFieldId&);
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>
158  T& operator*();
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.
176  Int fieldNumber() const
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.
191  Bool isAttached() const
192  {return NoticeTarget::isAttached();}
193 
194 private:
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 
228 template<class T> class RORecordFieldPtr
229 {
230 public:
232  RORecordFieldPtr (const RecordInterface& record, Int whichField)
233  : fieldPtr_p((RecordInterface&)record, whichField) {}
234  RORecordFieldPtr (const RecordInterface& record, const RecordFieldId& id)
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 
255  Int fieldNumber() const
256  {return fieldPtr_p.fieldNumber();}
257 
258  void detach() {fieldPtr_p.detach(); }
259  Bool isAttached() const {return fieldPtr_p.isAttached(); }
260 
261 private:
263 };
264 
265 
266 
267 //# Define some global functions to specialize some FieldRecordPtr functions.
268 //# Some compilers have problems with normal specializations.
269 inline void defineRecordFieldPtr (RecordInterface* parent, Int fieldNumber,
270  DataType type, const void* value)
271 {
272  parent->defineDataField (fieldNumber, type, value);
273 }
274 inline 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.
282 inline 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).
288 inline 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.
294 inline 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.
300 inline 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
RecordFieldPtr< T > & operator=(const RecordFieldPtr< T > &other)
int Int
Definition: aipstype.h:50
void detach()
Point to no field in any Record.
abstract base class for notice receptors
Definition: Notice.h:150
Main interface class to a read/write table.
Definition: Table.h:157
RecordFieldPtr()
This object does not point to any field, i.e.
RecordFieldPtr< T > fieldPtr_p
Definition: RecordField.h:262
void attachToRecord(RecordInterface &record, Int whichField)
Change our pointer to the supplied field.
void define(const T &value)
Store a value in the field using redefinition.
String name() const
Return the name of the field.
Definition: RecordField.h:180
void setComment(const String &comment)
Set the comment for this field.
void attachToRecord(const RecordInterface &record, const RecordFieldId &id)
Definition: RecordField.h:247
Int fieldNumber() const
Return the fieldnumber of this field.
Definition: RecordField.h:176
RORecordFieldPtr< T > & operator=(const RORecordFieldPtr< T > &other)
Definition: RecordField.h:240
virtual void notify(const Notice &message)
Not important for users - the mechanism by which field pointers are notified when there is a change i...
The identification of a record field.
Definition: RecordFieldId.h:91
Access to an individual field in a record.
Definition: RecordField.h:118
const String & comment() const
Get the comment of this field.
virtual void defineDataField(Int whichField, DataType type, const void *value)=0
Define a data field (for RecordFieldPtr).
RORecordFieldPtr(const RecordFieldPtr< T > &other)
Definition: RecordField.h:236
T & operator*()
Provide access to the field&#39;s value.
void attachToRecord(const RecordInterface &record, Int whichField)
Definition: RecordField.h:245
A hierarchical collection of named fields of various types.
Definition: Record.h:180
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
abstract base class for notices
Definition: Notice.h:62
Bool isAttached() const
Is this field pointer attached to a valid record? Operations which might cause it to become detached ...
Definition: RecordField.h:191
RORecordFieldPtr(const RecordInterface &record, Int whichField)
Definition: RecordField.h:232
A hierarchical collection of named fields of various types.
Definition: TableRecord.h:185
void * attachRecordFieldPtr(RecordInterface *parent, Int fieldNumber, DataType type, const void *)
This function attaches a RecordFieldPtr object.
Definition: RecordField.h:282
Bool isAttached() const
Returns a boolean value telling whether this NoticeTarget is still attached to a NoticeSource or not...
Definition: Notice.h:163
RecordInterface * parent_p
Definition: RecordField.h:196
const T & operator*() const
Definition: RecordField.h:159
RORecordFieldPtr(const RORecordFieldPtr< T > &other)
Definition: RecordField.h:238
const String & comment() const
Definition: RecordField.h:253
String: the storage and methods of handling collections of characters.
Definition: String.h:225
RORecordFieldPtr(const RecordInterface &record, const RecordFieldId &id)
Definition: RecordField.h:234
virtual void * get_pointer(Int whichField, DataType type) const =0
Used by the RecordFieldPtr classes to attach to the correct field.
Abstract base class for Record classes.
Read-Only access to an individual field from a Record.
Definition: RecordField.h:228
const T & operator*() const
Definition: RecordField.h:250
void defineRecordFieldPtr(RecordInterface *parent, Int fieldNumber, DataType type, const void *value)
Definition: RecordField.h:269
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
String name(const RecordFieldId &) const
Get the name of this field.