xref: /aoo4110/main/o3tl/inc/o3tl/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 INCLUDED_O3TL_RANGE_HXX
25 #define INCLUDED_O3TL_RANGE_HXX
26 
27 
28 #include <cstring>  // for std::size_t
29 #include <boost/assert.hpp>
30 
31 
32 
33 namespace o3tl
34 {
35 /** Represents a range of integer or iterator values.
36 
37     @tpl T
38     Has to be assignable, add- and subtractable. That is:
39     either it is
40         - an integral type
41         - or a random access iterator.
42 */
43 template <class T>
44 class range
45 {
46   public:
47     typedef T           element_type;       /// Provided for generic programming.
48     typedef range<T>    self;
49 
50   // LIFECYCLE
51                         range(
52                             T                   i_inclusiveLowerBorder,
53                             T                   i_exclusiveUpperBorder );
54 						~range();
55   // INQUIRY
56     T                   begin() const;
57     T                   end() const;
58     std::size_t         size() const;
59 
60     bool                contains(
61                             T                   i_value ) const;
62     bool                contains(
63                             const self &        i_other ) const;
64     bool                overlaps(
65                             const self &        i_other ) const;
66     /// @return i_other.begin() - this->end()
67     long                distance_to(
68                             const self &        i_other ) const;
69   private:
70   // DATA
71 	T                   nBegin;
72 	T                   nEnd;
73 };
74 
75 
76 template <class T>
77 inline range<T>
make_range(T i1,T i2)78 make_range(T i1, T i2)
79 {
80     return range<T>(i1, i2);
81 }
82 
83 template <class T>
84 inline range<typename T::const_iterator>
range_of(const T & i_container)85 range_of(const T & i_container)
86 {
87     return make_range( i_container.begin(),
88                        i_container.end()
89                      );
90 }
91 
92 template <class T>
93 inline range<typename T::iterator>
range_of(T & io_container)94 range_of(T & io_container)
95 {
96     return make_range( io_container.begin(),
97                        io_container.end()
98                      );
99 }
100 
101 
102 
103 
104 
105 // IMPLEMENTATION
106 
107 template <class T>
range(T i_inclusiveLowerBorder,T i_exclusiveUpperBorder)108 range<T>::range( T i_inclusiveLowerBorder,
109                  T i_exclusiveUpperBorder )
110     :   nBegin(i_inclusiveLowerBorder),
111         nEnd(i_exclusiveUpperBorder)
112 {
113     BOOST_ASSERT(   nBegin <= nEnd
114                  && "Invalid parameters for range<> constructor.");
115 }
116 
117 template <class T>
~range()118 range<T>::~range()
119 {
120 }
121 
122 template <class T>
123 inline T
begin() const124 range<T>::begin() const
125 {
126     return nBegin;
127 }
128 
129 template <class T>
130 inline T
end() const131 range<T>::end() const
132 {
133     return nEnd;
134 }
135 
136 template <class T>
137 inline std::size_t
size() const138 range<T>::size() const
139 {
140     BOOST_ASSERT(   nBegin <= nEnd
141                  && "Invalid range limits in range<>::size().");
142     return static_cast<std::size_t>( end() - begin() );
143 }
144 
145 template <class T>
146 bool
contains(T i_value) const147 range<T>::contains(T i_value ) const
148 {
149     return      begin() <= i_value
150             &&  i_value < end();
151 }
152 
153 template <class T>
154 bool
contains(const self & i_other) const155 range<T>::contains(const self & i_other) const
156 {
157     // This is subtle, because this would be wrong:
158     //      begin() <= i_other.begin()
159     //      &&  i_other.end() <= end();
160     // An empty range that begins and starts at my end()
161     // must not be contained.
162 
163     return      contains(i_other.begin())
164             &&  i_other.end() <= end();
165 }
166 
167 template <class T>
168 bool
overlaps(const self & i_other) const169 range<T>::overlaps(const self & i_other) const
170 {
171     return      contains(i_other.begin())
172             ||  i_other.contains(begin());
173 }
174 
175 template <class T>
176 long
distance_to(const self & i_other) const177 range<T>::distance_to(const self & i_other) const
178 {
179     return i_other.begin() - end();
180 }
181 
182 
183 
184 }   // namespace o3tl
185 #endif
186