[go: up one dir, main page]

Menu

[80c337]: / laddress.h  Maximize  Restore  History

Download this file

242 lines (207 with data), 10.1 kB

  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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#ifndef LOB_ADDRESS
#define LOB_ADDRESS
#include <OmHeaders.h>
#include <QObject>
#include <QMetaType>
/** \brief A class for indexing into Lob tree structures
*
* To describe the location of one node in a large OpenMath (Lob) tree structure, use a
* LobAddress. It specifies the steps you would need to take from the root node of the
* tree to reach the desired inner Lob. Each such step will either be a step to a child
* node, a step to an attribute key, or a step to an attribute value.
*
* Thus this class provides numSteps() to tell you how many steps are in the address,
* stepType() to query the type of each step (AsChild, AsKey, or AsValue, members of an
* enum in the OmNode class), and stepIndex() to tell you the number of the child or
* attribute into which the step was taken. For instance, an address with types
* AsChild,AsKey,AsChild and indices 0,2,1 has this meaning: "From the root,
* go to child 0, from there to attribute key 2, and from there to child 1."
*
* Newly constructed addresses have no steps, but you can add them with addStep().
* The default copy constructor and assignment operator apply.
*
* Two addresses are equal (operator==()) if they have the same number of steps,
* and all their steps and indices are equal.
* There is an ordering of addresses that corresponds to a view of how such OpenMath
* trees are "laid out." See operator<() for details.
*/
class LobAddress
{
public:
LobAddress();
/** \brief The inverse of toString(), creating LobAddress objects from string notation
*
* Given a string of the form described in toString(), this creates a new LobAddress
* object whose toString() value is \a encoding. If \a encoding is not of the format
* specified, an empty address is returned.
*
* This routine is tested in test_laddress::test_getters().
*/
LobAddress( const QString encoding );
/** \brief The index of the \a i<sup>th</sup> step
*
* If the \a i<sup>th</sup> step is to a child, this is the child's index.
* If it is to an attribute, this is the attribute's index.
*
* This routine is tested in test_laddress::test_getters().
*/
unsigned int stepIndex ( unsigned int i ) const;
/** \brief The type of the \a i<sup>th</sup> step
*
* This is of type OmNode::OwnershipType, which can be None, AsChild, AsKey,
* or AsValue. The None element of the enum has no meaning in this context,
* and should not be used; addStep() actually rejects it, so it is guaranteed
* not to be returned by this function.
*
* This routine is tested in test_laddress::test_getters().
*/
OmNode::OwnershipType stepType ( unsigned int i ) const;
/** \brief How many steps there are in the address
*
* Zero steps indicates an empty address. The address of the root node in a tree
* is empty, meaning no steps are required to get there from the root.
*
* This routine is tested in test_laddress::test_getters().
*/
unsigned int numSteps () const;
/** \brief Append a step to the end of the address
*
* Useful when constructing addresses.
* \param index As you would want returned from stepIndex()
* \param type As you would want returned from stepType(). Note that this function
* ignores any attempt to add a step with type equal to OmNode::None.
*
* This routine is tested in test_laddress::test_order().
*/
void addStep ( unsigned int index, OmNode::OwnershipType type );
/** \brief A copy of the address containing all steps but the last one
*
* This is useful for walking backwards up parent/container chains. For instance,
* <code>exampleLob.index( address.up() )</code> is the Lob that is the parent or
* container of <code>exampleLob.index( address )</code>.
*
* If this address has no steps, then an empty address is returned.
*/
LobAddress up () const;
/** \brief A copy of the address containing all steps but the first one
*
* This is useful for stepping inside a document or dependecy in a LurchEnvironment.
* See documentation for LurchEnvironment::address(Lob)
* and LurchEnvironment::index(LobAddress) for more information.
*
* If this address has no steps, then an empty address is returned.
*/
LobAddress down () const;
/** \brief Create a new address by appending another one to this one
*
* If \a other is the address of Lob A within Lob B, and this object is the address
* of Lob B within Lob C, then you can form the address of Lob A within Lob C by
* adding this address to \a other. The result is a new address whose first steps
* are equal to this address's steps, and whose final steps are equal to the steps
* of \a other, for a total number of steps equal to numSteps() + other.numSteps().
*/
LobAddress operator+ ( const LobAddress& other ) const;
/** \brief Strict ordering of addresses based on the steps in them
*
* It is easier to speak of one position in a tree being less than another, so I
* describe this function that way. It is the transitive closure of the following
* relation.
* <ul>
* <li>The root location in a tree is less than the locations of all its attributes
* and its children.</li>
* <li>The location of any attribute of a node is less than the location of any
* child of that same node.</li>
* <li>The locations of a node's attributes are ordered by index (lesser indices
* giving lesser locations).</li>
* <li>The locations of a node's children are ordered by index (lesser indices
* giving lesser locations).</li>
* <li>In a single attribute, the location of the key is less than the location
* of the value.</li>
* </ul>
* Note that this is a strict order relation, so if <code>addrA == addrB</code>
* then <code>!( addrA < addrB )</code>.
*
* Script authors can access this with the <code>.lessThan()</code> member function
* of LobAddress objects in script.
*
* This routine is tested in test_laddress::test_order()
* and test_laddress::test_lob_methods().
*/
bool operator< ( const LobAddress& other ) const;
/** \brief Whether two addresses have all the same steps
*
* Two addresses are equal if and only if they have the same number of steps, and each
* step in the one address has the same index and type as the corresponding step in
* the other address.
*
* Script authors can access this with the <code>.equals()</code> member function
* of LobAddress objects in script.
*
* This routine is tested in test_laddress::test_order().
*/
bool operator== ( const LobAddress& other ) const;
/** \brief Just the disjunction of operator<() with operator==()
*
* Due to its simplicity, this routine is untested.
*/
bool operator<= ( const LobAddress& other ) const;
/** \brief A simple string representation, for debugging
*
* The string is of the form CNCNCNCN..., where each C is a character indicating
* the step type (c for child, k for key, v for value) and N is an integer indicating
* the index (zero-based).
*
* This routine is partially tested in test_laddress::test_getters().
*/
QString toString () const;
/** \brief Tests whether this address has \a other as a prefix.
*
* Tests to see if the first \a other.numStep() steps of
* this address are the same as the corresponding steps of \a other.
*/
bool hasPrefix ( const LobAddress& other ) const;
/** \brief Returns a copy of this address modified to take into account the insertion of a Lob at \a loc
*
* When a Lob is inserted as a child, addresses of other children of its parent
* change. If an address is intended to be the location of some fixed Lob,
* then whenever a Lob is inserted as a child of one of that Lob's ancestors,
* the address must change.
* This method performs that update when a child is inserted at \a loc.
*
* This routine is tested in test_laddress::test_address_modification().
*/
LobAddress addressInserted ( const LobAddress& loc ) const;
/** \brief Returns a new address modified to take into account the insertion of a lob at \a loc
*
* Whenever a child of a Lob is removed, addresses of other children of its parent
* change. If an address is intended to be the location of some fixed Lob,
* then whenever a child of one of that Lob's ancestors is removed,
* the address must change.
* This method performs that update when a child is removed from \a loc.
*
* This routine is tested in test_laddress::test_address_modification().
*/
LobAddress addressRemoved( const LobAddress& loc ) const;
private:
/** Used internally as the workhorse for computing operator<().
* See the documentation for that function to learn how this one behaves.
*
* This is simply the recursive version, which assumes that steps 0 through i-1
* have been determined equal, and returns a result based only on comparing steps
* i through the end.
*/
bool strictOrderComparison ( const LobAddress& other, unsigned int i ) const;
/** Internal storage of the index of each step in the address.
*/
QList<unsigned int> stepIndices;
/** Internal storage of the type of each step in the address.
*/
QList<OmNode::OwnershipType> stepTypes;
};
Q_DECLARE_METATYPE( LobAddress )
/** \brief A global has function allowing LobAddress objects to be used as indices in a QMap
*
* See documentation on QHash for more information.
*/
uint qHash ( const LobAddress& key );
#endif // LOB_ADDRESS