00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef BZ_RANGE_H
00028 #define BZ_RANGE_H
00029
00030 #ifndef BZ_BLITZ_H
00031 #include <blitz/blitz.h>
00032 #endif
00033
00034 #ifndef BZ_VECEXPRWRAP_H
00035 #include <blitz/vecexprwrap.h>
00036 #endif
00037
00038 #include <blitz/wrap-climits.h>
00039
00040 BZ_NAMESPACE(blitz)
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 enum { fromStart = INT_MIN, toEnd = INT_MIN };
00051
00052
00053 class Range {
00054
00055 public:
00056
00057
00058
00059
00060 typedef int T_numtype;
00061
00062 enum { fromStart = INT_MIN, toEnd = INT_MIN };
00063
00064 Range()
00065 {
00066 first_ = fromStart;
00067 last_ = toEnd;
00068 stride_ = 1;
00069 }
00070
00071
00072 #ifdef BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR
00073 Range(const Range& r)
00074 {
00075 first_ = r.first_;
00076 last_ = r.last_;
00077 stride_ = r.stride_;
00078 }
00079 #endif
00080
00081 explicit Range(int slicePosition)
00082 {
00083 first_ = slicePosition;
00084 last_ = slicePosition;
00085 stride_ = 1;
00086 }
00087
00088 Range(int first, int last, int stride=1)
00089 : first_(first), last_(last), stride_(stride)
00090 {
00091 BZPRECHECK((first == fromStart) || (last == toEnd) ||
00092 (first < last) && (stride > 0) ||
00093 (first > last) && (stride < 0) ||
00094 (first == last), (*this) << " is an invalid range.");
00095 BZPRECHECK((last-first) % stride == 0,
00096 (*this) << ": the stride must evenly divide the range");
00097 }
00098
00099 int first(int lowRange = 0) const
00100 {
00101 if (first_ == fromStart)
00102 return lowRange;
00103 return first_;
00104 }
00105
00106 int last(int highRange = 0) const
00107 {
00108 if (last_ == toEnd)
00109 return highRange;
00110 return last_;
00111 }
00112
00113 unsigned length(int =0) const
00114 {
00115 BZPRECONDITION(first_ != fromStart);
00116 BZPRECONDITION(last_ != toEnd);
00117 BZPRECONDITION((last_ - first_) % stride_ == 0);
00118 return (last_ - first_) / stride_ + 1;
00119 }
00120
00121 int stride() const
00122 { return stride_; }
00123
00124 bool isAscendingContiguous() const
00125 {
00126 return ((first_ < last_) && (stride_ == 1) || (first_ == last_));
00127 }
00128
00129 void setRange(int first, int last, int stride=1)
00130 {
00131 BZPRECONDITION((first < last) && (stride > 0) ||
00132 (first > last) && (stride < 0) ||
00133 (first == last));
00134 BZPRECONDITION((last-first) % stride == 0);
00135 first_ = first;
00136 last_ = last;
00137 stride_ = stride;
00138 }
00139
00140 static Range all()
00141 { return Range(fromStart,toEnd,1); }
00142
00143 bool isUnitStride() const
00144 { return stride_ == 1; }
00145
00146
00147 Range operator-(int shift) const
00148 {
00149 BZPRECONDITION(first_ != fromStart);
00150 BZPRECONDITION(last_ != toEnd);
00151 return Range(first_ - shift, last_ - shift, stride_);
00152 }
00153
00154 Range operator+(int shift) const
00155 {
00156 BZPRECONDITION(first_ != fromStart);
00157 BZPRECONDITION(last_ != toEnd);
00158 return Range(first_ + shift, last_ + shift, stride_);
00159 }
00160
00161 int operator[](unsigned i) const
00162 {
00163 return first_ + i * stride_;
00164 }
00165
00166 int operator()(unsigned i) const
00167 {
00168 return first_ + i * stride_;
00169 }
00170
00171 friend inline ostream& operator<<(ostream& os, const Range& range)
00172 {
00173 os << "Range(" << range.first() << "," << range.last() << ","
00174 << range.stride() << ")";
00175
00176 return os;
00177 }
00178
00180
00181
00182
00184
00185 static const int
00186 _bz_staticLengthCount = 0,
00187 _bz_dynamicLengthCount = 0,
00188 _bz_staticLength = 0;
00189
00190 bool _bz_hasFastAccess() const
00191 { return stride_ == 1; }
00192
00193 T_numtype _bz_fastAccess(unsigned i) const
00194 { return first_ + i; }
00195
00196 unsigned _bz_suggestLength() const
00197 {
00198 return length();
00199 }
00200
00201 _bz_VecExpr<Range> _bz_asVecExpr() const
00202 { return _bz_VecExpr<Range>(*this); }
00203
00204 private:
00205 int first_, last_, stride_;
00206 };
00207
00208 BZ_NAMESPACE_END
00209
00210 #endif // BZ_RANGE_H