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.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

Generated on Wed Oct 17 15:15:51 2007 for blitz by  doxygen 1.5.2