1
// Copyright 2002 The Trustees of Indiana University.
3
// Use, modification and distribution is subject to the Boost Software
4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5
// http://www.boost.org/LICENSE_1_0.txt)
7
// Boost.MultiArray Library
8
// Authors: Ronald Garcia
11
// See http://www.boost.org/libs/multi_array for documentation.
13
#ifndef BOOST_INDEX_RANGE_RG071801_HPP
14
#define BOOST_INDEX_RANGE_RG071801_HPP
16
#include <boost/config.hpp>
18
#include <boost/limits.hpp>
20
// For representing intervals, also with stride.
21
// A degenerate range is a range with one element.
23
// Thanks to Doug Gregor for the really cool idea of using the
24
// comparison operators to express various interval types!
26
// Internally, we represent the interval as half-open.
30
namespace multi_array {
32
template <typename Index,typename SizeType>
36
typedef SizeType size_type;
39
static index from_start()
40
{ return (std::numeric_limits<index>::min)(); }
43
{ return (std::numeric_limits<index>::max)(); }
49
start_ = from_start();
55
explicit index_range(index pos)
63
explicit index_range(index start, index finish, index stride=1)
64
: start_(start), finish_(finish), stride_(stride),
69
// These are for chaining assignments to an index_range
70
index_range& start(index s) {
76
index_range& finish(index f) {
82
index_range& stride(index s) { stride_ = s; return *this; }
89
index get_start(index low_index_range = index_range::from_start()) const
91
if (start_ == from_start())
92
return low_index_range;
101
index get_finish(index high_index_range = index_range::to_end()) const
103
if (finish_ == to_end())
104
return high_index_range;
108
index stride() const { return stride_; }
110
void set_index_range(index start, index finish, index stride=1)
117
static index_range all()
118
{ return index_range(from_start(), to_end(), 1); }
120
bool is_degenerate() const { return degenerate_; }
122
index_range operator-(index shift) const
124
return index_range(start_ - shift, finish_ - shift, stride_);
127
index_range operator+(index shift) const
129
return index_range(start_ + shift, finish_ + shift, stride_);
132
index operator[](unsigned i) const
134
return start_ + i * stride_;
137
index operator()(unsigned i) const
139
return start_ + i * stride_;
142
// add conversion to std::slice?
145
index start_, finish_, stride_;
149
// Express open and closed interval end-points using the comparison
153
template <typename Index, typename SizeType>
154
inline index_range<Index,SizeType>
155
operator<=(Index s, const index_range<Index,SizeType>& r)
157
return index_range<Index,SizeType>(s, r.finish(), r.stride());
161
template <typename Index, typename SizeType>
162
inline index_range<Index,SizeType>
163
operator<(Index s, const index_range<Index,SizeType>& r)
165
return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
169
template <typename Index, typename SizeType>
170
inline index_range<Index,SizeType>
171
operator<(const index_range<Index,SizeType>& r, Index f)
173
return index_range<Index,SizeType>(r.start(), f, r.stride());
177
template <typename Index, typename SizeType>
178
inline index_range<Index,SizeType>
179
operator<=(const index_range<Index,SizeType>& r, Index f)
181
return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
184
} // namespace multi_array
185
} // namespace detail
188
#endif // BOOST_INDEX_RANGE_RG071801_HPP