source: XMLIO_V2/external/include/blitz/array/iter.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/array/iter.h  Basic iterator for arrays.
4 *
5 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * Suggestions:          blitz-dev@oonumerics.org
18 * Bugs:                 blitz-bugs@oonumerics.org
19 *
20 * For more information, please see the Blitz++ Home Page:
21 *    http://oonumerics.org/blitz/
22 *
23 ****************************************************************************/
24#ifndef BZ_ARRAY_H
25 #error <blitz/array/iter.h> must be included via <blitz/array.h>
26#endif
27
28#ifndef BZ_ARRAY_ITER_H
29#define BZ_ARRAY_ITER_H
30
31#ifdef BZ_HAVE_STL
32#include <iterator>
33#endif
34
35BZ_NAMESPACE(blitz)
36
37// helper class ConstPointerStack
38template<typename P_numtype, int N_rank>
39class ConstPointerStack {
40public:
41    typedef P_numtype                T_numtype;
42
43    void operator=(const ConstPointerStack<P_numtype,N_rank>& rhs) 
44    {
45        for (int i=0; i<N_rank; ++i)
46            stack_[i] = rhs.stack_[i];
47    }
48
49    const T_numtype*& operator[](int position)
50    {
51        return stack_[position];
52    }
53     
54private:
55    const T_numtype *                stack_[N_rank];
56};
57
58
59template<typename T, int N>
60class ConstArrayIterator {
61public:
62    ConstArrayIterator() : data_(0) { }
63
64    ConstArrayIterator(const Array<T,N>& array)
65    {
66        // Making internal copies of these avoids keeping
67        // a pointer to the array and doing indirection.
68        strides_ = array.stride();
69        lbound_ = array.lbound();
70        extent_ = array.extent();
71        order_ = array.ordering();
72        data_ = const_cast<T*>(array.dataFirst());
73
74        maxRank_ = order_(0);
75        stride_ = strides_(maxRank_);
76
77        for (int i=0; i < N; ++i)
78        {
79            stack_[i] = data_;
80            last_[i] = data_ + extent_(order_(i)) * strides_(order_(i));
81        }
82
83        pos_ = lbound_;
84    }
85
86    bool operator==(const ConstArrayIterator<T,N>& x) const 
87    { 
88        return data_ == x.data_; 
89    }
90   
91    bool operator!=(const ConstArrayIterator<T,N>& x) const 
92    { 
93        return data_ != x.data_; 
94    }
95 
96    const T& operator*() const
97    {
98        BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator "
99             << "(empty array or past end of array)");
100        return *data_;
101    }
102
103    const T* restrict operator->() const
104    {
105        BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator "
106             << "(empty array or past end of array)");
107        return data_;
108    }
109
110    ConstArrayIterator<T,N>& operator++();
111
112    ConstArrayIterator<T,N> operator++(int)
113    {
114        ConstArrayIterator<T,N> tmp = *this;
115        ++(*this); 
116        return tmp;
117    }
118
119    // get the current position of the Array iterator in index space
120    const TinyVector<int,N>& position() const
121    { 
122        BZPRECHECK(data_ != 0, "Array<T,N>::iterator::position() called on"
123             << " invalid iterator");
124        return pos_; 
125    }
126   
127private:
128    TinyVector<int,N> strides_, lbound_, extent_, order_;
129    ConstPointerStack<T,N> stack_;
130    ConstPointerStack<T,N> last_;
131    int stride_;
132    int maxRank_;
133
134protected:
135    TinyVector<int,N> pos_;
136    T * restrict data_;
137};
138
139
140template<typename T, int N>
141class ArrayIterator : public ConstArrayIterator<T,N> {
142private:
143    typedef ConstArrayIterator<T,N> T_base;
144    using T_base::data_;
145
146public:
147    ArrayIterator() { }
148
149    ArrayIterator(Array<T,N>& x) : T_base(x) { }
150
151    T& operator*() const
152    {
153        BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator "
154             << "(empty array or past end of array)");
155        return *data_;
156    }
157
158    T* restrict operator->() const
159    {
160        BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator "
161             << "(empty array or past end of array)");
162        return data_;
163    }
164
165    ArrayIterator<T,N>& operator++()
166    {
167        T_base::operator++();
168        return *this;
169    }
170
171    ArrayIterator<T,N> operator++(int)
172    {
173        ArrayIterator<T,N> tmp = *this;
174        ++(*this); 
175        return tmp;
176    }
177};
178
179
180template<typename T, int N>
181ConstArrayIterator<T,N>& ConstArrayIterator<T,N>::operator++()
182{
183    BZPRECHECK(data_ != 0, "Attempted to iterate past the end of an array.");
184
185    data_ += stride_;
186
187    if (data_ != last_[0])
188    {
189        // We hit this case almost all the time.
190        ++pos_[maxRank_];
191        return *this;
192    }
193
194    // We've hit the end of a row/column/whatever.  Need to
195    // increment one of the loops over another dimension.
196
197    int j = 1;
198    for (; j < N; ++j)
199    {
200        int r = order_(j);
201        data_ = const_cast<T*>(stack_[j]);
202        data_ += strides_[r];
203        ++pos_(r);
204
205        if (data_ != last_[j])
206            break;
207    }
208
209    // All done?
210    if (j == N)
211    {
212        // Setting data_ to 0 indicates the end of the array has
213        // been reached, and will match the end iterator.
214        data_ = 0;
215        return *this;
216    }
217
218    stack_[j] = data_;
219
220    // Now reset all the last pointers
221    for (--j; j >= 0; --j)
222    {
223        int r2 = order_(j);
224        stack_[j] = data_;
225        last_[j] = data_ + extent_(r2) * strides_(r2);
226        pos_(r2) = lbound_(r2);
227    }
228
229    return *this;
230}
231
232
233BZ_NAMESPACE_END
234
235
236#ifdef BZ_HAVE_STL
237// support for std::iterator_traits
238BZ_NAMESPACE(std)
239
240template <typename T, int N>
241struct iterator_traits< BZ_BLITZ_SCOPE(ConstArrayIterator)<T,N> > 
242{
243    typedef forward_iterator_tag               iterator_category;
244    typedef T                                  value_type;
245    typedef ptrdiff_t                          difference_type;
246    typedef const T*                           pointer;
247    typedef const T&                           reference;
248};
249
250template <typename T, int N>
251struct iterator_traits< BZ_BLITZ_SCOPE(ArrayIterator)<T,N> > 
252{
253    typedef forward_iterator_tag               iterator_category;
254    typedef T                                  value_type;
255    typedef ptrdiff_t                          difference_type;
256    typedef T*                                 pointer;
257    typedef T&                                 reference;
258};
259
260BZ_NAMESPACE_END
261
262#endif // BZ_HAVE_STL
263
264#endif // BZ_ARRAY_ITER_H
265
Note: See TracBrowser for help on using the repository browser.