summaryrefslogtreecommitdiffstats
path: root/raslib/miterd.hh
blob: a4c26d1bd2c0c4f7a5a8143f61e3cedf89ff06e5 (plain)
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
/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see <http://www.rasdaman.org>
* or contact Peter Baumann via <baumann@rasdaman.com>.
/
/**
 * INCLUDE: miterd.hh
 *
 * MODULE:  raslib
 * CLASS:   r_MiterDirect
 *
*/

#ifndef _R_MITERD_
#define _R_MITERD_

#include "raslib/mddtypes.hh"
#include "raslib/odmgtypes.hh"

#include <iosfwd>

class r_Minterval;

class r_miter_direct_data;

//@ManMemo: Module {\bf raslib}

/*@Doc:
  r_MiterDirect is similar to r_Miter, but allows stepping by more
  than one cell in each direction, arbitrary order of dimensions in
  the iteration and has a lot of its internal state variables as public
  members.
  It should be used in low-level, very time-critical code like
  folding operations which would otherwise require construction
  of a new iterator for each cell when only position and base
  address need to change.
*/

class r_MiterDirect
{
  public:
  /// constructor
  r_MiterDirect(void *data, const r_Minterval &total, const r_Minterval &iter,
		r_Bytes tlen, unsigned int step=1);
  /**
     constructor getting the data, the total domain, the iteration
     domain, the base type length and the number of steps per
     iteration.
  */

  /// destructor
  ~r_MiterDirect(void);

  /// increment the iterator in the default order, i.e. last dimension first
  inline r_MiterDirect &operator++(void);
  /// increment in user-specified order
  inline r_MiterDirect &iterateUserOrder(const r_Dimension *order, const unsigned int *step);
  /**
     increment the iterator in a user-specified order. order points to an array
     defining the order of the dimensions during iteration, e.g. for a 3D
     iteration 0,1,2 would iterate over the first dimension first and the
     last dimension last wheres 2,1,0 is equivalent to operator++(). step
     is the number of steps to do in each dimension.
  */
  /// increment or decrement in user-specified order
  inline r_MiterDirect &iterateUserOrder(const unsigned int *order, const int *step);
  /**
     see the other incrementUserOrder method for more details
  */

  /// returns != 0 if iteration is finished.
  inline bool isDone(void) const;
  /// returns pointer to data during normal iteration.
  inline void* getData(void);
  /// return pointer to data for non-standard iteration order
  inline void* getData(unsigned int *order);
  /**
     returns pointer to data during user-defined iteration; order is as
     defined in iterateUserOrder().
  */
  /// returns number of bytes to step in dimension d in one iteration
  inline r_Range getDimStep(r_Dimension d) const;
  /// returns number of bytes to step in dimension d when pos changes by 1.
  inline r_Bytes getDimBaseStep(r_Dimension d) const;
  /// returns extent in dimension d
  inline r_Range getExtent(r_Dimension d) const;
  /// notify that the position was changed and internal variables need to be recalculated
  inline void posChanged( void );
  /// reset the iterator (pos to low and data to baseAddress + offset)
  void reset(void);
  /// print the position
  void print_pos(std::ostream &str) const;

  bool done;
  r_miter_direct_data* id;
  void* baseAddress;

  private:

  /// if this data should change you must construct a new iterator,
  /// therefore no public access.
  r_Dimension dim;
  r_ULong length;
};



/*@Doc:
  r_miter_direct_data encapsulates data for each dimension.
  It's an auxiliary class for r_MiterDirect. The only reason
  not to make it a simple struct was data protection.
 */

class r_miter_direct_data
{
  friend class r_MiterDirect;

  public:

  r_miter_direct_data();
  ~r_miter_direct_data();

  /// Data concerning the iteration position and domain. May
  /// be changed by the user.
  void *data;
  r_Range pos;
  r_Range low;
  r_Range high;

  private:

  /// Data concerning the domain of the source object. Is fixed
  /// in the constructor.
  r_Range step;
  r_Range baseStep;
  r_Range extent;
  r_Range origin;
};


/// overloaded stream operator
extern std::ostream &operator<<(std::ostream &str, const r_MiterDirect &iter);



#include "raslib/miterd.icc"

#endif