blitz Version 0.9
|
00001 // -*- C++ -*- 00002 /*************************************************************************** 00003 * blitz/range.h Declaration of the Range class 00004 * 00005 * $Id: range.h,v 1.9 2005/05/07 04:17:56 julianc Exp $ 00006 * 00007 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * Suggestions: blitz-dev@oonumerics.org 00020 * Bugs: blitz-bugs@oonumerics.org 00021 * 00022 * For more information, please see the Blitz++ Home Page: 00023 * http://oonumerics.org/blitz/ 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> // _bz_VecExpr wrapper 00036 #endif 00037 00038 #include <blitz/wrap-climits.h> // for INT_MIN 00039 00040 BZ_NAMESPACE(blitz) 00041 00042 // Examples: 00043 // Vector<double> x(7); 00044 // Range::all() [0,1,2,3,4,5,6] 00045 // Range(3,5) [3,4,5] 00046 // Range(3,Range::toEnd) [3,4,5,6] 00047 // Range(Range::fromStart,3) [0,1,2,3] 00048 // Range(1,5,2); [1,3,5] 00049 00050 enum { fromStart = INT_MIN, toEnd = INT_MIN }; 00051 00052 // Class Range 00053 class Range { 00054 00055 public: 00056 // This declaration not yet supported by all compilers 00057 // const int fromStart = INT_MIN; 00058 // const int toEnd = INT_MIN; 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 // Range(Range r): allow default copy constructor to be used 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 // Operators 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 // Library-internal member functions 00181 // These are undocumented and may change or 00182 // disappear in future releases. 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