Branch data 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 : 30 : make_range(T i1, T i2)
75 : : {
76 [ + - ][ + - ]: 30 : return range<T>(i1, i2);
77 : : }
78 : :
79 : : template <class T>
80 : : inline range<typename T::const_iterator>
81 : 5 : range_of(const T & i_container)
82 : : {
83 : : return make_range( i_container.begin(),
84 : : i_container.end()
85 : 5 : );
86 : : }
87 : :
88 : : template <class T>
89 : : inline range<typename T::iterator>
90 : 5 : range_of(T & io_container)
91 : : {
92 : : return make_range( io_container.begin(),
93 : : io_container.end()
94 [ + - ]: 5 : );
95 : : }
96 : :
97 : :
98 : :
99 : :
100 : :
101 : : // IMPLEMENTATION
102 : :
103 : : template <class T>
104 : 160 : range<T>::range( T i_inclusiveLowerBorder,
105 : : T i_exclusiveUpperBorder )
106 : : : nBegin(i_inclusiveLowerBorder),
107 : 5 : nEnd(i_exclusiveUpperBorder)
108 : : {
109 : : BOOST_ASSERT( nBegin <= nEnd
110 : : && "Invalid parameters for range<> constructor.");
111 : 160 : }
112 : :
113 : : template <class T>
114 : 160 : range<T>::~range()
115 : : {
116 : 160 : }
117 : :
118 : : template <class T>
119 : : inline T
120 : 805 : range<T>::begin() const
121 : : {
122 : 805 : return nBegin;
123 : : }
124 : :
125 : : template <class T>
126 : : inline T
127 : 535 : range<T>::end() const
128 : : {
129 : 535 : return nEnd;
130 : : }
131 : :
132 : : template <class T>
133 : : inline std::size_t
134 : 20 : range<T>::size() const
135 : : {
136 : : BOOST_ASSERT( nBegin <= nEnd
137 : : && "Invalid range limits in range<>::size().");
138 [ + - ]: 20 : return static_cast<std::size_t>( end() - begin() );
139 : : }
140 : :
141 : : template <class T>
142 : : bool
143 : 380 : range<T>::contains(T i_value ) const
144 : : {
145 : : return begin() <= i_value
146 [ + - ][ + + ]: 380 : && i_value < end();
[ + - ][ + + ]
[ + + ][ + - ]
[ # # # # ]
[ + + ][ + + ]
147 : : }
148 : :
149 : : template <class T>
150 : : bool
151 : 120 : 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 : : return contains(i_other.begin())
160 [ + - ][ + + ]: 120 : && i_other.end() <= end();
[ + - ][ + + ]
[ + + ][ + + ]
[ # # # # ]
[ + + ][ + + ]
161 : : }
162 : :
163 : : template <class T>
164 : : bool
165 : 130 : range<T>::overlaps(const self & i_other) const
166 : : {
167 : : return contains(i_other.begin())
168 [ + + ][ + + ]: 130 : || i_other.contains(begin());
[ + + ][ + + ]
169 : : }
170 : :
171 : : template <class T>
172 : : long
173 : 50 : range<T>::distance_to(const self & i_other) const
174 : : {
175 [ + - ]: 50 : return i_other.begin() - end();
176 : : }
177 : :
178 : :
179 : :
180 : : } // namespace o3tl
181 : : #endif
182 : :
183 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|