This file is indexed.

/usr/include/falcon/iterator.h is in falconpl-dev 0.9.6.9-git20120606-2.1+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
   FALCON - The Falcon Programming Language.
   FILE: iterator.h

   Base abstract class for generic collection iterators.
   -------------------------------------------------------------------
   Author: Giancarlo Niccolai
   Begin: Sat, 01 Aug 2009 23:24:09 +0200

   -------------------------------------------------------------------
   (C) Copyright 2004: the FALCON developers (see list in AUTHORS file)

   See LICENSE file for licensing details.
*/

/** \file
   Base abstract class for generic collection iterators.
*/

#ifndef flc_iterator_H
#define flc_iterator_H

#include <falcon/setup.h>
#include <falcon/types.h>
#include <falcon/falcondata.h>
#include <falcon/sequence.h>
#include <falcon/fassert.h>

namespace Falcon {
class Sequence;
class CoreTable;
class Garbageable;
class Item;

/**
   Base abstract class for generic Item sequence/collection iterators.
   
   Iterators and sequences cooperate so that:
   - The iterator provides a common non-abstract non-virtual interface
     to access sequentially sequences of different nature.
   - The underlying sequence provides the virtual functionalities needed
     to access itself and receive orders from its own iterators.
     
   A common usage pattern may be:
   \code
   // ItemArray() supports the sequence interface.
   Sequence* seq = &some_item.asArray()->items();
   ...
   Iterator iter( seq ); // starts at begin.
   while( iter.hasCurrent() )   // while we have some element
   {
      Item& current = iter.getCurrent();
      // ... do something
      
      iter.next()
   }
   \endcode
   
   Iterators support the FalconData interface, so they can be set directly
   as inner data for FalconObject (i.e. Falcon script level iterator instances),
   or be guarded by the garbage collector via the GCPointer garbage pointer shells.
   
   In that case, instead of having iterators in the stack, it's possible to have
   them in the heap (allocated with "new"). 
   
   Iterators can be deleted via a simple delete.
   
   Iterators forward their gcMark() call to the sequence they are linked to, so
   if the sequence is part of a garbage sensible data (CoreArray, CoreObject, GCPointer etc.), 
   the item stays alive untill all the iterators are gone. 
   
   If a sequence is autonomously destroyed (i.e. via an explicit delete on a non-garbage
   sensible data), all the iterators on that sequence are "invalidated".
   
   Iterators are invalidated also when the sequence is changed so that the values
   of some or all iterators become no more valid (i.e. iterators to array or to paged
   maps).
   
   Invalidated iterators do not point to any sequence anymore, and calling any of their
   member except for disposal or isValid() causes a crash.
   
   Iterators are usually able to refer to the target sequence without the need for
   local structures. When this is not possible, their data member is filled with some
   structure specific iterator data, and their deletor() function is set to a function
   that can collect this deep reference data when the iterator is destroyed. As this
   function is totally independent from the source sequence, even deep iterators can
   be destroyed after their sequence has been destroyed, and they have been invalidated.
  
   If the iterator is destroyed while still valid (i.e. because of stack unroll), the
   Sequence::disposeIterator() callback method of the owner sequence is called; this
   gives the sequence the chance to de-account the iterator (and it's usually done in
   the Sequence base class). The disposeIterator() callback must NEVER destroy deep
   data in the iterator, which is done by the deletor() callback as a separate step.
   
   \note The Sequence-iterator pattern works well when there are a limited number of
         active iterator per sequence (1 to 3), which is a common practical usage in 
         many cases. \b Avoid using an iterator-per-item strategy (i.e. back-referenced
         sequence items, able to delete themselves via an erase on their iterator). 
*/
class FALCON_DYN_CLASS Iterator: public FalconData
{

public:
   typedef void(*t_deletor_func)(Iterator*);

private:
   Sequence* m_owner;

   typedef union t_position_holder {
      int64 pos;
      void* ptr;
   } u_idata;

   u_idata m_idata;

   t_deletor_func m_deletor;
   Iterator* m_next;

public:
   Iterator( Sequence* owner, bool tail = false ):
      m_owner( owner ),
      m_deletor(0),
      m_next(0)
   {
      m_idata.ptr = 0;
      owner->getIterator( *this, tail );
   }

