source: XIOS/dev/dev_olga/src/extern/blitz/include/blitz/range.h @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 9.4 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/range.h      Declaration of the Range class
4 *
5 * $Id$
6 *
7 * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
8 *
9 * This file is a part of Blitz.
10 *
11 * Blitz is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3
14 * of the License, or (at your option) any later version.
15 *
16 * Blitz is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 * Suggestions:          blitz-devel@lists.sourceforge.net
25 * Bugs:                 blitz-support@lists.sourceforge.net   
26 *
27 * For more information, please see the Blitz++ Home Page:
28 *    https://sourceforge.net/projects/blitz/
29 *
30 ***************************************************************************/
31
32#ifndef BZ_RANGE_H
33#define BZ_RANGE_H
34
35
36#include <blitz/blitz.h>
37#include <blitz/etbase.h>
38#include <blitz/array/asexpr.h>
39#include <blitz/prettyprint.h>
40#include <blitz/tinyvec2.h>
41#include <climits>                  // for INT_MIN, INT_MAX
42
43BZ_NAMESPACE(blitz)
44
45// A Range object is an ET that generates the specified sequence.
46
47// Examples:
48// Array<int,1> A(7);
49// A = 0,1,2,3,4,5,6;
50// A(Range::all());                   [0,1,2,3,4,5,6]
51// A(Range(3,5));                     [3,4,5]
52// A(Range(3,toEnd));                 [3,4,5,6]
53// A(Range(fromStart,3));             [0,1,2,3]
54// A(Range(1,5,2));                   [1,3,5]
55// A(Range(5,1,-2));                  [5,3,1]
56// A(Range(fromStart,toEnd,2));       [0,2,4,6]
57
58template<int N_rank> class RectDomain;
59class nilArraySection;
60
61const int fromStart = INT_MIN;
62const int toEnd = INT_MAX;
63
64// Class Range
65class Range : public ETBase<Range> {
66public:
67    typedef int T_numtype;
68  typedef opType<T_numtype>::T_optype T_optype;
69
70  typedef asET<T_numtype>::T_wrapped T_typeprop;
71  typedef unwrapET<T_typeprop>::T_unwrapped T_result;
72
73    typedef void T_ctorArg1;
74    typedef char       T_ctorArg2;    // dummy
75  typedef TinyVector<int, 1> T_index;
76  typedef Range T_range_result;
77    static const int 
78    numArrayOperands = 0, 
79        numTVOperands = 0, 
80        numTMOperands = 0,
81      numIndexPlaceholders = 1, 
82      minWidth = simdTypes<T_numtype>::vecWidth,
83      maxWidth = simdTypes<T_numtype>::vecWidth,
84      rank_ = 1;
85
86  /** The vectorized return type for a Range should be another range,
87      but that's not useful since a vectorized TinyVector assignment
88      can not contain index placeholders. In fact, since vectorization
89      doesn't work for index expressions anyway, we can just set this
90      to a dummy. */
91  template<int N> struct tvresult {
92    typedef FastTV2Iterator<T_numtype, N> Type;
93  };
94
95    Range()
96    {
97        first_ = fromStart;
98        last_ = toEnd;
99        stride_ = 1;
100    }
101
102    Range(const Range& r)
103    {
104        first_ = r.first_;
105        last_ = r.last_;
106        stride_ = r.stride_;
107    }
108
109    explicit Range(T_numtype slicePosition)
110    {
111        first_ = slicePosition;
112        last_ = slicePosition;
113        stride_ = 1;
114    }
115
116    Range(T_numtype first, T_numtype last, diffType stride=1)
117        : first_(first), last_(last), stride_(stride)
118    { 
119        BZPRECHECK((first == fromStart) || (last == toEnd) ||
120            ((first < last) && (stride > 0)) ||
121            ((first > last) && (stride < 0)) ||
122            (first == last), (*this) << " is an invalid range.");
123        BZPRECHECK((first == fromStart) || (last == toEnd) ||
124            (last-first) % stride == 0,
125            (*this) << ": the stride must evenly divide the range");
126    }
127
128  T_numtype operator*()   const { BZPRECONDITION(0); return 0; }
129  T_numtype first_value() const { BZPRECONDITION(0); return 0; }
130
131    int ascending(const int) const { return true; }
132    int ordering(const int)  const { return 0; }
133    int lbound(const int)    const { return 0; }
134  int ubound(const int)    const { return length()-1; }
135
136  RectDomain<rank_> domain() const;
137
138  bool assertInRange(const T_index& BZ_DEBUG_PARAM(index)) const;
139 
140#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
141    template<int N_rank>
142    T_numtype operator()(const TinyVector<int,N_rank> i) const
143  { assertInRange(i); return operator[](i[0]); }
144#else
145    template<int N_rank>
146    T_numtype operator()(const TinyVector<int,N_rank>& i) const
147  { assertInRange(i); return operator[](i[0]); }
148#endif
149
150  T_numtype operator[](int i) const;
151
152    T_numtype operator()(int i) const
153    {
154      return operator[](i);
155    }
156
157  // we could work out how this should work.
158  template<int N_rank>
159  const Range operator()(const RectDomain<N_rank>& d) const
160  {
161    BZPRECONDITION(0); return *this;
162  }
163
164    void push(int) { }
165    void pop(int) { }
166    void advance() { }
167    void advance(int) { }
168    void loadStride(int) { }
169
170    bool isUnitStride(int) const
171  { BZPRECONDITION(0); return 0; }
172
173    void advanceUnitStride()
174    { }
175
176    bool canCollapse(int,int) const 
177    { return true; }
178
179    T_numtype fastRead(diffType) const
180  { BZPRECONDITION(0); return 0; }
181
182  template<int N>
183  typename tvresult<N>::Type fastRead_tv(diffType) const
184  { BZPRECONDITION(0); return 0; }
185
186  // this is needed for the stencil expression fastRead to work
187  void _bz_offsetData(sizeType i) const{BZPRECONDITION(0);};
188
189    // and these are needed for stencil expression shift to work
190  void _bz_offsetData(sizeType offset, int dim) const {BZPRECONDITION(0);};
191 
192  void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim2) const {BZPRECONDITION(0);};
193
194    diffType suggestStride(int) const
195    { return 1; }
196
197    bool isStride(int,diffType) const
198    { return true; }
199
200  void moveTo(int) const { BZPRECONDITION(0); }
201
202  T_numtype shift(int offset, int dim) const { 
203    BZPRECONDITION(0); return T_numtype(); }
204
205    T_numtype shift(int offset1, int dim1,int offset2, int dim2) const 
206  { BZPRECONDITION(0); return T_numtype(); }
207
208    template<int N_rank>
209    void moveTo(const TinyVector<int,N_rank>&) const { BZPRECONDITION(0); }
210
211    void prettyPrint(BZ_STD_SCOPE(string) &str, 
212        prettyPrintFormat& format) const
213    {
214#ifdef BZ_HAVE_STD
215            BZ_STD_SCOPE(ostringstream) ostr;
216#else
217            ostrstream ostr;
218#endif
219            ostr << "Range(" << first_ << ", " << last_
220                 << ", " << stride_ << ")";
221            str += ostr.str();
222    }
223
224
225  // old range stuff below. what is needed for the range interface and
226  // what is old vecexpr stuff?
227
228    T_numtype first(T_numtype lowRange = 0) const
229    { 
230        if (first_ == fromStart)
231            return lowRange;
232        return first_; 
233    }
234
235    T_numtype last(T_numtype highRange = 0) const
236    {
237        if (last_ == toEnd)
238            return highRange;
239        return last_;
240    }
241
242  int length(int =0) const
243    {
244        BZPRECONDITION(first_ != fromStart);
245        BZPRECONDITION(last_ != toEnd);
246        BZPRECONDITION((last_ - first_) % stride_ == 0);
247        return (last_ - first_) / stride_ + 1;
248    }
249
250    diffType stride() const
251    { return stride_; }
252
253    bool isAscendingContiguous() const
254    {
255        return (((first_ < last_) && (stride_ == 1)) || (first_ == last_));
256    }
257
258    void setRange(T_numtype first, T_numtype last, diffType stride=1)
259    {
260        BZPRECONDITION(((first < last) && (stride > 0)) ||
261            ((first > last) && (stride < 0)) ||
262            (first == last));
263        BZPRECONDITION((last-first) % stride == 0);
264        first_ = first;
265        last_ = last;
266        stride_ = stride;
267    }
268
269    static Range all() 
270    { return Range(fromStart,toEnd,1); }
271
272  /// \todo this talks about the stride of the RANGE, not the expression stride.
273    bool isUnitStride() const
274    { return stride_ == 1; }
275
276    // Operators
277    Range operator-(T_numtype shift) const
278    { 
279        BZPRECONDITION(first_ != fromStart);
280        BZPRECONDITION(last_ != toEnd);
281        return Range(first_ - shift, last_ - shift, stride_); 
282    }
283
284    Range operator+(T_numtype shift) const
285    { 
286        BZPRECONDITION(first_ != fromStart);
287        BZPRECONDITION(last_ != toEnd);
288        return Range(first_ + shift, last_ + shift, stride_); 
289    }
290
291    friend inline ostream& operator<<(ostream& os, const Range& range)
292    {
293        os << "Range(" << range.first() << "," << range.last() << ","
294           << range.stride() << ")";
295
296        return os;
297    }
298
299  // we can't reduce the rank of a range, so we can't slice it
300  template<typename T1, typename T2 = nilArraySection, 
301           class T3 = nilArraySection, typename T4 = nilArraySection, 
302           class T5 = nilArraySection, typename T6 = nilArraySection, 
303           class T7 = nilArraySection, typename T8 = nilArraySection, 
304           class T9 = nilArraySection, typename T10 = nilArraySection, 
305           class T11 = nilArraySection>
306  class SliceInfo {
307  public:
308    typedef void T_slice;
309  };
310
311    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
312        typename T7, typename T8, typename T9, typename T10, typename T11>
313    typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice
314    operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const
315    {
316      return *this;
317    }
318
319private:
320  T_numtype first_, last_;
321  diffType stride_;
322};
323
324BZ_NAMESPACE_END
325
326#endif // BZ_RANGE_H
Note: See TracBrowser for help on using the repository browser.