HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GA_Iterator.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_Iterator.h (GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_Iterator__
12 #define __GA_Iterator__
13 
14 #include "GA_API.h"
15 #include "GA_IndexMap.h"
16 #include "GA_IteratorState.h"
17 #include "GA_Range.h"
18 #include "GA_Types.h"
19 #include <UT/UT_Assert.h>
20 
21 
22 /// @brief Iteration over a range of elements
23 ///
24 /// An iterator is used to iterate over the elements of a given range. All
25 /// state information for the iteration is stored by the iterator, external
26 /// to the range in question. All iterators are constructed rewound, so in
27 /// most cases there is no need for an explicit rewind() call.
29 {
30 public:
31  GA_Iterator();
32  explicit GA_Iterator(const GA_Range &range);
33  /// Ensure safe iteration if elements from the range are deleted during
34  /// traversal.
36  GA_Iterator(const GA_Iterator &iterator);
37  /// The end-condition iterator
39  : myRange()
40  , myState()
41  , myCurrent(GA_INVALID_OFFSET)
42  , myEnd(GA_INVALID_OFFSET)
43  , myEndIterator(true)
44  {}
45  ~GA_Iterator();
46 
47  /// Test to see whether the iterator is valid
48  bool isValid() const { return myRange.isValid(); }
49 
50  /// @{
51  /// Standard operators
52  const GA_Iterator &operator=(const GA_Iterator &src);
53  bool operator==(const GA_Iterator &src) const;
54  bool operator!=(const GA_Iterator &src) const
55  { return !(*this == src); }
56  /// @}
57 
58  /// Query the element type that is being iterated over
60  {
61  return myRange.getOwner();
62  }
63 
64  /// @{
65  /// Query state of the iterator
67  {
68  UT_ASSERT_P(!atEnd());
69  return myCurrent;
70  }
72  {
73  UT_ASSERT_P(!atEnd());
74  return myCurrent;
75  }
76  /// @}
77 
78  /// @{
79  /// Query the ordered index for the current state. Note that this will
80  /// perform a lookup into the index map, which may not be extremely
81  /// efficient.
83  {
84  UT_ASSERT_P(!atEnd());
85  if (!myEndIterator && myRange.getRTI())
86  {
87  return myRange.getRTI()->getIndexMap().indexFromOffset(myCurrent);
88  }
89  return GA_INVALID_INDEX;
90  }
91  /// @}
92 
93  /// @{
94  /// Standard iterator methods.
95  /// @warning We do not have a post-increment as it would have to
96  /// be written in a side-effect free way that would cause problmse.
97  /// @note All non-default constructors call rewind() already, so an
98  /// explicit call is usually not needed.
99  void rewind();
100  bool atEnd() const { return myEndIterator || myCurrent >= myEnd; }
101  void advance()
102  {
103  UT_ASSERT_P(!atEnd());
104  myCurrent++;
105  if (myCurrent == myEnd)
106  {
107  // We hit the end of our cached block, so iterate to the next block
108  myRange.iterateNext(myState, myCurrent, myEnd);
109  }
110  }
111  GA_Iterator &operator++() { advance(); return *this; }
112  /// @}
113 
114  /// Perform a block iteration. The block iteration will provide a
115  /// contiguous block of offsets which can be operated upon in batch.
116  /// Blocks are constrained to occupy a single page, so no block can
117  /// cross a page boundary. Consequently contiguous sequences that
118  /// cross page boundaries are automatically split into multiple blocks.
119  /// The (start, end] range is like Python in that @c start is included
120  /// in the range, but @c end is not. For example:@code
121  /// for (it.rewind(); iterator.blockAdvance(start, end); )
122  /// for (; start < end; ++start)
123  /// operation(start);
124  /// @endcode
125  bool blockAdvance(GA_Offset &start, GA_Offset &end);
126 
127  /// Like blockAdvance, except that the block isn't guaranteed to be
128  /// all within one page. The block is the maximum contiguous block
129  /// returned by the GA_Range.
130  bool fullBlockAdvance(GA_Offset &start, GA_Offset &end);
131 
132 private:
133  GA_Range myRange;
134  GA_IteratorState myState;
135  GA_Offset myCurrent, myEnd; // Block information
136  bool myEndIterator;
137 };
138 
139 #endif
GA_Offset operator*() const
Definition: GA_Iterator.h:71
GLenum GLint * range
Definition: glcorearb.h:1924
Iteration over a range of elements.
Definition: GA_Iterator.h:28
GA_Iterator(GA_Range::enditerator)
The end-condition iterator.
Definition: GA_Iterator.h:38
bool isValid() const
Test to see whether the iterator is valid.
Definition: GA_Iterator.h:48
GLuint start
Definition: glcorearb.h:474
GA_AttributeOwner getOwner() const
Query the element type that is being iterated over.
Definition: GA_Iterator.h:59
#define GA_API
Definition: GA_API.h:12
GA_Offset getOffset() const
Definition: GA_Iterator.h:66
bool operator!=(const GA_Iterator &src) const
Definition: GA_Iterator.h:54
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_Index getIndex() const
Definition: GA_Iterator.h:82
GA_Size GA_Offset
Definition: GA_Types.h:617
bool atEnd() const
Definition: GA_Iterator.h:100
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
GLuint GLuint end
Definition: glcorearb.h:474
GA_Iterator & operator++()
Definition: GA_Iterator.h:111
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
GA_AttributeOwner
Definition: GA_Types.h:33
#define GA_INVALID_INDEX
Definition: GA_Types.h:653
void advance()
Definition: GA_Iterator.h:101
GLenum src
Definition: glcorearb.h:1792