Update contrib.
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 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
17 // Trying to diagnose problems under visual
19 #include "boost/config.hpp"
20 #include "boost/array.hpp"
21 #include "boost/limits.hpp"
27 #include "std_log_result.h"
28 #define LOG_FILENAME_LINE __FILE__, __LINE__
35 typedef std::size_t size_type;
37 template <typename Index,typename SizeType>
43 start_ = from_start();
49 explicit index_range(Index pos)
57 explicit index_range(Index start, Index finish, Index stride=1)
58 : start_(start), finish_(finish), stride_(stride),
59 degenerate_(start_ == finish_)
63 // These are for chaining assignments to an index_range
64 index_range& start(Index s) {
66 degenerate_ = (start_ == finish_);
70 index_range& finish(Index f) {
72 degenerate_ = (start_ == finish_);
76 index_range& stride(Index s) { stride_ = s; return *this; }
83 Index get_start(Index low_index_range = 0) const
85 if (start_ == from_start())
86 return low_index_range;
95 Index get_finish(Index high_index_range = 0) const
97 if (finish_ == to_end())
98 return high_index_range;
102 unsigned int size(Index recommended_length = 0) const
104 if ((start_ == from_start()) || (finish_ == to_end()))
105 return recommended_length;
107 return (finish_ - start_) / stride_;
110 Index stride() const { return stride_; }
112 bool is_ascending_contiguous() const
114 return (start_ < finish_) && is_unit_stride();
117 void set_index_range(Index start, Index finish, Index stride=1)
124 static index_range all()
125 { return index_range(from_start(), to_end(), 1); }
127 bool is_unit_stride() const
128 { return stride_ == 1; }
130 bool is_degenerate() const { return degenerate_; }
132 index_range operator-(Index shift) const
134 return index_range(start_ - shift, finish_ - shift, stride_);
137 index_range operator+(Index shift) const
139 return index_range(start_ + shift, finish_ + shift, stride_);
142 Index operator[](unsigned i) const
144 return start_ + i * stride_;
147 Index operator()(unsigned i) const
149 return start_ + i * stride_;
152 // add conversion to std::slice?
155 static Index from_start()
156 { return (std::numeric_limits<Index>::min)(); }
158 static Index to_end()
159 { return (std::numeric_limits<Index>::max)(); }
161 Index start_, finish_, stride_;
165 // Express open and closed interval end-points using the comparison
169 template <typename Index, typename SizeType>
170 inline index_range<Index,SizeType>
171 operator<=(Index s, const index_range<Index,SizeType>& r)
173 return index_range<Index,SizeType>(s, r.finish(), r.stride());
177 template <typename Index, typename SizeType>
178 inline index_range<Index,SizeType>
179 operator<(Index s, const index_range<Index,SizeType>& r)
181 return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
185 template <typename Index, typename SizeType>
186 inline index_range<Index,SizeType>
187 operator<(const index_range<Index,SizeType>& r, Index f)
189 return index_range<Index,SizeType>(r.start(), f, r.stride());
193 template <typename Index, typename SizeType>
194 inline index_range<Index,SizeType>
195 operator<=(const index_range<Index,SizeType>& r, Index f)
197 return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
201 // range_list.hpp - helper to build boost::arrays for *_set types
204 /////////////////////////////////////////////////////////////////////////
205 // choose range list begins
208 struct choose_range_list_n {
209 template <typename T, std::size_t NumRanges>
211 typedef boost::array<T,NumRanges> type;
215 struct choose_range_list_zero {
216 template <typename T, std::size_t NumRanges>
218 typedef boost::array<T,1> type;
223 template <std::size_t NumRanges>
224 struct range_list_gen_helper {
225 typedef choose_range_list_n choice;
229 struct range_list_gen_helper<0> {
230 typedef choose_range_list_zero choice;
233 template <typename T, std::size_t NumRanges>
234 struct range_list_generator {
236 typedef typename range_list_gen_helper<NumRanges>::choice Choice;
238 typedef typename Choice::template bind<T,NumRanges>::type type;
242 // choose range list ends
243 /////////////////////////////////////////////////////////////////////////
246 // Index_gen.hpp stuff
249 template <int NumRanges, int NumDims>
252 typedef dimtest::index Index;
253 typedef size_type SizeType;
254 typedef index_range<Index,SizeType> range;
256 typedef typename range_list_generator<range,NumRanges>::type range_list;
262 explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
263 const index_range<Index,SizeType>& range)
265 std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
266 *ranges_.rbegin() = range;
269 index_gen<NumRanges+1,NumDims+1>
270 operator[](const index_range<Index,SizeType>& range) const
272 index_gen<NumRanges+1,NumDims+1> tmp;
273 std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
274 *tmp.ranges_.rbegin() = range;
278 index_gen<NumRanges+1,NumDims>
279 operator[](Index idx) const
281 index_gen<NumRanges+1,NumDims> tmp;
282 std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
283 *tmp.ranges_.rbegin() = index_range<Index,SizeType>(idx);
289 template <int NDims, int NRanges>
290 void accept_gen(index_gen<NRanges,NDims>& indices) {
294 template <typename X, typename Y, int A, int B>
300 template <int NDims, int NRanges>
301 void operator[](index_gen<NRanges,NDims>& indices) {
307 template <typename X, typename Y, int A1, int A2>
308 void take_foo(foo<X,Y,A1,A2>& f) { }
313 index_gen<0,0> indices;
314 typedef index_range<dimtest::index,size_type> range;
316 foo<int,std::size_t,1,2> f;
319 indices[range()][range()][range()];
321 index_gen<0,0> index_g;
323 index_gen<3,3> indices_3;
324 accept_gen(indices_3);
330 testResultXml("dimtest");