~vbursian/research-assistant/intervers

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