MoochoPack: Miscellaneous Utilities for MOOCHO  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RangePack_Range1D.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef RANGE1D_H
43 #define RANGE1D_H
44 
45 #include "RTOpPack_Types.hpp"
46 #include "Teuchos_Range1D.hpp"
47 #include "Teuchos_ScalarTraits.hpp"
48 
49 namespace RangePack {
50 
76 class Range1D {
77 public:
79  typedef RTOpPack::Ordinal Index;
81  enum EInvalidRange { INVALID };
83  static const Range1D Invalid;
94  inline Range1D();
104  inline Range1D( EInvalidRange );
119  inline Range1D(Index lbound, Index ubound);
121  inline bool full_range() const;
123  inline Index lbound() const;
125  inline Index ubound() const;
127  inline Index size() const;
129  inline bool in_range(Index i) const;
131  inline Range1D& operator+=( Index incr );
133  inline Range1D& operator-=( Index incr );
134 
135 private:
136  Index lbound_;
137  Index ubound_;
138 
139  // assert that the range is valid
140  inline void assert_valid_range(Index lbound, Index ubound) const;
141 
142 }; // end class Range1D
143 
150 inline bool operator==(const Range1D& rng1, const Range1D& rng2 )
151 {
152  return rng1.lbound() == rng2.lbound() && rng1.ubound() == rng2.ubound();
153 }
154 
166 inline Range1D operator+(const Range1D &rng_rhs, Range1D::Index i)
167 {
168  return Range1D(i+rng_rhs.lbound(), i+rng_rhs.ubound());
169 }
170 
182 inline Range1D operator+(Range1D::Index i, const Range1D &rng_rhs)
183 {
184  return Range1D(i+rng_rhs.lbound(), i+rng_rhs.ubound());
185 }
186 
198 inline Range1D operator-(const Range1D &rng_rhs, Range1D::Index i)
199 {
200  return Range1D(rng_rhs.lbound()-i, rng_rhs.ubound()-i);
201 }
202 
217 inline Range1D full_range(const Range1D &rng, Range1D::Index lbound, Range1D::Index ubound)
218 { return rng.full_range() ? Range1D(lbound,ubound) : rng; }
219 
224 inline Range1D convert( const Teuchos::Range1D &rng )
225 {
226  Range1D rngOut;
227  if (rng.full_range()) {
228  rngOut = Range1D();
229  }
230  else if (rng.size() == -1) {
231  rngOut = Range1D::Invalid;
232  }
233  else if (rng.size() == 0) {
234  rngOut = Range1D::Invalid;
235  }
236  else {
237  rngOut = Range1D(rng.lbound()+1, rng.ubound()+1);
238  }
239  return rngOut;
240 }
241 
246 inline Teuchos::Range1D convert( const Range1D &rng )
247 {
248  Teuchos::Range1D rngOut;
249  if (rng.full_range()) {
250  rngOut = Teuchos::Range1D();
251  }
252  else if (rng.size() == 0) {
253  rngOut = Teuchos::Range1D::Invalid;
254  }
255  else {
256  rngOut = Teuchos::Range1D(rng.lbound()-1, rng.ubound()-1);
257  }
258  return rngOut;
259 }
260 
261 
263 
264 // //////////////////////////////////////////////////////////
265 // Inline members
266 
267 inline
269  : lbound_(1), ubound_(std::numeric_limits<Index>::max()-1)
270 {}
271 
272 inline
274  : lbound_(1), ubound_(0)
275 {}
276 
277 
278 inline
279 Range1D::Range1D(Index lbound, Index ubound)
280  : lbound_(lbound), ubound_(ubound)
281 {
282  assert_valid_range(lbound,ubound);
283 }
284 
285 inline
286 bool Range1D::full_range() const {
287  return ubound_ == (std::numeric_limits<Index>::max()-1);
288 }
289 
290 inline
292  return lbound_;
293 }
294 
295 inline
297  return ubound_;
298 }
299 
300 inline
302  return 1 + ubound_ - lbound_;
303 }
304 
305 inline
306 bool Range1D::in_range(Index i) const {
307  return lbound_ <= i && i <= ubound_;
308 }
309 
310 inline
312  assert_valid_range( lbound_ + incr, ubound_ + incr );
313  lbound_ += incr;
314  ubound_ += incr;
315  return *this;
316 }
317 
318 inline
320  assert_valid_range( lbound_ - incr, ubound_ - incr );
321  lbound_ -= incr;
322  ubound_ -= incr;
323  return *this;
324 }
325 
326 // See Range1D.cpp
327 inline
328 void Range1D::assert_valid_range(Index lbound, Index ubound) const {
329 #ifdef TEUCHOS_DEBUG
331  lbound < 1, std::range_error
332  ,"Range1D::assert_valid_range(): Error, lbound ="<<lbound<<" must be greater than 0." );
334  lbound > ubound, std::range_error
335  ,"Range1D::assert_valid_range(): Error, lbound = "<<lbound<<" > ubound = "<<ubound );
336 #endif
337 }
338 
339 } // end namespace RangePack
340 
341 #endif // end RANGE1D_H
bool operator==(const Range1D &rng1, const Range1D &rng2)
rng1 == rng2.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Index size() const
Return the size of the range (ubound() - lbound() + 1)
Index ubound() const
Return upper bound of the range.
RTOpPack::Ordinal Index
Range1D & operator+=(Index incr)
Increment the range by a constant.
Range1D operator-(const Range1D &rng_rhs, Range1D::Index i)
rng_lhs = rng_rhs - i.
Ordinal ubound() const
bool full_range() const
. One-based subregion index range class.
Range1D()
Constructs a range representing the entire range.
Teuchos::Range1D convert(const Range1D &rng)
Convert from a 1-based RangePack::Range1D object to a 0-based Teuchos::Range1D object.
Range1D operator+(Range1D::Index i, const Range1D &rng_rhs)
rng_lhs = i + rng_rhs.
bool full_range() const
Returns true if the range represents the entire region (constructed from Range1D()) ...
Range1D full_range(const Range1D &rng, Range1D::Index lbound, Range1D::Index ubound)
Return a bounded index range from a potentially unbounded index range.
bool in_range(Index i) const
Return true if the index is in range.
static const Range1D Invalid
Ordinal lbound() const
static const Range1D Invalid
Range1D(INVALID)
Index lbound() const
Return lower bound of the range.
Range1D convert(const Teuchos::Range1D &rng)
Convert from a 0-based Teuchos::Range1D object to a 1-based RangePack::Range1D object.
Ordinal size() const
Range1D operator+(const Range1D &rng_rhs, Range1D::Index i)
rng_lhs = rng_rhs + i.
Range1D & operator-=(Index incr)
Deincrement the range by a constant.