blitz Version 0.10
|
00001 // -*- C++ -*- 00002 /*************************************************************************** 00003 * blitz/range.h Declaration of the Range class 00004 * 00005 * $Id: range.h,v 1.16 2011/03/25 22:41:16 julianc Exp $ 00006 * 00007 * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> 00008 * 00009 * This file is a part of Blitz. 00010 * 00011 * Blitz is free software: you can redistribute it and/or modify 00012 * it under the terms of the GNU Lesser General Public License 00013 * as published by the Free Software Foundation, either version 3 00014 * of the License, or (at your option) any later version. 00015 * 00016 * Blitz is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. 00023 * 00024 * Suggestions: blitz-devel@lists.sourceforge.net 00025 * Bugs: blitz-support@lists.sourceforge.net 00026 * 00027 * For more information, please see the Blitz++ Home Page: 00028 * https://sourceforge.net/projects/blitz/ 00029 * 00030 ***************************************************************************/ 00031 00032 #ifndef BZ_RANGE_H 00033 #define BZ_RANGE_H 00034 00035 #ifndef BZ_BLITZ_H 00036 #include <blitz/blitz.h> 00037 #endif 00038 00039 #ifndef BZ_VECEXPRWRAP_H 00040 #include <blitz/vecexprwrap.h> // _bz_VecExpr wrapper 00041 #endif 00042 00043 #include <climits> // for INT_MIN, INT_MAX 00044 00045 BZ_NAMESPACE(blitz) 00046 00047 // Examples: 00048 // Array<int,1> A(7); 00049 // A = 0,1,2,3,4,5,6; 00050 // A(Range::all()); [0,1,2,3,4,5,6] 00051 // A(Range(3,5)); [3,4,5] 00052 // A(Range(3,toEnd)); [3,4,5,6] 00053 // A(Range(fromStart,3)); [0,1,2,3] 00054 // A(Range(1,5,2)); [1,3,5] 00055 // A(Range(5,1,-2)); [5,3,1] 00056 // A(Range(fromStart,toEnd,2)); [0,2,4,6] 00057 00058 00059 const int fromStart = INT_MIN; 00060 const int toEnd = INT_MAX; 00061 00062 // Class Range 00063 class Range { 00064 00065 public: 00066 typedef int T_numtype; 00067 typedef unsigned int T_sizetype; 00068 00069 Range() 00070 { 00071 first_ = fromStart; 00072 last_ = toEnd; 00073 stride_ = 1; 00074 } 00075 00076 // Range(Range r): allow default copy constructor to be used 00077 #ifdef BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR 00078 Range(const Range& r) 00079 { 00080 first_ = r.first_; 00081 last_ = r.last_; 00082 stride_ = r.stride_; 00083 } 00084 #endif 00085 00086 explicit Range(T_numtype slicePosition) 00087 { 00088 first_ = slicePosition; 00089 last_ = slicePosition; 00090 stride_ = 1; 00091 } 00092 00093 Range(T_numtype first, T_numtype last, diffType stride=1) 00094 : first_(first), last_(last), stride_(stride) 00095 { 00096 BZPRECHECK((first == fromStart) || (last == toEnd) || 00097 ((first < last) && (stride > 0)) || 00098 ((first > last) && (stride < 0)) || 00099 (first == last), (*this) << " is an invalid range."); 00100 BZPRECHECK((first == fromStart) || (last == toEnd) || 00101 (last-first) % stride == 0, 00102 (*this) << ": the stride must evenly divide the range"); 00103 } 00104 00105 T_numtype first(T_numtype lowRange = 0) const 00106 { 00107 if (first_ == fromStart) 00108 return lowRange; 00109 return first_; 00110 } 00111 00112 T_numtype last(T_numtype highRange = 0) const 00113 { 00114 if (last_ == toEnd) 00115 return highRange; 00116 return last_; 00117 } 00118 00119 T_sizetype length(int =0) const 00120 { 00121 BZPRECONDITION(first_ != fromStart); 00122 BZPRECONDITION(last_ != toEnd); 00123 BZPRECONDITION((last_ - first_) % stride_ == 0); 00124 return (last_ - first_) / stride_ + 1; 00125 } 00126 00127 diffType stride() const 00128 { return stride_; } 00129 00130 bool isAscendingContiguous() const 00131 { 00132 return (((first_ < last_) && (stride_ == 1)) || (first_ == last_)); 00133 } 00134 00135 void setRange(T_numtype first, T_numtype last, diffType stride=1) 00136 { 00137 BZPRECONDITION(((first < last) && (stride > 0)) || 00138 ((first > last) && (stride < 0)) || 00139 (first == last)); 00140 BZPRECONDITION((last-first) % stride == 0); 00141 first_ = first; 00142 last_ = last; 00143 stride_ = stride; 00144 } 00145 00146 static Range all() 00147 { return Range(fromStart,toEnd,1); } 00148 00149 bool isUnitStride() const 00150 { return stride_ == 1; } 00151 00152 // Operators 00153 Range operator-(T_numtype shift) const 00154 { 00155 BZPRECONDITION(first_ != fromStart); 00156 BZPRECONDITION(last_ != toEnd); 00157 return Range(first_ - shift, last_ - shift, stride_); 00158 } 00159 00160 Range operator+(T_numtype shift) const 00161 { 00162 BZPRECONDITION(first_ != fromStart); 00163 BZPRECONDITION(last_ != toEnd); 00164 return Range(first_ + shift, last_ + shift, stride_); 00165 } 00166 00167 T_numtype operator[](T_sizetype i) const 00168 { 00169 return first_ + i * stride_; 00170 } 00171 00172 T_numtype operator()(T_sizetype i) const 00173 { 00174 return first_ + i * stride_; 00175 } 00176 00177 friend inline ostream& operator<<(ostream& os, const Range& range) 00178 { 00179 os << "Range(" << range.first() << "," << range.last() << "," 00180 << range.stride() << ")"; 00181 00182 return os; 00183 } 00184 00186 // Library-internal member functions 00187 // These are undocumented and may change or 00188 // disappear in future releases. 00190 00191 static const int 00192 _bz_staticLengthCount = 0, 00193 _bz_dynamicLengthCount = 0, 00194 _bz_staticLength = 0; 00195 00196 bool _bz_hasFastAccess() const 00197 { return stride_ == 1; } 00198 00199 int _bz_fastAccess(unsigned int i) const 00200 { return first_ + i; } 00201 00202 unsigned int _bz_suggestLength() const 00203 { 00204 return length(); 00205 } 00206 00207 _bz_VecExpr<Range> _bz_asVecExpr() const 00208 { return _bz_VecExpr<Range>(*this); } 00209 00210 private: 00211 T_numtype first_, last_; 00212 diffType stride_; 00213 }; 00214 00215 BZ_NAMESPACE_END 00216 00217 #endif // BZ_RANGE_H