xref: /aoo4110/main/cosv/inc/cosv/tpl/range.hxx (revision b1cdbd2c)
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