source: trunk/yat/utility/Range.h @ 3210

Last change on this file since 3210 was 3210, checked in by Peter, 8 years ago

update copyright years

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1#ifndef _theplu_yat_utility_range_
2#define _theplu_yat_utility_range_
3
4// $Id: Range.h 3210 2014-05-05 06:10:02Z peter $
5
6/*
7  Copyright (C) 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 2014 Peter Johansson
9
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include <algorithm>
27
28namespace theplu {
29namespace yat {
30namespace utility {
31
32  /**
33     @brief A class for storing a shallow copy of a Range
34
35     This class can be used to create a shallow copy of range, [first,
36     end), defined by two iterators of type T. This can be useful, for
37     example, when creating numerous sub-ranges of a larger container.
38
39     \since New in yat 0.5
40
41     \see <a href="\boost_url/range/index.html">Boost Range class</a>,
42     which provides a more extensive interface.
43  */
44  template<typename T>
45  class Range
46  {
47  public:
48    /**
49       Iterator type T.
50     */
51    typedef T iterator_type;
52
53    /**
54       @brief Default Constructor
55    */
56    // For STL container usage
57    Range(void);
58
59    /**
60       \brief Constructor
61    */
62    Range(T first, T last);
63
64    /**
65       \note If T is a mutable iterator, it is possible to use
66       returned iterator to modify underlying range although this
67       function is const.
68
69       \return iterator indicating beginning of Range.
70     */
71    T begin(void) const;
72
73    /**
74       \return iterator after the Range.
75     */
76    T end(void) const;
77
78
79    /**
80       @brief Does not modify underlying data.
81
82       This only changes this object by reassigning two iterators,
83       begin() and end(). If you would like to modify the underlying
84       data, use std::copy instead.
85    */
86    Range& operator=(const Range&);
87
88  private:
89    // Using compiler generated copy constructor
90    // Range(const Range&);
91
92    T first_;
93    T last_;
94  };
95
96  /**
97     \brief Equality comparison
98     \return true iff underlying elements are equal
99
100     \since New in yat 0.5
101
102     \relatesalso Range
103   */
104  template<typename T1, typename T2>
105  bool operator==(const Range<T1>&, const Range<T2>&);
106
107  /**
108     \brief Based on operator==
109
110     \since New in yat 0.5
111
112     \relatesalso Range
113   */
114  template<typename T1, typename T2>
115  bool operator!=(const Range<T1>&, const Range<T2>&);
116
117  /**
118     \brief Ordering relation
119
120     Using std::lexicographical_compare
121
122     \return true if \a lhs < \a rhs
123
124     \since New in yat 0.5
125
126     \relatesalso Range
127   */
128  template<typename T1, typename T2>
129  bool operator<(const Range<T1>& lhs, const Range<T2>& rhs);
130
131  /**
132     \return ! (\a rhs < \a lhs )
133
134     \since New in yat 0.5
135
136     \relatesalso Range
137   */
138  template<typename T1, typename T2>
139  bool operator<=(const Range<T1>& lhs, const Range<T2>& rhs);
140
141  /**
142     \return \a rhs < \a lhs
143
144     \since New in yat 0.5
145
146     \relatesalso Range
147   */
148  template<typename T1, typename T2>
149  bool operator>(const Range<T1>&, const Range<T2>&);
150
151  /**
152     \return ! (\a lhs < \a rhs )
153
154     \since New in yat 0.5
155
156     \relatesalso Range
157   */
158  template<typename T1, typename T2>
159  bool operator>=(const Range<T1>&, const Range<T2>&);
160
161
162  // implementations
163  template<typename T>
164  Range<T>::Range(void){}
165
166  template<typename T>
167  Range<T>::Range(T first, T last)
168    : first_(first), last_(last)
169  {}
170
171  template<typename T>
172  T Range<T>::begin(void) const
173  { return first_; }
174
175
176  template<typename T>
177  T Range<T>::end(void) const
178  { return last_; }
179
180
181  template<typename T>
182  Range<T>& Range<T>::operator=(const Range<T>& rhs)
183  {
184    first_ = rhs.begin();
185    last_ = rhs.end();
186    return *this;
187  }
188
189
190  template<typename T1, typename T2>
191  bool operator==(const Range<T1>& lhs, const Range<T2>& rhs)
192  {
193    // we are not using std::equal because we want to handle ranges of
194    // different length
195    T1 first1(lhs.begin());
196    T1 last1(lhs.end());
197    T2 first2(rhs.begin());
198    T2 last2(rhs.end());
199    while (first1 != last1 && first2 != last2) {
200      if (*first1 != *first2)
201        return false;
202      ++first1;
203      ++first2;
204    }
205    // check that ranges are equally long
206    return first1==last1 && first2==last2;
207  }
208
209
210  template<typename T1, typename T2>
211  bool operator!=(const Range<T1>& lhs, const Range<T2>& rhs)
212  {
213    return ! (lhs==rhs);
214  }
215
216
217  template<typename T1, typename T2>
218  bool operator<(const Range<T1>& lhs, const Range<T2>& rhs)
219  {
220    return std::lexicographical_compare(lhs.begin(), lhs.end(),
221                                        rhs.begin(), rhs.end());
222  }
223
224
225  template<typename T1, typename T2>
226  bool operator>(const Range<T1>& lhs, const Range<T2>& rhs)
227  {
228    return rhs < lhs;
229  }
230
231
232  template<typename T1, typename T2>
233  bool operator<=(const Range<T1>& lhs, const Range<T2>& rhs)
234  {
235    return ! (rhs<lhs);
236  }
237
238
239  template<typename T1, typename T2>
240  bool operator>=(const Range<T1>& lhs, const Range<T2>& rhs)
241  {
242    return ! (lhs<rhs);
243  }
244
245}}} // of namespace utility, yat, and theplu
246
247#endif
Note: See TracBrowser for help on using the repository browser.