2
2
/***************************************************************************
3
3
* blitz/range.h Declaration of the Range class
5
* $Id: range.h,v 1.9 2005/05/07 04:17:56 julianc Exp $
7
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
7
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
9
* This file is a part of Blitz.
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
12
14
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
16
* Blitz is distributed in the hope that it will be useful,
15
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* GNU Lesser General Public License for more details.
19
* Suggestions: blitz-dev@oonumerics.org
20
* Bugs: blitz-bugs@oonumerics.org
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/>.
24
* Suggestions: blitz-devel@lists.sourceforge.net
25
* Bugs: blitz-support@lists.sourceforge.net
22
27
* For more information, please see the Blitz++ Home Page:
23
* http://oonumerics.org/blitz/
28
* https://sourceforge.net/projects/blitz/
25
30
***************************************************************************/
31
#include <blitz/blitz.h>
34
#ifndef BZ_VECEXPRWRAP_H
35
#include <blitz/vecexprwrap.h> // _bz_VecExpr wrapper
38
#include <blitz/wrap-climits.h> // for INT_MIN
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
40
43
BZ_NAMESPACE(blitz)
45
// A Range object is an ET that generates the specified sequence.
43
// Vector<double> x(7);
44
// Range::all() [0,1,2,3,4,5,6]
46
// Range(3,Range::toEnd) [3,4,5,6]
47
// Range(Range::fromStart,3) [0,1,2,3]
48
// Range(1,5,2); [1,3,5]
50
enum { fromStart = INT_MIN, toEnd = INT_MIN };
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]
58
template<int N_rank> class RectDomain;
59
class nilArraySection;
61
const int fromStart = INT_MIN;
62
const int toEnd = INT_MAX;
65
class Range : public ETBase<Range> {
56
// This declaration not yet supported by all compilers
57
// const int fromStart = INT_MIN;
58
// const int toEnd = INT_MIN;
60
67
typedef int T_numtype;
62
enum { fromStart = INT_MIN, toEnd = INT_MIN };
68
typedef opType<T_numtype>::T_optype T_optype;
70
typedef asET<T_numtype>::T_wrapped T_typeprop;
71
typedef unwrapET<T_typeprop>::T_unwrapped T_result;
73
typedef void T_ctorArg1;
74
typedef char T_ctorArg2; // dummy
75
typedef TinyVector<int, 1> T_index;
76
typedef Range T_range_result;
81
numIndexPlaceholders = 1,
82
minWidth = simdTypes<T_numtype>::vecWidth,
83
maxWidth = simdTypes<T_numtype>::vecWidth,
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
91
template<int N> struct tvresult {
92
typedef FastTV2Iterator<T_numtype, N> Type;
71
// Range(Range r): allow default copy constructor to be used
72
#ifdef BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR
73
102
Range(const Range& r)
75
104
first_ = r.first_;
77
106
stride_ = r.stride_;
81
explicit Range(int slicePosition)
109
explicit Range(T_numtype slicePosition)
83
111
first_ = slicePosition;
84
112
last_ = slicePosition;
88
Range(int first, int last, int stride=1)
116
Range(T_numtype first, T_numtype last, diffType stride=1)
89
117
: first_(first), last_(last), stride_(stride)
91
119
BZPRECHECK((first == fromStart) || (last == toEnd) ||
92
(first < last) && (stride > 0) ||
93
(first > last) && (stride < 0) ||
94
(first == last), (*this) << " is an invalid range.");
95
BZPRECHECK((last-first) % stride == 0,
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,
96
125
(*this) << ": the stride must evenly divide the range");
99
int first(int lowRange = 0) const
128
T_numtype operator*() const { BZPRECONDITION(0); return 0; }
129
T_numtype first_value() const { BZPRECONDITION(0); return 0; }
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; }
136
RectDomain<rank_> domain() const;
138
bool assertInRange(const T_index& BZ_DEBUG_PARAM(index)) const;
140
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
142
T_numtype operator()(const TinyVector<int,N_rank> i) const
143
{ assertInRange(i); return operator[](i[0]); }
146
T_numtype operator()(const TinyVector<int,N_rank>& i) const
147
{ assertInRange(i); return operator[](i[0]); }
150
T_numtype operator[](int i) const;
152
T_numtype operator()(int i) const
154
return operator[](i);
157
// we could work out how this should work.
159
const Range operator()(const RectDomain<N_rank>& d) const
161
BZPRECONDITION(0); return *this;
167
void advance(int) { }
168
void loadStride(int) { }
170
bool isUnitStride(int) const
171
{ BZPRECONDITION(0); return 0; }
173
void advanceUnitStride()
176
bool canCollapse(int,int) const
179
T_numtype fastRead(diffType) const
180
{ BZPRECONDITION(0); return 0; }
183
typename tvresult<N>::Type fastRead_tv(diffType) const
184
{ BZPRECONDITION(0); return 0; }
186
// this is needed for the stencil expression fastRead to work
187
void _bz_offsetData(sizeType i) const{BZPRECONDITION(0);};
189
// and these are needed for stencil expression shift to work
190
void _bz_offsetData(sizeType offset, int dim) const {BZPRECONDITION(0);};
192
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim2) const {BZPRECONDITION(0);};
194
diffType suggestStride(int) const
197
bool isStride(int,diffType) const
200
void moveTo(int) const { BZPRECONDITION(0); }
202
T_numtype shift(int offset, int dim) const {
203
BZPRECONDITION(0); return T_numtype(); }
205
T_numtype shift(int offset1, int dim1,int offset2, int dim2) const
206
{ BZPRECONDITION(0); return T_numtype(); }
209
void moveTo(const TinyVector<int,N_rank>&) const { BZPRECONDITION(0); }
211
void prettyPrint(BZ_STD_SCOPE(string) &str,
212
prettyPrintFormat& format) const
215
BZ_STD_SCOPE(ostringstream) ostr;
219
ostr << "Range(" << first_ << ", " << last_
220
<< ", " << stride_ << ")";
225
// old range stuff below. what is needed for the range interface and
226
// what is old vecexpr stuff?
228
T_numtype first(T_numtype lowRange = 0) const
101
230
if (first_ == fromStart)
106
int last(int highRange = 0) const
235
T_numtype last(T_numtype highRange = 0) const
108
237
if (last_ == toEnd)
109
238
return highRange;
113
unsigned length(int =0) const
242
int length(int =0) const
115
244
BZPRECONDITION(first_ != fromStart);
116
245
BZPRECONDITION(last_ != toEnd);
140
269
static Range all()
141
270
{ return Range(fromStart,toEnd,1); }
272
/// \todo this talks about the stride of the RANGE, not the expression stride.
143
273
bool isUnitStride() const
144
274
{ return stride_ == 1; }
147
Range operator-(int shift) const
277
Range operator-(T_numtype shift) const
149
279
BZPRECONDITION(first_ != fromStart);
150
280
BZPRECONDITION(last_ != toEnd);
151
281
return Range(first_ - shift, last_ - shift, stride_);
154
Range operator+(int shift) const
284
Range operator+(T_numtype shift) const
156
286
BZPRECONDITION(first_ != fromStart);
157
287
BZPRECONDITION(last_ != toEnd);
158
288
return Range(first_ + shift, last_ + shift, stride_);
161
int operator[](unsigned i) const
163
return first_ + i * stride_;
166
int operator()(unsigned i) const
168
return first_ + i * stride_;
171
291
friend inline ostream& operator<<(ostream& os, const Range& range)
173
293
os << "Range(" << range.first() << "," << range.last() << ","
179
/////////////////////////////////////////////
180
// Library-internal member functions
181
// These are undocumented and may change or
182
// disappear in future releases.
183
/////////////////////////////////////////////
186
_bz_staticLengthCount = 0,
187
_bz_dynamicLengthCount = 0,
188
_bz_staticLength = 0;
190
bool _bz_hasFastAccess() const
191
{ return stride_ == 1; }
193
T_numtype _bz_fastAccess(unsigned i) const
194
{ return first_ + i; }
196
unsigned _bz_suggestLength() const
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>
308
typedef void T_slice;
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
201
_bz_VecExpr<Range> _bz_asVecExpr() const
202
{ return _bz_VecExpr<Range>(*this); }
205
int first_, last_, stride_;
320
T_numtype first_, last_;