Statistics
| Branch: | Revision:

root / include / carray.h @ master

History | View | Annotate | Download (11.2 KB)

1
//==========================================================================
2
//  CARRAY.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Declaration of the following classes:
8
//    cArray : flexible array to store cObject objects
9
//
10
//==========================================================================
11

    
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19

    
20
#ifndef __CARRAY_H
21
#define __CARRAY_H
22

    
23
#include "cownedobject.h"
24

    
25
NAMESPACE_BEGIN
26

    
27

    
28
/**
29
 * Container object that holds objects derived from cObject.
30
 * cArray stores the pointers of the objects inserted instead of making copies.
31
 * cArray works as an array, but if it gets full, it grows automatically by
32
 * a specified delta.
33
 *
34
 * Ownership of cOwnedObjects may be controlled by invoking setTakeOwnership()
35
 * prior to inserting objects. Objects that cannot track their ownership
36
 * (cObject but not cOwnedObject) are always treated as owned. Whether an
37
 * object is owned or not affects the operation of the destructor, clean(),
38
 * the copy constructor and the dup() method.
39
 *
40
 * @ingroup Containers
41
 */
42
class SIM_API cArray : public cOwnedObject
43
{
44
  public:
45
    /**
46
     * Walks along a cArray.
47
     */
48
    class Iterator
49
    {
50
      private:
51
        cArray *array;
52
        int k;
53

    
54
      public:
55
        /**
56
         * Constructor. Iterator will walk on the array passed as argument.
57
         * The starting object will be the first (if athead==true) or
58
         * the last (athead==false) object in the array, not counting empty slots.
59
         */
60
        Iterator(const cArray& a, bool athead=true)  {init(a, athead);}
61

    
62
        /**
63
         * Reinitializes the iterator object.
64
         */
65
        void init(const cArray& a, bool athead=true);
66

    
67
        /**
68
         * Returns the current object, or NULL if the iterator is not
69
         * at a valid position.
70
         */
71
        cObject *operator()()  {return array->get(k);}
72

    
73
        /**
74
         * Returns true if the iterator has reached either end of the array.
75
         */
76
        bool end() const   {return k<0 || k>=array->size();}
77

    
78
        /**
79
         * Returns the current object, then moves the iterator to the next item.
80
         * Empty slots in the array are skipped.
81
         * If the iterator has reached either end of the array, nothing happens;
82
         * you have to call init() again to restart iterating.
83
         * If elements are added or removed during interation, the behaviour
84
         * is undefined.
85
         */
86
        cObject *operator++(int);
87

    
88
        /**
89
         * Returns the current object, then moves the iterator to the previous item.
90
         * Empty slots in the array are skipped.
91
         * If the iterator has reached either end of the array, nothing happens;
92
         * you have to call init() again to restart iterating.
93
         * If elements are added or removed during interation, the behaviour
94
         * is undefined.
95
         */
96
        cObject *operator--(int);
97
    };
98

    
99
  private:
100
    enum {FL_TKOWNERSHIP = 4};
101
    cObject **vect;   // vector of objects
102
    int capacity;     // allocated size of vect[]
103
    int delta;        // if needed, grows by delta
104
    int firstfree;    // first free position in vect[]
105
    int last;         // last used position
106

    
107
  public:
108
    /** @name Constructors, destructor, assignment. */
109
    //@{
110

    
111
    /**
112
     * Copy constructor. Contained objects that are owned by cArray
113
     * will be duplicated so that the new cArray will have its own
114
     * copy of them.
115
     */
116
    cArray(const cArray& list);
117

    
118
    /**
119
     * Constructor. The initial capacity of the container and the delta
120
     * (by which the capacity will grow if it gets full) can be specified.
121
     */
122
    explicit cArray(const char *name=NULL, int capacity=0, int delta=10);
123

    
124
    /**
125
     * Destructor. The contained objects that were owned by the container
126
     * will be deleted.
127
     */
128
    virtual ~cArray();
129

    
130
    /**
131
     * Assignment operator. The name member is not copied;
132
     * see cNamedObject's operator=() for more details.
133
     * Duplication and assignment work all right with cArray.
134
     * Contained objects that are owned by cArray will be duplicated
135
     * so that the new cArray will have its own copy of them.
136
     */
137
    cArray& operator=(const cArray& list);
138
    //@}
139

    
140
    /** @name Redefined cObject member functions */
141
    //@{
142

    
143
    /**
144
     * Duplication and assignment are supported by cArray.
145
     * Contained objects that are owned by cArray will be duplicated
146
     * so that the new cArray will have its own copy of them.
147
     */
148
    virtual cArray *dup() const  {return new cArray(*this);}
149

    
150
    /**
151
     * Produces a one-line description of the object's contents.
152
     * See cObject for more details.
153
     */
154
    virtual std::string info() const;
155

    
156
    /**
157
     * Calls v->visit(this) for each contained object.
158
     * See cObject for more details.
159
     */
160
    virtual void forEachChild(cVisitor *v);
161

    
162
    /**
163
     * Serializes the object into an MPI send buffer.
164
     * Used by the simulation kernel for parallel execution.
165
     * See cObject for more details.
166
     */
167
    virtual void parsimPack(cCommBuffer *buffer);
168

    
169
    /**
170
     * Deserializes the object from an MPI receive buffer
171
     * Used by the simulation kernel for parallel execution.
172
     * See cObject for more details.
173
     */
174
    virtual void parsimUnpack(cCommBuffer *buffer);
175
    //@}
176

    
177
    /** @name Container functions. */
178
    //@{
179

    
180
    /**
181
     * Returns the index of last used position+1. This only equals the
182
     * number of contained objects if there are no "holes" (NULL elements)
183
     * in the array.
184
     */
185
    int size() const {return last+1;}
186

    
187
    /**
188
     * Makes the container empty. Contained objects that were owned by the
189
     * container will be deleted.
190
     */
191
    void clear();
192

    
193
    /**
194
     * Returns the allocated size of the underlying array.
195
     */
196
    int getCapacity() const {return capacity;}
197

    
198
    /**
199
     * Resizes the the underlying array, without changing the contents of
200
     * this array. The specified capacity cannot be less than size().
201
     */
202
    void setCapacity(int capacity);
203

    
204
    /**
205
     * Inserts the object into the array. Only the pointer of the object
206
     * will be stored. The return value is the object's index in the
207
     * array.
208
     */
209
    int add(cObject *obj);
210

    
211
    /**
212
     * Inserts the object into the array at the given position. If
213
     * the position is occupied, the function throws a cRuntimeError.
214
     * The return value is the object's index in the array.
215
     */
216
    int addAt(int m, cObject *obj);
217

    
218
    /**
219
     * Inserts the object into the array. If the array already contains
220
     * an object with the same name, it will be replaced (hashtable-like
221
     * behavior.) The replaced object, if it was owned by the container,
222
     * is deleted using discard().
223
     * The return value is the object's index in the array.
224
     */
225
    int set(cObject *obj);
226

    
227
    /**
228
     * Searches the array for the pointer of the object passed and returns
229
     * the index of the first match. If the object was not found, -1 is
230
     * returned.
231
     */
232
    int find(cObject *obj) const;
233

    
234
    /**
235
     * Returns the index of the first item in the array that has the
236
     * name pointed to by s (cObject::isName() is used.)
237
     * If no such item was found, -1 is returned.
238
     */
239
    int find(const char *objname) const;
240

    
241
    /**
242
     * Returns reference to the mth object in the array. Returns NULL
243
     * if the mth position is not used.
244
     */
245
    cObject *get(int m);
246

    
247
    /**
248
     * Returns reference to the first object in the array with name s.
249
     * Returns NULL if no object with the given name was found.
250
     */
251
    cObject *get(const char *objname);
252

    
253
    /**
254
     * Returns reference to the mth object in the array. Returns NULL
255
     * if the mth position is not used.
256
     */
257
    const cObject *get(int m) const;
258

    
259
    /**
260
     * Returns reference to the first object in the array with name s.
261
     * Returns NULL if no object with the given name was found.
262
     */
263
    const cObject *get(const char *objname) const;
264

    
265
    /**
266
     * The same as get(int). With the indexing operator,
267
     * cArray can be used as a vector.
268
     */
269
    cObject *operator[](int m)  {return get(m);}
270

    
271
    /**
272
     * The same as get(const char *). With the indexing operator,
273
     * cArray can be used as a vector.
274
     */
275
    cObject *operator[](const char *objname)  {return get(objname);}
276

    
277
    /**
278
     * The same as get(int). With the indexing operator,
279
     * cArray can be used as a vector.
280
     */
281
    const cObject *operator[](int m) const  {return get(m);}
282

    
283
    /**
284
     * The same as get(const char *). With the indexing operator,
285
     * cArray can be used as a vector.
286
     */
287
    const cObject *operator[](const char *objname) const  {return get(objname);}
288

    
289
    /**
290
     * Returns true if position m is used in the array, otherwise false.
291
     */
292
    bool exist(int m) const  {return m>=0 && m<=last && vect[m]!=NULL;}
293

    
294
    /**
295
     * Returns true if the array contains an object with the given name,
296
     * otherwise false.
297
     */
298
    bool exist(const char *objname) const  {return find(objname)!=-1;}
299

    
300
    /**
301
     * Removes the object given with its index/name/pointer from the
302
     * container. (If the object was owned by the container, drop()
303
     * is called.)
304
     */
305
    cObject *remove(int m);
306

    
307
    /**
308
     * Removes the object given with its index/name/pointer from the
309
     * container. (If the object was owned by the container, drop()
310
     * is called.)
311
     */
312
    cObject *remove(const char *objname);
313

    
314
    /**
315
     * Removes the object given with its index/name/pointer from the
316
     * container, and returns the same pointer. If the object was not
317
     * found, NULL is returned. (If the object was owned by the container, drop()
318
     * is called.)
319
     */
320
    cObject *remove(cObject *obj);
321
    //@}
322

    
323
    /** @name Ownership control flag.
324
     *
325
     * The ownership control flag is to be used by derived container classes.
326
     * If the flag is set, the container should take() any object that is
327
     * inserted into it.
328
     */
329
    //@{
330

    
331
    /**
332
     * Sets the flag which determines whether the container object should
333
     * automatically take ownership of the objects that are inserted into it.
334
     * It does not affect objects already in the queue. When an inserted
335
     * object is owned by the container, that means it will be deleted when
336
     * the container object is deleted or cleared, and will be duplicated when
337
     * the container object is duplicated or copied.
338
     *
339
     * Setting the flag to false does not affect the treatment of objects
340
     * that are NOT cOwnedObject. Since they do not support the ownership
341
     * protocol, they will always be treated by the container.
342
     */
343
    void setTakeOwnership(bool tk) {setFlag(FL_TKOWNERSHIP,tk);}
344

    
345
    /**
346
     * Returns the flag which determines whether the container object
347
     * should automatically take ownership of the objects that are inserted
348
     * into it. See setTakeOwnedship() for more details.
349
     */
350
    bool getTakeOwnership() const   {return flags&FL_TKOWNERSHIP;}
351
    //@}
352
};
353

    
354
NAMESPACE_END
355

    
356

    
357
#endif
358