   Iterator( const Iterator& other ):
      m_owner( other.m_owner ),
      m_deletor( other.m_deletor ),
      m_next(0)
   {
      m_idata.ptr = 0;
      m_owner->copyIterator( *this, other );
   }


public:
   virtual ~Iterator();
   virtual void gcMark( uint32 mark );
   virtual Iterator *clone() const;

   /** Sets a deep deletor for this iterator.
      Should be called by the Sequence::getIterator and Sequence::copyIterator
      re-implementations in case this iterator is given a deep data that
      must be deleted at termination.
      
      If non-zero, this callback is called at iterator destruction.
   */
   void deletor( t_deletor_func f ) { m_deletor = f; }
   t_deletor_func deletor() const { return m_deletor; }
   /** Advance to the next item.
    * \return false if the iterator couldn't be advanced (because invalid or at end).
    */
   inline bool next() {
      fassert( m_owner != 0 );
      return m_owner->next( *this );
   }

   /** Retreat to the previous item.
    * \return false if the iterator couldn't be retreated (because invalid or at begin).
    */
   inline bool prev() {
      fassert( m_owner != 0 );
      return m_owner->prev( *this );
   }

   inline bool hasNext() const {
      return m_owner != 0 && m_owner->hasNext( *this );
   }

   inline bool hasPrev() const {
      return m_owner != 0 && m_owner->hasPrev( *this );
   }

   /** True if this iterator has a current element.
    *
    * Iterators past the last element (at end) are still valid, but they can't be used
    * to access a current element.
    */
   inline bool hasCurrent() const {
      return m_owner != 0 && m_owner->hasCurrent( *this );
   }

   /** Must be called after an isValid() check */
   inline Item &getCurrent() const {
      fassert( m_owner != 0 );
      return m_owner->getCurrent( *this );
   }

   /** Must be called after an isValid() check.
    * Calling this on non-dictionary sequences will cause an AccessError to be thrown.
    *  */
   inline Item &getCurrentKey() const {
      fassert( m_owner != 0 );
      return m_owner->getCurrentKey( *this );
   }

   inline bool isValid() const { return m_owner != 0; }
   inline bool isOwner( void *collection ) const { return collection == static_cast<void*>(m_owner); }

   inline bool equal( const Iterator &other ) const {
      fassert( m_owner != 0 );
      return m_owner == other.m_owner && m_owner->equalIterator( *this, other );
   }

   /** Erase an element pointed by this iterator.

      This erases the element in the sequence pointed by this iterator.
      the iterator is moved to the next element, or if this was the last
      element in the collection, it points to past-end.

      The operation may or may not invalidate the other iterators on the sequence,
      depending on the nature of the sequecne; however, the iterator itself it's granted
      to stay valid.
   */
   inline void erase() {
      fassert( m_owner != 0 );
      m_owner->erase( *this );
   }

   /** Insert an item at current position in a non-dictionary sequence.
    Calling this on a dictionary sequence will cause an AccessError to be thrown.

    The item is insert before the position to which the iterator points.
    If the iterator isValid() but not hasCurrent(), insertion is at past end (append).

    After the insert, the iterator is not moved (still points to the same element).
    **/
   inline void insert( const Item &item ) {
      fassert( m_owner != 0 );
      m_owner->insert( *this, item );
   }

   /** Turns this in an invalid iterator.
    * Notice that invalid iterators doesn't back-mark their owner.
    */
   void invalidate() { m_owner = 0; }

   Sequence* sequence() const { return m_owner; }

   void sequence( Sequence* s ) { m_owner = s; }

   void *data() const { return m_idata.ptr; }
   void data( void* dt ) { m_idata.ptr = dt; }

   int64 position() const { return m_idata.pos; }
   void position( int64 pos ) { m_idata.pos = pos; }
   
   Iterator* nextIter() const { return m_next; }
   void nextIter( Iterator* n )
   {
      fassert( n != this );
      m_next = n;
   }

   inline void goTop() {
      m_owner->getIterator( *this );
   }

   inline void goBottom() {
      m_owner->getIterator( *this, true );
   }
};

}

#endif /* ITERATOR_H_ */