Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_O3TL_RANGE_HXX
21 : #define INCLUDED_O3TL_RANGE_HXX
22 :
23 :
24 : #include <cstring> // for std::size_t
25 : #include <boost/assert.hpp>
26 :
27 :
28 :
29 : namespace o3tl
30 : {
31 : /** Represents a range of integer or iterator values.
32 :
33 : @tpl T
34 : Has to be assignable, add- and subtractable. That is:
35 : either it is
36 : - an integral type
37 : - or a random access iterator.
38 : */
39 : template <class T>
40 : class range
41 : {
42 : public:
43 : typedef T element_type; /// Provided for generic programming.
44 : typedef range<T> self;
45 :
46 : // LIFECYCLE
47 : range(
48 : T i_inclusiveLowerBorder,
49 : T i_exclusiveUpperBorder );
50 : ~range();
51 : // INQUIRY
52 : T begin() const;
53 : T end() const;
54 : std::size_t size() const;
55 :
56 : bool contains(
57 : T i_value ) const;
58 : bool contains(
59 : const self & i_other ) const;
60 : bool overlaps(
61 : const self & i_other ) const;
62 : /// @return i_other.begin() - this->end()
63 : long distance_to(
64 : const self & i_other ) const;
65 : private:
66 : // DATA
67 : T nBegin;
68 : T nEnd;
69 : };
70 :
71 :
72 : template <class T>
73 : inline range<T>
74 6 : make_range(T i1, T i2)
75 : {
76 6 : return range<T>(i1, i2);
77 : }
78 :
79 : template <class T>
80 : inline range<typename T::const_iterator>
81 1 : range_of(const T & i_container)
82 : {
83 : return make_range( i_container.begin(),
84 : i_container.end()
85 1 : );
86 : }
87 :
88 : template <class T>
89 : inline range<typename T::iterator>
90 1 : range_of(T & io_container)
91 : {
92 : return make_range( io_container.begin(),
93 : io_container.end()
94 1 : );
95 : }
96 :
97 :
98 :
99 :
100 :
101 : // IMPLEMENTATION
102 :
103 : template <class T>
104 32 : range<T>::range( T i_inclusiveLowerBorder,
105 : T i_exclusiveUpperBorder )
106 : : nBegin(i_inclusiveLowerBorder),
107 32 : nEnd(i_exclusiveUpperBorder)
108 : {
109 : BOOST_ASSERT( nBegin <= nEnd
110 : && "Invalid parameters for range<> constructor.");
111 32 : }
112 :
113 : template <class T>
114 32 : range<T>::~range()
115 : {
116 32 : }
117 :
118 : template <class T>
119 : inline T
120 161 : range<T>::begin() const
121 : {
122 161 : return nBegin;
123 : }
124 :
125 : template <class T>
126 : inline T
127 107 : range<T>::end() const
128 : {
129 107 : return nEnd;
130 : }
131 :
132 : template <class T>
133 : inline std::size_t
134 4 : range<T>::size() const
135 : {
136 : BOOST_ASSERT( nBegin <= nEnd
137 : && "Invalid range limits in range<>::size().");
138 4 : return static_cast<std::size_t>( end() - begin() );
139 : }
140 :
141 : template <class T>
142 : bool
143 76 : range<T>::contains(T i_value ) const
144 : {
145 190 : return begin() <= i_value
146 190 : && i_value < end();
147 : }
148 :
149 : template <class T>
150 : bool
151 24 : range<T>::contains(const self & i_other) const
152 : {
153 : // This is subtle, because this would be wrong:
154 : // begin() <= i_other.begin()
155 : // && i_other.end() <= end();
156 : // An empty range that begins and starts at my end()
157 : // must not be contained.
158 :
159 24 : return contains(i_other.begin())
160 36 : && i_other.end() <= end();
161 : }
162 :
163 : template <class T>
164 : bool
165 26 : range<T>::overlaps(const self & i_other) const
166 : {
167 26 : return contains(i_other.begin())
168 26 : || i_other.contains(begin());
169 : }
170 :
171 : template <class T>
172 : long
173 10 : range<T>::distance_to(const self & i_other) const
174 : {
175 10 : return i_other.begin() - end();
176 : }
177 :
178 :
179 :
180 : } // namespace o3tl
181 : #endif
182 :
183 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|