~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to boost/multi_array/index_range.hpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
  private:
 
39
    static index from_start()
 
40
      { return (std::numeric_limits<index>::min)(); }
 
41
 
 
42
    static index to_end()
 
43
      { return (std::numeric_limits<index>::max)(); }
 
44
 
 
45
  public:
 
46
 
 
47
    index_range()
 
48
    {
 
49
      start_ = from_start();
 
50
      finish_ = to_end();
 
51
      stride_ = 1;
 
52
      degenerate_ = false;
 
53
    }
 
54
 
 
55
    explicit index_range(index pos)
 
56
    {
 
57
      start_ = pos;
 
58
      finish_ = pos+1;
 
59
      stride_ = 1;
 
60
      degenerate_ = true;
 
61
    }
 
62
 
 
63
    explicit index_range(index start, index finish, index stride=1)
 
64
      : start_(start), finish_(finish), stride_(stride),
 
65
        degenerate_(false)
 
66
    { }
 
67
 
 
68
 
 
69
    // These are for chaining assignments to an index_range
 
70
    index_range& start(index s) {
 
71
      start_ = s;
 
72
      degenerate_ = false;
 
73
      return *this;
 
74
    }
 
75
 
 
76
    index_range& finish(index f) {
 
77
      finish_ = f;
 
78
      degenerate_ = false;
 
79
      return *this;
 
80
    }
 
81
 
 
82
    index_range& stride(index s) { stride_ = s; return *this; }
 
83
 
 
84
    index start() const
 
85
    { 
 
86
      return start_; 
 
87
    }
 
88
 
 
89
    index get_start(index low_index_range = index_range::from_start()) const
 
90
    { 
 
91
      if (start_ == from_start())
 
92
        return low_index_range;
 
93
      return start_; 
 
94
    }
 
95
 
 
96
    index finish() const
 
97
    {
 
98
      return finish_;
 
99
    }
 
100
 
 
101
    index get_finish(index high_index_range = index_range::to_end()) const
 
102
    {
 
103
      if (finish_ == to_end())
 
104
        return high_index_range;
 
105
      return finish_;
 
106
    }
 
107
 
 
108
    index stride() const { return stride_; }
 
109
 
 
110
    void set_index_range(index start, index finish, index stride=1)
 
111
    {
 
112
      start_ = start;
 
113
      finish_ = finish;
 
114
      stride_ = stride;
 
115
    }
 
116
 
 
117
    static index_range all() 
 
118
    { return index_range(from_start(), to_end(), 1); }
 
119
 
 
120
    bool is_degenerate() const { return degenerate_; }
 
121
 
 
122
    index_range operator-(index shift) const
 
123
    { 
 
124
      return index_range(start_ - shift, finish_ - shift, stride_); 
 
125
    }
 
126
 
 
127
    index_range operator+(index shift) const
 
128
    { 
 
129
      return index_range(start_ + shift, finish_ + shift, stride_); 
 
130
    }
 
131
 
 
132
    index operator[](unsigned i) const
 
133
    {
 
134
      return start_ + i * stride_;
 
135
    }
 
136
 
 
137
    index operator()(unsigned i) const
 
138
    {
 
139
      return start_ + i * stride_;
 
140
    }
 
141
 
 
142
    // add conversion to std::slice?
 
143
 
 
144
  public:
 
145
    index start_, finish_, stride_;
 
146
    bool degenerate_;
 
147
  };
 
148
 
 
149
  // Express open and closed interval end-points using the comparison
 
150
  // operators.
 
151
 
 
152
  // left closed
 
153
  template <typename Index, typename SizeType>
 
154
  inline index_range<Index,SizeType>
 
155
  operator<=(Index s, const index_range<Index,SizeType>& r)
 
156
  {
 
157
    return index_range<Index,SizeType>(s, r.finish(), r.stride());
 
158
  }
 
159
 
 
160
  // left open
 
161
  template <typename Index, typename SizeType>
 
162
  inline index_range<Index,SizeType>
 
163
  operator<(Index s, const index_range<Index,SizeType>& r)
 
164
  {
 
165
    return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
 
166
  }
 
167
 
 
168
  // right open
 
169
  template <typename Index, typename SizeType>
 
170
  inline index_range<Index,SizeType>
 
171
  operator<(const index_range<Index,SizeType>& r, Index f)
 
172
  {
 
173
    return index_range<Index,SizeType>(r.start(), f, r.stride());
 
174
  }
 
175
 
 
176
  // right closed
 
177
  template <typename Index, typename SizeType>
 
178
  inline index_range<Index,SizeType>
 
179
  operator<=(const index_range<Index,SizeType>& r, Index f)
 
180
  {
 
181
    return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
 
182
  }
 
183
 
 
184
} // namespace multi_array
 
185
} // namespace detail  
 
186
} // namespace boost
 
187
 
 
188
#endif // BOOST_INDEX_RANGE_RG071801_HPP