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

Last change on this file since 1797 was 1797, checked in by Peter, 15 years ago

updating copyright statements

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