]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/index_range.hpp
Upgrade to boost 1.33.1
[lyx.git] / boost / boost / multi_array / index_range.hpp
1 // Copyright 2002 The Trustees of Indiana University.
2
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)
6
7 //  Boost.MultiArray Library
8 //  Authors: Ronald Garcia
9 //           Jeremy Siek
10 //           Andrew Lumsdaine
11 //  See http://www.boost.org/libs/multi_array for documentation.
12
13 #ifndef BOOST_INDEX_RANGE_RG071801_HPP
14 #define BOOST_INDEX_RANGE_RG071801_HPP
15
16 #include <boost/config.hpp>
17 #include <utility>
18 #include <boost/limits.hpp>
19
20 // For representing intervals, also with stride.
21 // A degenerate range is a range with one element.
22
23 // Thanks to Doug Gregor for the really cool idea of using the
24 // comparison operators to express various interval types!
25
26 // Internally, we represent the interval as half-open.
27
28 namespace boost {
29 namespace detail {
30 namespace multi_array {
31
32   template <typename Index,typename SizeType>
33   class index_range {
34   public:
35     typedef Index index;
36     typedef SizeType size_type;
37
38     index_range()
39     {
40       start_ = from_start();
41       finish_ = to_end();
42       stride_ = 1;
43       degenerate_ = false;
44     }
45
46     explicit index_range(index pos)
47     {
48       start_ = pos;
49       finish_ = pos;
50       stride_ = 1;
51       degenerate_ = true;
52     }
53
54     explicit index_range(index start, index finish, index stride=1)
55       : start_(start), finish_(finish), stride_(stride),
56         degenerate_(false)
57     { }
58
59
60     // These are for chaining assignments to an index_range
61     index_range& start(index s) {
62       start_ = s;
63       degenerate_ = (start_ == finish_);
64       return *this;
65     }
66
67     index_range& finish(index f) {
68       finish_ = f;
69       degenerate_ = (start_ == finish_);
70       return *this;
71     }
72
73     index_range& stride(index s) { stride_ = s; return *this; }
74
75     index start() const
76     { 
77       return start_; 
78     }
79
80     index get_start(index low_index_range = 0) const
81     { 
82       if (start_ == from_start())
83         return low_index_range;
84       return start_; 
85     }
86
87     index finish() const
88     {
89       return finish_;
90     }
91
92     index get_finish(index high_index_range = 0) const
93     {
94       if (finish_ == to_end())
95         return high_index_range;
96       return finish_;
97     }
98
99     size_type size(index recommended_length = 0) const
100     {
101       if ((start_ == from_start()) || (finish_ == to_end()))
102         return recommended_length;
103       else 
104         return (finish_ - start_) / stride_;
105     }
106
107     index stride() const { return stride_; }
108
109     bool is_ascending_contiguous() const
110     {
111       return (start_ < finish_) && is_unit_stride();
112     }
113
114     void set_index_range(index start, index finish, index stride=1)
115     {
116       start_ = start;
117       finish_ = finish;
118       stride_ = stride;
119     }
120
121     static index_range all() 
122     { return index_range(from_start(), to_end(), 1); }
123
124     bool is_unit_stride() const
125     { return stride_ == 1; }
126
127     bool is_degenerate() const { return degenerate_; }
128
129     index_range operator-(index shift) const
130     { 
131       return index_range(start_ - shift, finish_ - shift, stride_); 
132     }
133
134     index_range operator+(index shift) const
135     { 
136       return index_range(start_ + shift, finish_ + shift, stride_); 
137     }
138
139     index operator[](unsigned i) const
140     {
141       return start_ + i * stride_;
142     }
143
144     index operator()(unsigned i) const
145     {
146       return start_ + i * stride_;
147     }
148
149     // add conversion to std::slice?
150
151   private:
152     static index from_start()
153       { return (std::numeric_limits<index>::min)(); }
154
155     static index to_end()
156       { return (std::numeric_limits<index>::max)(); }
157   public:
158     index start_, finish_, stride_;
159     bool degenerate_;
160   };
161
162   // Express open and closed interval end-points using the comparison
163   // operators.
164
165   // left closed
166   template <typename Index, typename SizeType>
167   inline index_range<Index,SizeType>
168   operator<=(Index s, const index_range<Index,SizeType>& r)
169   {
170     return index_range<Index,SizeType>(s, r.finish(), r.stride());
171   }
172
173   // left open
174   template <typename Index, typename SizeType>
175   inline index_range<Index,SizeType>
176   operator<(Index s, const index_range<Index,SizeType>& r)
177   {
178     return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
179   }
180
181   // right open
182   template <typename Index, typename SizeType>
183   inline index_range<Index,SizeType>
184   operator<(const index_range<Index,SizeType>& r, Index f)
185   {
186     return index_range<Index,SizeType>(r.start(), f, r.stride());
187   }
188
189   // right closed
190   template <typename Index, typename SizeType>
191   inline index_range<Index,SizeType>
192   operator<=(const index_range<Index,SizeType>& r, Index f)
193   {
194     return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
195   }
196
197 } // namespace multi_array
198 } // namespace detail  
199 } // namespace boost
200
201 #endif // BOOST_INDEX_RANGE_RG071801_HPP