OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
DaleCurtis
2015/10/19 21:45:25
Is this just a std::map<x, Range> ?
https://code.
hubbe
2015/10/20 00:31:39
no
Comment added to explain this class.
| |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MEDIA_BLINK_RANGEMAP_H_ | |
6 #define MEDIA_BLINK_RANGEMAP_H_ | |
7 | |
8 #include <limits> | |
9 #include <map> | |
10 | |
11 #include "base/logging.h" | |
12 | |
13 namespace media { | |
14 | |
15 template<typename T> | |
16 struct Range { | |
17 public: | |
18 Range(const T& begin_, const T& end_) : begin(begin_), end(end_) {} | |
19 T begin; | |
20 T end; | |
21 }; | |
22 | |
23 template<typename KeyType, typename ValueType> | |
24 class RangeMapConstIterator { | |
25 public: | |
26 typedef std::map<KeyType, ValueType> MapType; | |
27 RangeMapConstIterator() {} | |
28 RangeMapConstIterator(const MapType* map, | |
29 typename MapType::const_iterator first, | |
30 typename MapType::const_iterator second) : | |
31 map_(map), | |
32 first_(first), | |
33 second_(second) { | |
34 } | |
35 bool operator==(const RangeMapConstIterator& other) { | |
36 return first_ == other.first_ && second_ == other.second_; | |
37 } | |
38 bool operator!=(const RangeMapConstIterator& other) { | |
39 return first_ != other.first_ || second_ != other.second_; | |
40 } | |
41 KeyType range_begin() const { | |
42 if (first_ == map_->end()) { | |
43 return std::numeric_limits<KeyType>::min(); | |
44 } else { | |
45 return first_->first; | |
46 } | |
47 } | |
48 KeyType range_end() const { | |
49 if (second_ == map_->end()) { | |
50 return std::numeric_limits<KeyType>::max(); | |
51 } else { | |
52 return second_->first; | |
53 } | |
54 } | |
55 Range<KeyType> range() const { | |
56 return Range<KeyType>(range_begin(), range_end()); | |
57 } | |
58 | |
59 ValueType value() const { | |
60 if (first_ == map_->end()) | |
61 return 0; | |
62 return first_->second; | |
63 } | |
64 void operator++() { | |
65 first_ = second_; | |
66 second_++; | |
67 } | |
68 void operator--() { | |
69 second_ = first_; | |
70 if (first_ == map_->begin()) { | |
71 first_ = map_->end(); | |
72 } else { | |
73 first_--; | |
74 } | |
75 } | |
76 private: | |
77 const MapType* map_; | |
78 typename MapType::const_iterator first_; | |
79 typename MapType::const_iterator second_; | |
80 }; | |
81 | |
82 template<typename KeyType, typename ValueType> | |
83 class RangeMap { | |
84 public: | |
85 typedef std::map<KeyType, ValueType> MapType; | |
86 typedef RangeMapConstIterator<KeyType, ValueType> const_iterator; | |
87 | |
88 ValueType operator[](KeyType k) const { | |
89 typename MapType::const_iterator i = map_.upper_bound(k); | |
90 if (i == map_.begin()) { | |
91 return 0; | |
92 } else { | |
93 --i; | |
94 return i->second; | |
95 } | |
96 } | |
97 | |
98 // Increase [from..to) by howmuch. | |
99 void IncrementRange(KeyType from, KeyType to, ValueType howmuch) { | |
100 DCHECK_GE(to, from); | |
101 if (from == to || howmuch == 0) | |
102 return; | |
103 typename MapType::iterator a = MakeEntry(from); | |
104 typename MapType::iterator b = MakeEntry(to); | |
105 for (typename MapType::iterator i = a; i != b; ++i) { | |
106 i->second += howmuch; | |
107 } | |
108 RemoveDuplicates(a); | |
109 // b may be invalid | |
110 RemoveDuplicates(map_.lower_bound(to)); | |
111 } | |
112 | |
113 // Set [from..to) to howmuch. | |
114 void SetRange(KeyType from, KeyType to, ValueType howmuch) { | |
115 DCHECK_GE(to, from); | |
116 if (from == to) | |
117 return; | |
118 typename MapType::iterator a = MakeEntry(from); | |
119 typename MapType::iterator b = MakeEntry(to); | |
120 a->second = howmuch; | |
121 while (true) { | |
122 typename MapType::iterator c = a; | |
123 ++c; | |
124 if (c == b) { | |
125 break; | |
126 } else { | |
127 map_.erase(c); | |
128 } | |
129 } | |
130 RemoveDuplicates(a); | |
131 // b may be invalid | |
132 RemoveDuplicates(map_.lower_bound(to)); | |
133 } | |
134 | |
135 // Returns an iterator to the first range. | |
136 // Note, there is always at least one range. | |
137 const_iterator first_range() const { | |
138 return const_iterator(&map(), map_.end(), map_.begin()); | |
139 } | |
140 | |
141 // Returns an iterator to the last range. | |
142 // Note, there is always at least one range. | |
143 const_iterator last_range() const { | |
144 if (map_.empty()) { | |
145 return const_iterator(&map(), map_.end(), map_.end()); | |
146 } | |
147 typename MapType::const_iterator i = map_.end(); | |
148 --i; | |
149 return const_iterator(&map(), i, map_.end()); | |
150 } | |
151 | |
152 // Returns an iterator to the range containing |k|. | |
153 // Always returns a valid iterator. | |
154 const_iterator find(KeyType k) const { | |
155 if (map_.empty()) { | |
156 return const_iterator(&map(), map_.end(), map_.end()); | |
157 } | |
158 typename MapType::const_iterator i = map_.upper_bound(k); | |
159 typename MapType::const_iterator j = i; | |
160 if (j == map_.begin()) { | |
161 j = map_.end(); | |
162 } else { | |
163 --j; | |
164 } | |
165 return const_iterator(&map(), j, i); | |
166 } | |
167 | |
168 const MapType& map() const { return map_; } | |
169 | |
170 private: | |
171 typename MapType::iterator MakeEntry(KeyType k) { | |
172 typename MapType::value_type tmp(k, 0); | |
173 std::pair<typename MapType::iterator, bool> insert_result; | |
174 insert_result = map_.insert(tmp); | |
175 if (insert_result.second) { | |
176 if (insert_result.first != map_.begin()) { | |
177 typename MapType::iterator i = insert_result.first; | |
178 --i; | |
179 insert_result.first->second = i->second; | |
180 } | |
181 } | |
182 return insert_result.first; | |
183 } | |
184 | |
185 void RemoveDuplicates(typename MapType::iterator i) { | |
186 if (i == map_.end()) | |
187 return; | |
188 if (i == map_.begin() && i->second == 0) { | |
189 typename MapType::iterator j = i; | |
190 ++i; | |
191 map_.erase(j); | |
192 if (i == map_.end()) | |
193 return; | |
194 } | |
195 if (i != map_.begin()) { | |
196 typename MapType::iterator j = i; | |
197 --i; | |
198 if (i ->second == j->second) { | |
199 map_.erase(j); | |
200 } | |
201 } | |
202 typename MapType::iterator j = i; | |
203 ++j; | |
204 if (j != map_.end() && i ->second == j->second) { | |
205 map_.erase(j); | |
206 } | |
207 } | |
208 | |
209 MapType map_; | |
210 }; | |
211 | |
212 | |
213 } // namespace media | |
214 | |
215 #endif // MEDIA_BLINK_RANGEMAP_H_ | |
OLD | NEW |