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.
14 // Trying to diagnose problems under visual
16 #include <boost/config.hpp>
17 #include <boost/array.hpp>
18 #include <boost/limits.hpp>
23 typedef std::size_t size_type
;
25 template <typename Index
,typename SizeType
>
31 start_
= from_start();
37 explicit index_range(Index pos
)
45 explicit index_range(Index start
, Index finish
, Index stride
=1)
46 : start_(start
), finish_(finish
), stride_(stride
),
47 degenerate_(start_
== finish_
)
51 // These are for chaining assignments to an index_range
52 index_range
& start(Index s
) {
54 degenerate_
= (start_
== finish_
);
58 index_range
& finish(Index f
) {
60 degenerate_
= (start_
== finish_
);
64 index_range
& stride(Index s
) { stride_
= s
; return *this; }
71 Index
get_start(Index low_index_range
= 0) const
73 if (start_
== from_start())
74 return low_index_range
;
83 Index
get_finish(Index high_index_range
= 0) const
85 if (finish_
== to_end())
86 return high_index_range
;
90 unsigned int size(Index recommended_length
= 0) const
92 if ((start_
== from_start()) || (finish_
== to_end()))
93 return recommended_length
;
95 return (finish_
- start_
) / stride_
;
98 Index
stride() const { return stride_
; }
100 bool is_ascending_contiguous() const
102 return (start_
< finish_
) && is_unit_stride();
105 void set_index_range(Index start
, Index finish
, Index stride
=1)
112 static index_range
all()
113 { return index_range(from_start(), to_end(), 1); }
115 bool is_unit_stride() const
116 { return stride_
== 1; }
118 bool is_degenerate() const { return degenerate_
; }
120 index_range
operator-(Index shift
) const
122 return index_range(start_
- shift
, finish_
- shift
, stride_
);
125 index_range
operator+(Index shift
) const
127 return index_range(start_
+ shift
, finish_
+ shift
, stride_
);
130 Index
operator[](unsigned i
) const
132 return start_
+ i
* stride_
;
135 Index
operator()(unsigned i
) const
137 return start_
+ i
* stride_
;
140 // add conversion to std::slice?
143 static Index
from_start()
144 { return (std::numeric_limits
<Index
>::min
)(); }
146 static Index
to_end()
147 { return (std::numeric_limits
<Index
>::max
)(); }
149 Index start_
, finish_
, stride_
;
153 // Express open and closed interval end-points using the comparison
157 template <typename Index
, typename SizeType
>
158 inline index_range
<Index
,SizeType
>
159 operator<=(Index s
, const index_range
<Index
,SizeType
>& r
)
161 return index_range
<Index
,SizeType
>(s
, r
.finish(), r
.stride());
165 template <typename Index
, typename SizeType
>
166 inline index_range
<Index
,SizeType
>
167 operator<(Index s
, const index_range
<Index
,SizeType
>& r
)
169 return index_range
<Index
,SizeType
>(s
+ 1, r
.finish(), r
.stride());
173 template <typename Index
, typename SizeType
>
174 inline index_range
<Index
,SizeType
>
175 operator<(const index_range
<Index
,SizeType
>& r
, Index f
)
177 return index_range
<Index
,SizeType
>(r
.start(), f
, r
.stride());
181 template <typename Index
, typename SizeType
>
182 inline index_range
<Index
,SizeType
>
183 operator<=(const index_range
<Index
,SizeType
>& r
, Index f
)
185 return index_range
<Index
,SizeType
>(r
.start(), f
+ 1, r
.stride());
189 // range_list.hpp - helper to build boost::arrays for *_set types
192 /////////////////////////////////////////////////////////////////////////
193 // choose range list begins
196 struct choose_range_list_n
{
197 template <typename T
, std::size_t NumRanges
>
199 typedef boost::array
<T
,NumRanges
> type
;
203 struct choose_range_list_zero
{
204 template <typename T
, std::size_t NumRanges
>
206 typedef boost::array
<T
,1> type
;
211 template <std::size_t NumRanges
>
212 struct range_list_gen_helper
{
213 typedef choose_range_list_n choice
;
217 struct range_list_gen_helper
<0> {
218 typedef choose_range_list_zero choice
;
221 template <typename T
, std::size_t NumRanges
>
222 struct range_list_generator
{
224 typedef typename range_list_gen_helper
<NumRanges
>::choice Choice
;
226 typedef typename
Choice::template bind
<T
,NumRanges
>::type type
;
230 // choose range list ends
231 /////////////////////////////////////////////////////////////////////////
234 // Index_gen.hpp stuff
237 template <int NumRanges
, int NumDims
>
241 typedef size_type SizeType
;
242 typedef index_range
<Index
,SizeType
> range
;
244 typedef typename range_list_generator
<range
,NumRanges
>::type range_list
;
250 explicit index_gen(const index_gen
<NumRanges
-1,ND
>& rhs
,
251 const index_range
<Index
,SizeType
>& range
)
253 std::copy(rhs
.ranges_
.begin(),rhs
.ranges_
.end(),ranges_
.begin());
254 *ranges_
.rbegin() = range
;
257 index_gen
<NumRanges
+1,NumDims
+1>
258 operator[](const index_range
<Index
,SizeType
>& range
) const
260 index_gen
<NumRanges
+1,NumDims
+1> tmp
;
261 std::copy(ranges_
.begin(),ranges_
.end(),tmp
.ranges_
.begin());
262 *tmp
.ranges_
.rbegin() = range
;
266 index_gen
<NumRanges
+1,NumDims
>
267 operator[](Index idx
) const
269 index_gen
<NumRanges
+1,NumDims
> tmp
;
270 std::copy(ranges_
.begin(),ranges_
.end(),tmp
.ranges_
.begin());
271 *tmp
.ranges_
.rbegin() = index_range
<Index
,SizeType
>(idx
);
277 template <int NDims
, int NRanges
>
278 void accept_gen(index_gen
<NRanges
,NDims
>& indices
) {
282 template <typename X
, typename Y
, int A
, int B
>
287 template <int NDims
, int NRanges
>
288 void operator[](index_gen
<NRanges
,NDims
>& indices
) {
293 template <typename X
, typename Y
, int A1
, int A2
>
294 void take_foo(foo
<X
,Y
,A1
,A2
>& f
) { }
298 index_gen
<0,0> indices
;
299 typedef index_range
<index
,size_type
> range
;
301 take_foo(foo
<int,std::size_t,1,2>());
303 indices
[range()][range()][range()];
305 accept_gen(index_gen
<0,0>());
306 accept_gen(indices
[range()][range()][range()]);
309 b
[indices
[range()][range()][range()]];