Chris@16
|
1 /*-----------------------------------------------------------------------------+
|
Chris@16
|
2 Copyright (c) 2010-2010: Joachim Faulhaber
|
Chris@16
|
3 +------------------------------------------------------------------------------+
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
5 (See accompanying file LICENCE.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 +-----------------------------------------------------------------------------*/
|
Chris@16
|
8 #ifndef BOOST_ICL_CONCEPT_INTERVAL_MAP_HPP_JOFA_100920
|
Chris@16
|
9 #define BOOST_ICL_CONCEPT_INTERVAL_MAP_HPP_JOFA_100920
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/icl/type_traits/element_type_of.hpp>
|
Chris@16
|
12 #include <boost/icl/type_traits/segment_type_of.hpp>
|
Chris@16
|
13 #include <boost/icl/type_traits/absorbs_identities.hpp>
|
Chris@16
|
14 #include <boost/icl/type_traits/is_combinable.hpp>
|
Chris@16
|
15 #include <boost/icl/type_traits/is_interval_splitter.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/icl/detail/set_algo.hpp>
|
Chris@16
|
18 #include <boost/icl/detail/interval_map_algo.hpp>
|
Chris@16
|
19 #include <boost/icl/concept/interval.hpp>
|
Chris@16
|
20 #include <boost/icl/concept/joinable.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost{ namespace icl
|
Chris@16
|
23 {
|
Chris@16
|
24
|
Chris@16
|
25 template<class Type>
|
Chris@16
|
26 inline typename enable_if<is_interval_map<Type>, typename Type::segment_type>::type
|
Chris@16
|
27 make_segment(const typename Type::element_type& element)
|
Chris@16
|
28 {
|
Chris@16
|
29 typedef typename Type::interval_type interval_type;
|
Chris@16
|
30 typedef typename Type::segment_type segment_type;
|
Chris@16
|
31 return segment_type(icl::singleton<interval_type>(element.key), element.data);
|
Chris@16
|
32 }
|
Chris@16
|
33
|
Chris@16
|
34
|
Chris@16
|
35 //==============================================================================
|
Chris@16
|
36 //= Containedness<IntervalMap>
|
Chris@16
|
37 //==============================================================================
|
Chris@16
|
38 //------------------------------------------------------------------------------
|
Chris@16
|
39 //- bool contains(c T&, c P&) T:{M} P:{b p M} fragment_types
|
Chris@16
|
40 //------------------------------------------------------------------------------
|
Chris@16
|
41 template<class Type>
|
Chris@16
|
42 typename enable_if<is_interval_map<Type>, bool>::type
|
Chris@16
|
43 contains(const Type& super, const typename Type::element_type& key_value_pair)
|
Chris@16
|
44 {
|
Chris@16
|
45 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
46 const_iterator it_ = icl::find(super, key_value_pair.key);
|
Chris@16
|
47 return it_ != super.end() && (*it_).second == key_value_pair.data;
|
Chris@16
|
48 }
|
Chris@16
|
49
|
Chris@16
|
50 template<class Type>
|
Chris@16
|
51 typename enable_if<is_interval_map<Type>, bool>::type
|
Chris@16
|
52 contains(const Type& super, const typename Type::segment_type& sub_segment)
|
Chris@16
|
53 {
|
Chris@16
|
54 typedef typename Type::interval_type interval_type;
|
Chris@16
|
55 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
56
|
Chris@16
|
57 interval_type sub_interval = sub_segment.first;
|
Chris@16
|
58 if(icl::is_empty(sub_interval))
|
Chris@16
|
59 return true;
|
Chris@16
|
60
|
Chris@16
|
61 std::pair<const_iterator, const_iterator> exterior = super.equal_range(sub_interval);
|
Chris@16
|
62 if(exterior.first == exterior.second)
|
Chris@16
|
63 return false;
|
Chris@16
|
64
|
Chris@16
|
65 const_iterator last_overlap = prior(exterior.second);
|
Chris@16
|
66
|
Chris@16
|
67 if(!(sub_segment.second == exterior.first->second) )
|
Chris@16
|
68 return false;
|
Chris@16
|
69
|
Chris@16
|
70 return
|
Chris@16
|
71 icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
|
Chris@16
|
72 && Interval_Map::is_joinable(super, exterior.first, last_overlap);
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 template<class Type, class CoType>
|
Chris@16
|
76 typename enable_if<is_concept_compatible<is_interval_map, Type, CoType>, bool>::type
|
Chris@16
|
77 contains(const Type& super, const CoType& sub)
|
Chris@16
|
78 {
|
Chris@16
|
79 return Interval_Set::within(sub, super);
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82
|
Chris@16
|
83 //------------------------------------------------------------------------------
|
Chris@16
|
84 //- bool contains(c T&, c P&) T:{M} P:{e i S} key_types : total
|
Chris@16
|
85 //------------------------------------------------------------------------------
|
Chris@16
|
86 template<class Type, class CoType>
|
Chris@16
|
87 typename enable_if< mpl::and_< is_interval_map<Type>
|
Chris@16
|
88 , is_total<Type>
|
Chris@16
|
89 , is_cross_derivative<Type, CoType> >
|
Chris@16
|
90 , bool>::type
|
Chris@16
|
91 contains(const Type&, const CoType&)
|
Chris@16
|
92 {
|
Chris@16
|
93 return true;
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 //------------------------------------------------------------------------------
|
Chris@16
|
97 //- bool contains(c T&, c P&) T:{M} P:{e i S} key_types : partial
|
Chris@16
|
98 //------------------------------------------------------------------------------
|
Chris@16
|
99 template<class Type>
|
Chris@16
|
100 typename enable_if< mpl::and_< is_interval_map<Type>
|
Chris@16
|
101 , mpl::not_<is_total<Type> > >
|
Chris@16
|
102 , bool>::type
|
Chris@16
|
103 contains(const Type& super, const typename Type::domain_type& key)
|
Chris@16
|
104 {
|
Chris@16
|
105 return icl::find(super, key) != super.end();
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 template<class Type>
|
Chris@16
|
109 typename enable_if< mpl::and_< is_interval_map<Type>
|
Chris@16
|
110 , mpl::not_<is_total<Type> > >
|
Chris@16
|
111 , bool>::type
|
Chris@16
|
112 contains(const Type& super, const typename Type::interval_type& sub_interval)
|
Chris@16
|
113 {
|
Chris@16
|
114 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
115
|
Chris@16
|
116 if(icl::is_empty(sub_interval))
|
Chris@16
|
117 return true;
|
Chris@16
|
118
|
Chris@16
|
119 std::pair<const_iterator, const_iterator> exterior = super.equal_range(sub_interval);
|
Chris@16
|
120 if(exterior.first == exterior.second)
|
Chris@16
|
121 return false;
|
Chris@16
|
122
|
Chris@16
|
123 const_iterator last_overlap = prior(exterior.second);
|
Chris@16
|
124
|
Chris@16
|
125 return
|
Chris@16
|
126 icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
|
Chris@16
|
127 && Interval_Set::is_joinable(super, exterior.first, last_overlap);
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 template<class Type, class KeyT>
|
Chris@16
|
131 typename enable_if< mpl::and_< is_concept_combinable<is_interval_map, is_interval_set, Type, KeyT>
|
Chris@16
|
132 , mpl::not_<is_total<Type> > >
|
Chris@16
|
133 , bool>::type
|
Chris@16
|
134 contains(const Type& super, const KeyT& sub)
|
Chris@16
|
135 {
|
Chris@16
|
136 return Interval_Set::within(sub, super);
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 //==============================================================================
|
Chris@16
|
140 //= Addition<IntervalMap>
|
Chris@16
|
141 //==============================================================================
|
Chris@16
|
142 //------------------------------------------------------------------------------
|
Chris@16
|
143 //- T& add(T&, c P&) T:{M} P:{b p} fragment_types
|
Chris@16
|
144 //------------------------------------------------------------------------------
|
Chris@16
|
145 template<class Type>
|
Chris@16
|
146 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
147 add(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
148 {
|
Chris@16
|
149 return object.add(operand);
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 template<class Type>
|
Chris@16
|
153 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
154 add(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
155 {
|
Chris@16
|
156 return icl::add(object, make_segment<Type>(operand));
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 //------------------------------------------------------------------------------
|
Chris@16
|
160 //- T& add(T&, J, c P&) T:{M} P:{p} segment_type
|
Chris@16
|
161 //------------------------------------------------------------------------------
|
Chris@16
|
162 template<class Type>
|
Chris@16
|
163 typename enable_if<is_interval_map<Type>, typename Type::iterator >::type
|
Chris@16
|
164 add(Type& object, typename Type::iterator prior_,
|
Chris@16
|
165 const typename Type::segment_type& operand)
|
Chris@16
|
166 {
|
Chris@16
|
167 return object.add(prior_, operand);
|
Chris@16
|
168 }
|
Chris@16
|
169
|
Chris@16
|
170 //==============================================================================
|
Chris@16
|
171 //= Insertion<IntervalMap>
|
Chris@16
|
172 //==============================================================================
|
Chris@16
|
173 //------------------------------------------------------------------------------
|
Chris@16
|
174 //- T& insert(T&, c P&) T:{M} P:{b p} fragment_types
|
Chris@16
|
175 //------------------------------------------------------------------------------
|
Chris@16
|
176 template<class Type>
|
Chris@16
|
177 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
178 insert(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
179 {
|
Chris@16
|
180 return object.insert(operand);
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 template<class Type>
|
Chris@16
|
184 inline typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
185 insert(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
186 {
|
Chris@16
|
187 return icl::insert(object, make_segment<Type>(operand));
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 //------------------------------------------------------------------------------
|
Chris@16
|
191 //- T& insert(T&, J, c P&) T:{M} P:{p} with hint
|
Chris@16
|
192 //------------------------------------------------------------------------------
|
Chris@16
|
193 template<class Type>
|
Chris@16
|
194 typename enable_if<is_interval_map<Type>, typename Type::iterator>::type
|
Chris@16
|
195 insert(Type& object, typename Type::iterator prior,
|
Chris@16
|
196 const typename Type::segment_type& operand)
|
Chris@16
|
197 {
|
Chris@16
|
198 return object.insert(prior, operand);
|
Chris@16
|
199 }
|
Chris@16
|
200
|
Chris@16
|
201
|
Chris@16
|
202 //==============================================================================
|
Chris@16
|
203 //= Erasure<IntervalMap>
|
Chris@16
|
204 //==============================================================================
|
Chris@16
|
205 //------------------------------------------------------------------------------
|
Chris@16
|
206 //- T& erase(T&, c P&) T:{M} P:{e i} key_types
|
Chris@16
|
207 //------------------------------------------------------------------------------
|
Chris@16
|
208 template<class Type>
|
Chris@16
|
209 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
210 erase(Type& object, const typename Type::interval_type& operand)
|
Chris@16
|
211 {
|
Chris@16
|
212 return object.erase(operand);
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 template<class Type>
|
Chris@16
|
216 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
217 erase(Type& object, const typename Type::domain_type& operand)
|
Chris@16
|
218 {
|
Chris@16
|
219 typedef typename Type::interval_type interval_type;
|
Chris@16
|
220 return icl::erase(object, icl::singleton<interval_type>(operand));
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 //------------------------------------------------------------------------------
|
Chris@16
|
224 //- T& erase(T&, c P&) T:{M} P:{b p} fragment_types
|
Chris@16
|
225 //------------------------------------------------------------------------------
|
Chris@16
|
226 template<class Type>
|
Chris@16
|
227 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
228 erase(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
229 {
|
Chris@16
|
230 return object.erase(operand);
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 template<class Type>
|
Chris@16
|
234 inline typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
235 erase(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
236 {
|
Chris@16
|
237 return icl::erase(object, make_segment<Type>(operand));
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 //==============================================================================
|
Chris@16
|
241 //= Subtraction<IntervalMap>
|
Chris@16
|
242 //==============================================================================
|
Chris@16
|
243 //------------------------------------------------------------------------------
|
Chris@16
|
244 //- T& subtract(T&, c P&) T:{M} P:{b p} fragment_types
|
Chris@16
|
245 //------------------------------------------------------------------------------
|
Chris@16
|
246 template<class Type>
|
Chris@16
|
247 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
248 subtract(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
249 {
|
Chris@16
|
250 return object.subtract(operand);
|
Chris@16
|
251 }
|
Chris@16
|
252
|
Chris@16
|
253 template<class Type>
|
Chris@16
|
254 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
255 subtract(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
256 {
|
Chris@16
|
257 return icl::subtract(object, make_segment<Type>(operand));
|
Chris@16
|
258 }
|
Chris@16
|
259
|
Chris@16
|
260 //------------------------------------------------------------------------------
|
Chris@16
|
261 //- T& subtract(T&, c P&) T:{M} P:{e i} key_types
|
Chris@16
|
262 //------------------------------------------------------------------------------
|
Chris@16
|
263 template<class Type>
|
Chris@16
|
264 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
265 subtract(Type& object, const typename Type::domain_type& operand)
|
Chris@16
|
266 {
|
Chris@16
|
267 return object.erase(operand);
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 template<class Type>
|
Chris@16
|
271 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
272 subtract(Type& object, const typename Type::interval_type& operand)
|
Chris@16
|
273 {
|
Chris@16
|
274 return object.erase(operand);
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 //==============================================================================
|
Chris@16
|
278 //= Selective Update<IntervalMap>
|
Chris@16
|
279 //==============================================================================
|
Chris@16
|
280 //------------------------------------------------------------------------------
|
Chris@16
|
281 //- T& set_at(T&, c P&) T:{M} P:{e i}
|
Chris@16
|
282 //------------------------------------------------------------------------------
|
Chris@16
|
283 template<class Type>
|
Chris@16
|
284 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
285 set_at(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
286 {
|
Chris@16
|
287 icl::erase(object, operand.first);
|
Chris@16
|
288 return icl::insert(object, operand);
|
Chris@16
|
289 }
|
Chris@16
|
290
|
Chris@16
|
291 template<class Type>
|
Chris@16
|
292 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
293 set_at(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
294 {
|
Chris@16
|
295 return icl::set_at(object, make_segment<Type>(operand));
|
Chris@16
|
296 }
|
Chris@16
|
297
|
Chris@16
|
298 //==============================================================================
|
Chris@16
|
299 //= Intersection<IntervalMap>
|
Chris@16
|
300 //==============================================================================
|
Chris@16
|
301 //------------------------------------------------------------------------------
|
Chris@16
|
302 //- T& subtract(T&, c P&) T:{M} P:{b p} fragment_type
|
Chris@16
|
303 //------------------------------------------------------------------------------
|
Chris@16
|
304 template<class Type>
|
Chris@16
|
305 typename enable_if<is_interval_map<Type>, void>::type
|
Chris@16
|
306 add_intersection(Type& section, const Type& object,
|
Chris@16
|
307 const typename Type::element_type& operand)
|
Chris@16
|
308 {
|
Chris@16
|
309 typedef typename Type::segment_type segment_type;
|
Chris@16
|
310 object.add_intersection(section, make_segment<Type>(operand));
|
Chris@16
|
311 }
|
Chris@16
|
312
|
Chris@16
|
313 template<class Type>
|
Chris@16
|
314 typename enable_if<is_interval_map<Type>, void>::type
|
Chris@16
|
315 add_intersection(Type& section, const Type& object,
|
Chris@16
|
316 const typename Type::segment_type& operand)
|
Chris@16
|
317 {
|
Chris@16
|
318 object.add_intersection(section, operand);
|
Chris@16
|
319 }
|
Chris@16
|
320
|
Chris@16
|
321 //------------------------------------------------------------------------------
|
Chris@16
|
322 //- T& subtract(T&, c P&) T:{M} P:{M'} map fragment_type total
|
Chris@16
|
323 //------------------------------------------------------------------------------
|
Chris@16
|
324 template<class Type, class MapT>
|
Chris@16
|
325 typename enable_if
|
Chris@16
|
326 <
|
Chris@16
|
327 mpl::and_< is_total<Type>
|
Chris@16
|
328 , is_concept_compatible<is_interval_map, Type, MapT> >
|
Chris@16
|
329 , void
|
Chris@16
|
330 >::type
|
Chris@16
|
331 add_intersection(Type& section, const Type& object, const MapT& operand)
|
Chris@16
|
332 {
|
Chris@16
|
333 section += object;
|
Chris@16
|
334 section += operand;
|
Chris@16
|
335 }
|
Chris@16
|
336
|
Chris@16
|
337 //------------------------------------------------------------------------------
|
Chris@16
|
338 //- T& subtract(T&, c P&) T:{M} P:{M'} map fragment_type partial
|
Chris@16
|
339 //------------------------------------------------------------------------------
|
Chris@16
|
340 template<class Type, class MapT>
|
Chris@16
|
341 typename enable_if
|
Chris@16
|
342 <
|
Chris@16
|
343 mpl::and_< mpl::not_<is_total<Type> >
|
Chris@16
|
344 , is_concept_compatible<is_interval_map, Type, MapT> >
|
Chris@16
|
345 , void
|
Chris@16
|
346 >::type
|
Chris@16
|
347 add_intersection(Type& section, const Type& object, const MapT& operand)
|
Chris@16
|
348 {
|
Chris@16
|
349 typedef typename Type::segment_type segment_type;
|
Chris@16
|
350 typedef typename Type::interval_type interval_type;
|
Chris@16
|
351 typedef typename MapT::const_iterator const_iterator;
|
Chris@16
|
352
|
Chris@16
|
353 if(operand.empty())
|
Chris@16
|
354 return;
|
Chris@16
|
355 const_iterator common_lwb, common_upb;
|
Chris@16
|
356 if(!Set::common_range(common_lwb, common_upb, operand, object))
|
Chris@16
|
357 return;
|
Chris@16
|
358 const_iterator it_ = common_lwb;
|
Chris@16
|
359 while(it_ != common_upb)
|
Chris@16
|
360 add_intersection(section, object, *it_++);
|
Chris@16
|
361 }
|
Chris@16
|
362
|
Chris@16
|
363 //------------------------------------------------------------------------------
|
Chris@16
|
364 //- T& subtract(T&, c P&) T:{M} P:{e i S} key_type
|
Chris@16
|
365 //------------------------------------------------------------------------------
|
Chris@16
|
366 template<class Type>
|
Chris@16
|
367 typename enable_if<is_interval_map<Type>, void>::type
|
Chris@16
|
368 add_intersection(Type& section, const Type& object,
|
Chris@16
|
369 const typename Type::domain_type& key_value)
|
Chris@16
|
370 {
|
Chris@16
|
371 typedef typename Type::interval_type interval_type;
|
Chris@16
|
372 typedef typename Type::segment_type segment_type;
|
Chris@16
|
373 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
374
|
Chris@16
|
375 const_iterator it_ = icl::find(object, key_value);
|
Chris@16
|
376 if(it_ != object.end())
|
Chris@16
|
377 add(section, segment_type(interval_type(key_value),(*it_).second));
|
Chris@16
|
378 }
|
Chris@16
|
379
|
Chris@16
|
380 template<class Type>
|
Chris@16
|
381 typename enable_if<is_interval_map<Type>, void>::type
|
Chris@16
|
382 add_intersection(Type& section, const Type& object,
|
Chris@16
|
383 const typename Type::interval_type& inter_val)
|
Chris@16
|
384 {
|
Chris@16
|
385 typedef typename Type::interval_type interval_type;
|
Chris@16
|
386 typedef typename Type::value_type value_type;
|
Chris@16
|
387 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
388 typedef typename Type::iterator iterator;
|
Chris@16
|
389
|
Chris@16
|
390 if(icl::is_empty(inter_val))
|
Chris@16
|
391 return;
|
Chris@16
|
392
|
Chris@16
|
393 std::pair<const_iterator, const_iterator> exterior
|
Chris@16
|
394 = object.equal_range(inter_val);
|
Chris@16
|
395 if(exterior.first == exterior.second)
|
Chris@16
|
396 return;
|
Chris@16
|
397
|
Chris@16
|
398 iterator prior_ = section.end();
|
Chris@16
|
399 for(const_iterator it_=exterior.first; it_ != exterior.second; it_++)
|
Chris@16
|
400 {
|
Chris@16
|
401 interval_type common_interval = (*it_).first & inter_val;
|
Chris@16
|
402 if(!icl::is_empty(common_interval))
|
Chris@16
|
403 prior_ = add(section, prior_,
|
Chris@16
|
404 value_type(common_interval, (*it_).second) );
|
Chris@16
|
405 }
|
Chris@16
|
406 }
|
Chris@16
|
407
|
Chris@16
|
408 template<class Type, class KeySetT>
|
Chris@16
|
409 typename enable_if<is_concept_combinable<is_interval_map, is_interval_set, Type, KeySetT>, void>::type
|
Chris@16
|
410 add_intersection(Type& section, const Type& object, const KeySetT& key_set)
|
Chris@16
|
411 {
|
Chris@16
|
412 typedef typename KeySetT::const_iterator const_iterator;
|
Chris@16
|
413
|
Chris@16
|
414 if(icl::is_empty(key_set))
|
Chris@16
|
415 return;
|
Chris@16
|
416
|
Chris@16
|
417 const_iterator common_lwb, common_upb;
|
Chris@16
|
418 if(!Set::common_range(common_lwb, common_upb, key_set, object))
|
Chris@16
|
419 return;
|
Chris@16
|
420
|
Chris@16
|
421 const_iterator it_ = common_lwb;
|
Chris@16
|
422 while(it_ != common_upb)
|
Chris@16
|
423 add_intersection(section, object, *it_++);
|
Chris@16
|
424 }
|
Chris@16
|
425
|
Chris@16
|
426 //------------------------------------------------------------------------------
|
Chris@16
|
427 //- intersects<IntervalMaps> fragment_types
|
Chris@16
|
428 //------------------------------------------------------------------------------
|
Chris@16
|
429 template<class Type, class OperandT>
|
Chris@16
|
430 typename enable_if<mpl::and_< is_interval_map<Type>
|
Chris@16
|
431 , is_total<Type>
|
Chris@16
|
432 , boost::is_same< OperandT
|
Chris@16
|
433 , typename segment_type_of<Type>::type> >,
|
Chris@16
|
434 bool>::type
|
Chris@16
|
435 intersects(const Type&, const OperandT&)
|
Chris@16
|
436 {
|
Chris@16
|
437 return true;
|
Chris@16
|
438 }
|
Chris@16
|
439
|
Chris@16
|
440 template<class Type, class OperandT>
|
Chris@16
|
441 typename enable_if<mpl::and_< is_interval_map<Type>
|
Chris@16
|
442 , mpl::not_<is_total<Type> >
|
Chris@16
|
443 , boost::is_same<OperandT, typename segment_type_of<Type>::type> >,
|
Chris@16
|
444 bool>::type
|
Chris@16
|
445 intersects(const Type& object, const OperandT& operand)
|
Chris@16
|
446 {
|
Chris@16
|
447 Type intersection;
|
Chris@16
|
448 icl::add_intersection(intersection, object, operand);
|
Chris@16
|
449 return !icl::is_empty(intersection);
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 template<class Type, class OperandT>
|
Chris@16
|
453 typename enable_if<mpl::and_< is_interval_map<Type>
|
Chris@16
|
454 , boost::is_same<OperandT, typename element_type_of<Type>::type> >,
|
Chris@16
|
455 bool>::type
|
Chris@16
|
456 intersects(const Type& object, const OperandT& operand)
|
Chris@16
|
457 {
|
Chris@16
|
458 return icl::intersects(object, make_segment<Type>(operand));
|
Chris@16
|
459 }
|
Chris@16
|
460
|
Chris@16
|
461 //==============================================================================
|
Chris@16
|
462 //= Symmetric difference<IntervalMap>
|
Chris@16
|
463 //==============================================================================
|
Chris@16
|
464 //------------------------------------------------------------------------------
|
Chris@16
|
465 //- T& flip(T&, c P&) T:{M} P:{b p} fragment_types
|
Chris@16
|
466 //------------------------------------------------------------------------------
|
Chris@16
|
467 template<class Type>
|
Chris@16
|
468 typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
469 flip(Type& object, const typename Type::segment_type& operand)
|
Chris@16
|
470 {
|
Chris@16
|
471 return object.flip(operand);
|
Chris@16
|
472 }
|
Chris@16
|
473
|
Chris@16
|
474 template<class Type>
|
Chris@16
|
475 inline typename enable_if<is_interval_map<Type>, Type>::type&
|
Chris@16
|
476 flip(Type& object, const typename Type::element_type& operand)
|
Chris@16
|
477 {
|
Chris@16
|
478 return icl::flip(object, make_segment<Type>(operand));
|
Chris@16
|
479 }
|
Chris@16
|
480
|
Chris@16
|
481 //------------------------------------------------------------------------------
|
Chris@16
|
482 //- T& flip(T&, c P&) T:{M} P:{M'} total absorber
|
Chris@16
|
483 //------------------------------------------------------------------------------
|
Chris@16
|
484 template<class Type, class OperandT>
|
Chris@16
|
485 typename enable_if< mpl::and_< is_total<Type>
|
Chris@16
|
486 , absorbs_identities<Type>
|
Chris@16
|
487 , is_concept_compatible<is_interval_map,
|
Chris@16
|
488 Type, OperandT >
|
Chris@16
|
489 >
|
Chris@16
|
490 , Type>::type&
|
Chris@16
|
491 flip(Type& object, const OperandT&)
|
Chris@16
|
492 {
|
Chris@16
|
493 object.clear();
|
Chris@16
|
494 return object;
|
Chris@16
|
495 }
|
Chris@16
|
496
|
Chris@16
|
497 //------------------------------------------------------------------------------
|
Chris@16
|
498 //- T& flip(T&, c P&) T:{M} P:{M'} total enricher
|
Chris@16
|
499 //------------------------------------------------------------------------------
|
Chris@16
|
500 #ifdef BOOST_MSVC
|
Chris@16
|
501 #pragma warning(push)
|
Chris@16
|
502 #pragma warning(disable:4127) // conditional expression is constant
|
Chris@16
|
503 #endif
|
Chris@16
|
504 template<class Type, class OperandT>
|
Chris@16
|
505 typename enable_if< mpl::and_< is_total<Type>
|
Chris@16
|
506 , mpl::not_<absorbs_identities<Type> >
|
Chris@16
|
507 , is_concept_compatible<is_interval_map,
|
Chris@16
|
508 Type, OperandT >
|
Chris@16
|
509 >
|
Chris@16
|
510 , Type>::type&
|
Chris@16
|
511 flip(Type& object, const OperandT& operand)
|
Chris@16
|
512 {
|
Chris@16
|
513 typedef typename Type::codomain_type codomain_type;
|
Chris@16
|
514
|
Chris@16
|
515 object += operand;
|
Chris@16
|
516 ICL_FORALL(typename Type, it_, object)
|
Chris@16
|
517 (*it_).second = identity_element<codomain_type>::value();
|
Chris@16
|
518
|
Chris@16
|
519 if(mpl::not_<is_interval_splitter<Type> >::value)
|
Chris@16
|
520 icl::join(object);
|
Chris@16
|
521
|
Chris@16
|
522 return object;
|
Chris@16
|
523 }
|
Chris@16
|
524 #ifdef BOOST_MSVC
|
Chris@16
|
525 #pragma warning(pop)
|
Chris@16
|
526 #endif
|
Chris@16
|
527
|
Chris@16
|
528
|
Chris@16
|
529 //------------------------------------------------------------------------------
|
Chris@16
|
530 //- T& flip(T&, c P&) T:{M} P:{M'} partial
|
Chris@16
|
531 //------------------------------------------------------------------------------
|
Chris@16
|
532 template<class Type, class OperandT>
|
Chris@16
|
533 typename enable_if< mpl::and_< mpl::not_<is_total<Type> >
|
Chris@16
|
534 , is_concept_compatible<is_interval_map,
|
Chris@16
|
535 Type, OperandT >
|
Chris@16
|
536 >
|
Chris@16
|
537 , Type>::type&
|
Chris@16
|
538 flip(Type& object, const OperandT& operand)
|
Chris@16
|
539 {
|
Chris@16
|
540 typedef typename OperandT::const_iterator const_iterator;
|
Chris@16
|
541 typedef typename Type::codomain_type codomain_type;
|
Chris@16
|
542
|
Chris@16
|
543 const_iterator common_lwb, common_upb;
|
Chris@16
|
544
|
Chris@16
|
545 if(!Set::common_range(common_lwb, common_upb, operand, object))
|
Chris@16
|
546 return object += operand;
|
Chris@16
|
547
|
Chris@16
|
548 const_iterator it_ = operand.begin();
|
Chris@16
|
549
|
Chris@16
|
550 // All elements of operand left of the common range are added
|
Chris@16
|
551 while(it_ != common_lwb)
|
Chris@16
|
552 icl::add(object, *it_++);
|
Chris@16
|
553 // All elements of operand in the common range are symmetrically subtracted
|
Chris@16
|
554 while(it_ != common_upb)
|
Chris@16
|
555 icl::flip(object, *it_++);
|
Chris@16
|
556 // All elements of operand right of the common range are added
|
Chris@16
|
557 while(it_ != operand.end())
|
Chris@16
|
558 icl::add(object, *it_++);
|
Chris@16
|
559
|
Chris@16
|
560 return object;
|
Chris@16
|
561 }
|
Chris@16
|
562
|
Chris@16
|
563 //==============================================================================
|
Chris@16
|
564 //= Set selection
|
Chris@16
|
565 //==============================================================================
|
Chris@16
|
566 template<class Type, class SetT>
|
Chris@16
|
567 typename enable_if<is_concept_combinable<is_interval_set, is_interval_map,
|
Chris@16
|
568 SetT, Type>, SetT>::type&
|
Chris@16
|
569 domain(SetT& result, const Type& object)
|
Chris@16
|
570 {
|
Chris@16
|
571 typedef typename SetT::iterator set_iterator;
|
Chris@16
|
572 result.clear();
|
Chris@16
|
573 set_iterator prior_ = result.end();
|
Chris@16
|
574 ICL_const_FORALL(typename Type, it_, object)
|
Chris@16
|
575 prior_ = icl::insert(result, prior_, (*it_).first);
|
Chris@16
|
576
|
Chris@16
|
577 return result;
|
Chris@16
|
578 }
|
Chris@16
|
579
|
Chris@16
|
580 template<class Type, class SetT>
|
Chris@16
|
581 typename enable_if<is_concept_combinable<is_interval_set, is_interval_map,
|
Chris@16
|
582 SetT, Type>, SetT>::type&
|
Chris@16
|
583 between(SetT& in_between, const Type& object)
|
Chris@16
|
584 {
|
Chris@16
|
585 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
586 typedef typename SetT::iterator set_iterator;
|
Chris@16
|
587 in_between.clear();
|
Chris@16
|
588 const_iterator it_ = object.begin(), pred_;
|
Chris@16
|
589 set_iterator prior_ = in_between.end();
|
Chris@16
|
590
|
Chris@16
|
591 if(it_ != object.end())
|
Chris@16
|
592 pred_ = it_++;
|
Chris@16
|
593
|
Chris@16
|
594 while(it_ != object.end())
|
Chris@16
|
595 prior_ = icl::insert(in_between, prior_,
|
Chris@16
|
596 between((*pred_++).first, (*it_++).first));
|
Chris@16
|
597
|
Chris@16
|
598 return in_between;
|
Chris@16
|
599 }
|
Chris@16
|
600
|
Chris@16
|
601 //==============================================================================
|
Chris@16
|
602 //= Manipulation by predicates
|
Chris@16
|
603 //==============================================================================
|
Chris@16
|
604 template<class MapT, class Predicate>
|
Chris@16
|
605 typename enable_if<is_interval_map<MapT>, MapT>::type&
|
Chris@16
|
606 erase_if(const Predicate& pred, MapT& object)
|
Chris@16
|
607 {
|
Chris@16
|
608 typename MapT::iterator it_ = object.begin();
|
Chris@16
|
609 while(it_ != object.end())
|
Chris@16
|
610 if(pred(*it_))
|
Chris@16
|
611 object.erase(it_++);
|
Chris@16
|
612 else ++it_;
|
Chris@16
|
613 return object;
|
Chris@16
|
614 }
|
Chris@16
|
615
|
Chris@16
|
616 template<class MapT, class Predicate>
|
Chris@16
|
617 inline typename enable_if<is_interval_map<MapT>, MapT>::type&
|
Chris@16
|
618 add_if(const Predicate& pred, MapT& object, const MapT& src)
|
Chris@16
|
619 {
|
Chris@16
|
620 typename MapT::const_iterator it_ = src.begin();
|
Chris@16
|
621 while(it_ != src.end())
|
Chris@16
|
622 if(pred(*it_))
|
Chris@16
|
623 icl::add(object, *it_++);
|
Chris@16
|
624
|
Chris@16
|
625 return object;
|
Chris@16
|
626 }
|
Chris@16
|
627
|
Chris@16
|
628 template<class MapT, class Predicate>
|
Chris@16
|
629 inline typename enable_if<is_interval_map<MapT>, MapT>::type&
|
Chris@16
|
630 assign_if(const Predicate& pred, MapT& object, const MapT& src)
|
Chris@16
|
631 {
|
Chris@16
|
632 icl::clear(object);
|
Chris@16
|
633 return add_if(object, src, pred);
|
Chris@16
|
634 }
|
Chris@16
|
635
|
Chris@16
|
636
|
Chris@16
|
637 //==============================================================================
|
Chris@16
|
638 //= Morphisms
|
Chris@16
|
639 //==============================================================================
|
Chris@16
|
640 template<class Type>
|
Chris@16
|
641 typename enable_if<mpl::and_< is_interval_map<Type>
|
Chris@16
|
642 , absorbs_identities<Type> >, Type>::type&
|
Chris@16
|
643 absorb_identities(Type& object)
|
Chris@16
|
644 {
|
Chris@16
|
645 return object;
|
Chris@16
|
646 }
|
Chris@16
|
647
|
Chris@16
|
648 template<class Type>
|
Chris@16
|
649 typename enable_if<mpl::and_< is_interval_map<Type>
|
Chris@16
|
650 , mpl::not_<absorbs_identities<Type> > >, Type>::type&
|
Chris@16
|
651 absorb_identities(Type& object)
|
Chris@16
|
652 {
|
Chris@16
|
653 typedef typename Type::segment_type segment_type;
|
Chris@16
|
654 return icl::erase_if(content_is_identity_element<segment_type>(), object);
|
Chris@16
|
655 }
|
Chris@16
|
656
|
Chris@16
|
657 //==============================================================================
|
Chris@16
|
658 //= Streaming
|
Chris@16
|
659 //==============================================================================
|
Chris@16
|
660 template<class CharType, class CharTraits, class Type>
|
Chris@16
|
661 typename enable_if<is_interval_map<Type>,
|
Chris@16
|
662 std::basic_ostream<CharType, CharTraits> >::type&
|
Chris@16
|
663 operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object)
|
Chris@16
|
664 {
|
Chris@16
|
665 stream << "{";
|
Chris@16
|
666 ICL_const_FORALL(typename Type, it_, object)
|
Chris@16
|
667 stream << "(" << (*it_).first << "->" << (*it_).second << ")";
|
Chris@16
|
668
|
Chris@16
|
669 return stream << "}";
|
Chris@16
|
670 }
|
Chris@16
|
671
|
Chris@16
|
672
|
Chris@16
|
673 }} // namespace boost icl
|
Chris@16
|
674
|
Chris@16
|
675 #endif
|
Chris@16
|
676
|
Chris@16
|
677
|