1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef CSV_RANGE_HXX
25 #define CSV_RANGE_HXX
26
27 #include <cstring> // for std::size_t
28
29
30
31
32 namespace csv
33 {
34
35
36 /** Represents a range of integer or iterator values.
37
38 @tpl T
39 Has to be assignable, add- and subtractable. That is:
40 either it is
41 - an integral type
42 - or a random access iterator.
43 */
44 template <class T>
45 class range
46 {
47 public:
48 typedef T element_type; /// Provided for generic programming.
49 typedef range<T> self;
50
51 // LIFECYCLE
52 range(
53 T i_inclusiveLowerBorder,
54 T i_exclusiveUpperBorder );
55 ~range();
56 // INQUIRY
57 T begin() const;
58 T end() const;
59 std::size_t size() const;
60
61 bool contains(
62 T i_value ) const;
63 bool contains(
64 const self & i_other ) const;
65 bool overlaps(
66 const self & i_other ) const;
67 /// @return i_other.begin() - this->end()
68 long distance_to(
69 const self & i_other ) const;
70 private:
71 // DATA
72 T nBegin;
73 T nEnd;
74 };
75
76
77 template <class T>
78 inline range<T>
make_range(T i1,T i2)79 make_range(T i1, T i2)
80 {
81 return range<T>(i1, i2);
82 }
83
84 template <class T>
85 inline range<typename T::const_iterator>
range_of(const T & i_container)86 range_of(const T & i_container)
87 {
88 return make_range( i_container.begin(),
89 i_container.end()
90 );
91 }
92
93 template <class T>
94 inline range<typename T::iterator>
range_of(T & io_container)95 range_of(T & io_container)
96 {
97 return make_range( io_container.begin(),
98 io_container.end()
99 );
100 }
101
102
103
104
105
106 // IMPLEMENTATION
107
108 template <class T>
range(T i_inclusiveLowerBorder,T i_exclusiveUpperBorder)109 range<T>::range( T i_inclusiveLowerBorder,
110 T i_exclusiveUpperBorder )
111 : nBegin(i_inclusiveLowerBorder),
112 nEnd(i_exclusiveUpperBorder)
113 {
114 csv_assert( nBegin <= nEnd
115 && "Invalid parameters for range<> constructor.");
116 }
117
118 template <class T>
~range()119 range<T>::~range()
120 {
121 }
122
123 template <class T>
124 inline T
begin() const125 range<T>::begin() const
126 {
127 return nBegin;
128 }
129
130 template <class T>
131 inline T
end() const132 range<T>::end() const
133 {
134 return nEnd;
135 }
136
137 template <class T>
138 inline std::size_t
size() const139 range<T>::size() const
140 {
141 csv_assert( nBegin <= nEnd
142 && "Invalid range limits in range<>::size().");
143 return static_cast<std::size_t>( end() - begin() );
144 }
145
146 template <class T>
147 bool
contains(T i_value) const148 range<T>::contains(T i_value ) const
149 {
150 return begin() <= i_value
151 && i_value < end();
152 }
153
154 template <class T>
155 bool
contains(const self & i_other) const156 range<T>::contains(const self & i_other) const
157 {
158 // This is subtle, because this would be wrong:
159 // begin() <= i_other.begin()
160 // && i_other.end() <= end();
161 // An empty range that begins and starts at my end()
162 // must not be contained.
163
164 return contains(i_other.begin())
165 && i_other.end() <= end();
166 }
167
168 template <class T>
169 bool
overlaps(const self & i_other) const170 range<T>::overlaps(const self & i_other) const
171 {
172 return contains(i_other.begin())
173 || i_other.contains(begin());
174 }
175
176 template <class T>
177 long
distance_to(const self & i_other) const178 range<T>::distance_to(const self & i_other) const
179 {
180 return i_other.begin() - end();
181 }
182
183
184
185
186 } // namespace csv
187 #endif
188