blitz Version 0.10
blitz/range.h
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines