1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
////////////////////////////////////////////////////////////////////////////////
/*! @file Attribute.h Class sAttribute and macros for cycling through.
- Part of RANet - Research Assistant Net Library (based on ANSI C++).
- Copyright(C) 1994-2013, Viktor E. Bursian, St.Petersburg, Russia.
Viktor.Bursian@mail.ioffe.ru
*///////////////////////////////////////////////////////////////////////////////
#ifndef Attribute_H
#define Attribute_H
#include "Time.h"
#include "NodePtr.h"
namespace RA {
//------------------------------------------------------------------------------
//ANNOUNCE_CLASS(sAttribute) //already predeclared in NodeLocation.h
//--------------------------------------------------------------- sAttribute ---
/*! An attribute,
meaning a directed link from one node to another.
Any sFolderNode instance may have a number of attributes.
An attribute can be named or nameless (see sAttrName::eType).
The value of an attribute is the node to which it refers.
*/
class RANet_EXPORT sAttribute
{
public://contants
static const int32_t OrderingIndexMin
= std::numeric_limits<int32_t>::min();
static const int32_t OrderingIndexMax
= std::numeric_limits<int32_t>::max();
static const int32_t OrderingIndexInc = 0x100000;
public://types
enum tIOStatus {cNewborn,cSynchronized,cDeleted};
public:
static bool Deleted (rcsAttribute attr)
{ return attr.IOStatus == cDeleted; }
public:
virtual ~sAttribute ();
sAttribute (rcsAttribute);
sAttribute (rcsAttrName attribute_name
,sNodePtr value_ptr
);
sAttribute (rcsAttrName attribute_name
,psNodeLocation node_location
,tIOStatus io_status
);
virtual rsAttribute operator = (rcsAttribute);
sAttrName::eType NameType () const
{ return TheName.Type(); }
sAttrName Name () const
{ return TheName; }
sNodePtr Value () const
{ return TheValue; }
private: // это запрещаем, вообще говоря, на всякий случай
void operator & ();
private://fields
sAttrName TheName;
sNodePtr TheValue;
tIOStatus IOStatus;
sTime StatusTimeStamp;
friend class sNet;
friend class sFolderNode;
#ifdef RANET_DEBUG
public:
static long int Counter;
#endif
};
//------------------------------------------------------------------------------
/*! Begins a loop through the attributes of a node.
@param a An identifier that will be declared inside the loop as pointer to
the current attribute.
@param folder An expression of sNodePtr type. It will be calculated @ once and
the value is checked for being a pointer to a folder-type node.
If this is not true or the node has no attributes, the loop will
do nothing.
Example:
@code
for_each_attribute( A , Config>>"Users" ){
//...;
//...;
}end_attr_loop()
@endcode
@note This macro already opens a C-block, which is then closed by
end_attr_loop() macro. So there is no need to use { } in the example above.
However, it is a good idea to use them: this makes Qt Creator editor to
understand the whole loop as a block (it can be collapsed, etc.)
@sa end_attr_loop(), for_each_nameless_attribute().
@macro
*/
#define for_each_attribute(a,folder) \
{ \
sPtr<sFolderNode> __ra_ptr (folder); \
if( __ra_ptr.IsCorrect() && __ra_ptr->HasAttributes() ){ \
QMutexLocker __ra_locker (__ra_ptr->AttrListMutexPtr()); \
for(std::list<sAttribute>::const_iterator \
a = __ra_ptr->Attributes().begin() \
; a != __ra_ptr->Attributes().end() \
; a++ ) \
if( ! sAttribute::Deleted( *a ) ) { \
//------------------------------------------------------------------------------
/*! Begins a loop through the nameless attributes.
@param value_node_ptr An identifier that will be declared inside the loop as
pointer to the @b value of the current attribute.
@param folder An expression of sNodePtr type. It will be calculated @b once and
the value is checked for being a pointer to a folder-type node.
If this is not true or the node has no attributes, the loop will
do nothing.
Usage:
@code
for_each_nameless_attribute(N,FolderPtr){
//...;
//...;
}end_attr_loop()
@endcode
@sa end_attr_loop(), for_each_attribute().
@macro
*/
#define for_each_nameless_attribute(value_node_ptr,folder) \
{ \
sPtr<sFolderNode> __ra_ptr (folder); \
if( __ra_ptr.IsCorrect() && __ra_ptr->HasAttributes() ){ \
QMutexLocker __ra_locker (__ra_ptr->AttrListMutexPtr()); \
for(std::list<sAttribute>::const_iterator \
__ra_attr = __ra_ptr->Attributes().begin() \
; __ra_attr != __ra_ptr->Attributes().end() \
; __ra_attr++ ) \
if( (__ra_attr->Name().Type() == sAttrName::cNameless) \
&& ! sAttribute::Deleted( * __ra_attr ) ) { \
sNodePtr value_node_ptr (__ra_attr->Value()); \
//------------------------------------------------------------------------------
/*! End of loop through the attributes.
@param a One can omit it or put here the first argument of the corresponding
for_each_attribute() macro. In fact, whatever stands in the
parentheses as an argument to this macro is ignored. However, the
parentheses are required. The reason why this macro is defined with
a parameter is that otherwise it compromises the syntax highlighting
in Qt Creator. It took me a while to find this workaround.
Terminates the loop started with for_each_attribute() or
with for_each_nameless_attribute() macro.
Usage:
@code
for_each_attribute(A,FolderPtr){
//...;
//...;
}end_attr_loop(A)
@endcode
or
@code
for_each_attribute(A,FolderPtr){
//...;
//...;
}end_attr_loop()
@endcode
@sa for_each_attribute(), for_each_nameless_attribute().
@macro
*/
#define end_attr_loop(a) }}}
//------------------------------------------------------------------------------
} //namespace RA
#endif
|