blitz  Version 0.9
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
range.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  * blitz/range.h Declaration of the Range class
4  *
5  * $Id: range.h,v 1.9 2005/05/07 04:17:56 julianc Exp $
6  *
7  * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * Suggestions: blitz-dev@oonumerics.org
20  * Bugs: blitz-bugs@oonumerics.org
21  *
22  * For more information, please see the Blitz++ Home Page:
23  * http://oonumerics.org/blitz/
24  *
25  ***************************************************************************/
26 
27 #ifndef BZ_RANGE_H
28 #define BZ_RANGE_H
29 
30 #ifndef BZ_BLITZ_H
31  #include <blitz/blitz.h>
32 #endif
33 
34 #ifndef BZ_VECEXPRWRAP_H
35  #include <blitz/vecexprwrap.h> // _bz_VecExpr wrapper
36 #endif
37 
38 #include <blitz/wrap-climits.h> // for INT_MIN
39 
40 BZ_NAMESPACE(blitz)
41 
42 // Examples:
43 // Vector<double> x(7);
44 // Range::all() [0,1,2,3,4,5,6]
45 // Range(3,5) [3,4,5]
46 // Range(3,Range::toEnd) [3,4,5,6]
47 // Range(Range::fromStart,3) [0,1,2,3]
48 // Range(1,5,2); [1,3,5]
49 
50 enum { fromStart = INT_MIN, toEnd = INT_MIN };
51 
52 // Class Range
53 class Range {
54 
55 public:
56  // This declaration not yet supported by all compilers
57  // const int fromStart = INT_MIN;
58  // const int toEnd = INT_MIN;
59 
60  typedef int T_numtype;
61 
62  enum { fromStart = INT_MIN, toEnd = INT_MIN };
63 
65  {
66  first_ = fromStart;
67  last_ = toEnd;
68  stride_ = 1;
69  }
70 
71  // Range(Range r): allow default copy constructor to be used
72 #ifdef BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR
73  Range(const Range& r)
74  {
75  first_ = r.first_;
76  last_ = r.last_;
77  stride_ = r.stride_;
78  }
79 #endif
80 
81  explicit Range(int slicePosition)
82  {
83  first_ = slicePosition;
84  last_ = slicePosition;
85  stride_ = 1;
86  }
87 
88  Range(int first, int last, int stride=1)
89  : first_(first), last_(last), stride_(stride)
90  {
91  BZPRECHECK((first == fromStart) || (last == toEnd) ||
92  (first < last) && (stride > 0) ||
93  (first > last) && (stride < 0) ||
94  (first == last), (*this) << " is an invalid range.");
95  BZPRECHECK((last-first) % stride == 0,
96  (*this) << ": the stride must evenly divide the range");
97  }
98 
99  int first(int lowRange = 0) const
100  {
101  if (first_ == fromStart)
102  return lowRange;
103  return first_;
104  }
105 
106  int last(int highRange = 0) const
107  {
108  if (last_ == toEnd)
109  return highRange;
110  return last_;
111  }
112 
113  unsigned length(int =0) const
114  {
115  BZPRECONDITION(first_ != fromStart);
116  BZPRECONDITION(last_ != toEnd);
117  BZPRECONDITION((last_ - first_) % stride_ == 0);
118  return (last_ - first_) / stride_ + 1;
119  }
120 
121  int stride() const
122  { return stride_; }
123 
125  {
126  return ((first_ < last_) && (stride_ == 1) || (first_ == last_));
127  }
128 
129  void setRange(int first, int last, int stride=1)
130  {
131  BZPRECONDITION((first < last) && (stride > 0) ||
132  (first > last) && (stride < 0) ||
133  (first == last));
134  BZPRECONDITION((last-first) % stride == 0);
135  first_ = first;
136  last_ = last;
137  stride_ = stride;
138  }
139 
140  static Range all()
141  { return Range(fromStart,toEnd,1); }
142 
143  bool isUnitStride() const
144  { return stride_ == 1; }
145 
146  // Operators
147  Range operator-(int shift) const
148  {
149  BZPRECONDITION(first_ != fromStart);
150  BZPRECONDITION(last_ != toEnd);
151  return Range(first_ - shift, last_ - shift, stride_);
152  }
153 
154  Range operator+(int shift) const
155  {
156  BZPRECONDITION(first_ != fromStart);
157  BZPRECONDITION(last_ != toEnd);
158  return Range(first_ + shift, last_ + shift, stride_);
159  }
160 
161  int operator[](unsigned i) const
162  {
163  return first_ + i * stride_;
164  }
165 
166  int operator()(unsigned i) const
167  {
168  return first_ + i * stride_;
169  }
170 
171  friend inline ostream& operator<<(ostream& os, const Range& range)
172  {
173  os << "Range(" << range.first() << "," << range.last() << ","
174  << range.stride() << ")";
175 
176  return os;
177  }
178 
180  // Library-internal member functions
181  // These are undocumented and may change or
182  // disappear in future releases.
184 
185  static const int
189 
190  bool _bz_hasFastAccess() const
191  { return stride_ == 1; }
192 
193  T_numtype _bz_fastAccess(unsigned i) const
194  { return first_ + i; }
195 
196  unsigned _bz_suggestLength() const
197  {
198  return length();
199  }
200 
201  _bz_VecExpr<Range> _bz_asVecExpr() const
202  { return _bz_VecExpr<Range>(*this); }
203 
204 private:
206 };
207 
209 
210 #endif // BZ_RANGE_H