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