]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*-----------------------------------------------------------------------------+ |
2 | Copyright (c) 2010-2010: Joachim Faulhaber | |
3 | +------------------------------------------------------------------------------+ | |
4 | Distributed under the Boost Software License, Version 1.0. | |
5 | (See accompanying file LICENCE.txt or copy at | |
6 | http://www.boost.org/LICENSE_1_0.txt) | |
7 | +-----------------------------------------------------------------------------*/ | |
8 | #ifndef BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920 | |
9 | #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920 | |
10 | ||
11 | #include <boost/icl/type_traits/domain_type_of.hpp> | |
12 | #include <boost/icl/type_traits/interval_type_of.hpp> | |
13 | #include <boost/icl/type_traits/is_combinable.hpp> | |
14 | #include <boost/icl/detail/set_algo.hpp> | |
15 | #include <boost/icl/detail/map_algo.hpp> | |
16 | #include <boost/icl/detail/interval_set_algo.hpp> | |
17 | #include <boost/icl/detail/interval_map_algo.hpp> | |
18 | #include <boost/icl/concept/interval.hpp> | |
19 | ||
20 | namespace boost{ namespace icl | |
21 | { | |
22 | ||
23 | //============================================================================== | |
24 | //= Containedness<IntervalSet|IntervalMap> | |
25 | //============================================================================== | |
26 | //------------------------------------------------------------------------------ | |
27 | //- bool within(c T&, c P&) T={Set,Map} P={e i b p S M} | |
28 | //------------------------------------------------------------------------------ | |
29 | template<class SubT, class SuperT> | |
30 | typename enable_if<is_interval_container<SuperT>, bool>::type | |
31 | within(const SubT& sub, const SuperT& super) | |
32 | { | |
33 | return icl::contains(super, sub); | |
34 | } | |
35 | ||
36 | //============================================================================== | |
37 | //= Equivalences and Orderings<IntervalSet|IntervalMap> | |
38 | //============================================================================== | |
39 | template<class Type> | |
40 | inline typename enable_if<is_interval_container<Type>, bool>::type | |
41 | operator == (const Type& left, const Type& right) | |
42 | { | |
43 | return Set::lexicographical_equal(left, right); | |
44 | } | |
45 | ||
46 | template<class Type> | |
47 | inline typename enable_if<is_interval_container<Type>, bool>::type | |
48 | operator < (const Type& left, const Type& right) | |
49 | { | |
50 | typedef typename Type::segment_compare segment_compare; | |
51 | return std::lexicographical_compare( | |
52 | left.begin(), left.end(), right.begin(), right.end(), | |
53 | segment_compare() | |
54 | ); | |
55 | } | |
56 | ||
57 | /** Returns true, if \c left and \c right contain the same elements. | |
58 | Complexity: linear. */ | |
59 | template<class LeftT, class RightT> | |
60 | typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type | |
61 | is_element_equal(const LeftT& left, const RightT& right) | |
62 | { | |
63 | return Interval_Set::is_element_equal(left, right); | |
64 | } | |
65 | ||
66 | /** Returns true, if \c left is lexicographically less than \c right. | |
67 | Intervals are interpreted as sequence of elements. | |
68 | Complexity: linear. */ | |
69 | template<class LeftT, class RightT> | |
70 | typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type | |
71 | is_element_less(const LeftT& left, const RightT& right) | |
72 | { | |
73 | return Interval_Set::is_element_less(left, right); | |
74 | } | |
75 | ||
76 | /** Returns true, if \c left is lexicographically greater than \c right. | |
77 | Intervals are interpreted as sequence of elements. | |
78 | Complexity: linear. */ | |
79 | template<class LeftT, class RightT> | |
80 | typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type | |
81 | is_element_greater(const LeftT& left, const RightT& right) | |
82 | { | |
83 | return Interval_Set::is_element_greater(left, right); | |
84 | } | |
85 | ||
86 | //------------------------------------------------------------------------------ | |
87 | template<class LeftT, class RightT> | |
88 | typename enable_if<is_inter_combinable<LeftT, RightT>, int>::type | |
89 | inclusion_compare(const LeftT& left, const RightT& right) | |
90 | { | |
91 | return Interval_Set::subset_compare(left, right, | |
92 | left.begin(), left.end(), | |
93 | right.begin(), right.end()); | |
94 | } | |
95 | ||
96 | //------------------------------------------------------------------------------ | |
97 | template<class LeftT, class RightT> | |
98 | typename enable_if< is_concept_compatible<is_interval_map, LeftT, RightT>, | |
99 | bool >::type | |
100 | is_distinct_equal(const LeftT& left, const RightT& right) | |
101 | { | |
102 | return Map::lexicographical_distinct_equal(left, right); | |
103 | } | |
104 | ||
105 | //============================================================================== | |
106 | //= Size<IntervalSet|IntervalMap> | |
107 | //============================================================================== | |
108 | template<class Type> | |
109 | typename enable_if<is_interval_container<Type>, std::size_t>::type | |
110 | iterative_size(const Type& object) | |
111 | { | |
112 | return object.iterative_size(); | |
113 | } | |
114 | ||
115 | template<class Type> | |
116 | typename enable_if | |
117 | < mpl::and_< is_interval_container<Type> | |
118 | , is_discrete<typename Type::domain_type> > | |
119 | , typename Type::size_type | |
120 | >::type | |
121 | cardinality(const Type& object) | |
122 | { | |
123 | typedef typename Type::size_type size_type; | |
124 | //CL typedef typename Type::interval_type interval_type; | |
125 | ||
126 | size_type size = identity_element<size_type>::value(); | |
127 | ICL_const_FORALL(typename Type, it, object) | |
128 | size += icl::cardinality(key_value<Type>(it)); | |
129 | return size; | |
130 | ||
131 | } | |
132 | ||
133 | template<class Type> | |
134 | typename enable_if | |
135 | < mpl::and_< is_interval_container<Type> | |
136 | , mpl::not_<is_discrete<typename Type::domain_type> > > | |
137 | , typename Type::size_type | |
138 | >::type | |
139 | cardinality(const Type& object) | |
140 | { | |
141 | typedef typename Type::size_type size_type; | |
142 | //CL typedef typename Type::interval_type interval_type; | |
143 | ||
144 | size_type size = identity_element<size_type>::value(); | |
145 | size_type interval_size; | |
146 | ICL_const_FORALL(typename Type, it, object) | |
147 | { | |
148 | interval_size = icl::cardinality(key_value<Type>(it)); | |
149 | if(interval_size == icl::infinity<size_type>::value()) | |
150 | return interval_size; | |
151 | else | |
152 | size += interval_size; | |
153 | } | |
154 | return size; | |
155 | } | |
156 | ||
157 | template<class Type> | |
158 | inline typename enable_if<is_interval_container<Type>, typename Type::size_type>::type | |
159 | size(const Type& object) | |
160 | { | |
161 | return icl::cardinality(object); | |
162 | } | |
163 | ||
164 | template<class Type> | |
165 | typename enable_if<is_interval_container<Type>, typename Type::difference_type>::type | |
166 | length(const Type& object) | |
167 | { | |
168 | typedef typename Type::difference_type difference_type; | |
169 | typedef typename Type::const_iterator const_iterator; | |
170 | difference_type length = identity_element<difference_type>::value(); | |
171 | const_iterator it_ = object.begin(); | |
172 | ||
173 | while(it_ != object.end()) | |
174 | length += icl::length(key_value<Type>(it_++)); | |
175 | return length; | |
176 | } | |
177 | ||
178 | template<class Type> | |
179 | typename enable_if<is_interval_container<Type>, std::size_t>::type | |
180 | interval_count(const Type& object) | |
181 | { | |
182 | return icl::iterative_size(object); | |
183 | } | |
184 | ||
185 | ||
186 | template<class Type> | |
187 | typename enable_if< is_interval_container<Type> | |
188 | , typename Type::difference_type >::type | |
189 | distance(const Type& object) | |
190 | { | |
191 | typedef typename Type::difference_type DiffT; | |
192 | typedef typename Type::const_iterator const_iterator; | |
193 | const_iterator it_ = object.begin(), pred_; | |
194 | DiffT dist = identity_element<DiffT>::value(); | |
195 | ||
196 | if(it_ != object.end()) | |
197 | pred_ = it_++; | |
198 | ||
199 | while(it_ != object.end()) | |
200 | dist += icl::distance(key_value<Type>(pred_++), key_value<Type>(it_++)); | |
201 | ||
202 | return dist; | |
203 | } | |
204 | ||
205 | //============================================================================== | |
206 | //= Range<IntervalSet|IntervalMap> | |
207 | //============================================================================== | |
208 | template<class Type> | |
209 | typename enable_if<is_interval_container<Type>, | |
210 | typename Type::interval_type>::type | |
211 | hull(const Type& object) | |
212 | { | |
213 | return | |
214 | icl::is_empty(object) | |
215 | ? identity_element<typename Type::interval_type>::value() | |
216 | : icl::hull( key_value<Type>(object.begin()), | |
217 | key_value<Type>(object.rbegin()) ); | |
218 | } | |
219 | ||
220 | template<class Type> | |
221 | typename enable_if<is_interval_container<Type>, | |
222 | typename domain_type_of<Type>::type>::type | |
223 | lower(const Type& object) | |
224 | { | |
225 | typedef typename domain_type_of<Type>::type DomainT; | |
226 | return | |
227 | icl::is_empty(object) | |
228 | ? unit_element<DomainT>::value() | |
229 | : icl::lower( key_value<Type>(object.begin()) ); | |
230 | } | |
231 | ||
232 | template<class Type> | |
233 | typename enable_if<is_interval_container<Type>, | |
234 | typename domain_type_of<Type>::type>::type | |
235 | upper(const Type& object) | |
236 | { | |
237 | typedef typename domain_type_of<Type>::type DomainT; | |
238 | return | |
239 | icl::is_empty(object) | |
240 | ? identity_element<DomainT>::value() | |
241 | : icl::upper( key_value<Type>(object.rbegin()) ); | |
242 | } | |
243 | ||
244 | //------------------------------------------------------------------------------ | |
245 | template<class Type> | |
246 | typename enable_if | |
247 | < mpl::and_< is_interval_container<Type> | |
248 | , is_discrete<typename domain_type_of<Type>::type> > | |
249 | , typename domain_type_of<Type>::type>::type | |
250 | first(const Type& object) | |
251 | { | |
252 | typedef typename domain_type_of<Type>::type DomainT; | |
253 | return | |
254 | icl::is_empty(object) | |
255 | ? unit_element<DomainT>::value() | |
256 | : icl::first( key_value<Type>(object.begin()) ); | |
257 | } | |
258 | ||
259 | template<class Type> | |
260 | typename enable_if | |
261 | < mpl::and_< is_interval_container<Type> | |
262 | , is_discrete<typename domain_type_of<Type>::type> > | |
263 | , typename domain_type_of<Type>::type>::type | |
264 | last(const Type& object) | |
265 | { | |
266 | typedef typename domain_type_of<Type>::type DomainT; | |
267 | return | |
268 | icl::is_empty(object) | |
269 | ? identity_element<DomainT>::value() | |
270 | : icl::last( key_value<Type>(object.rbegin()) ); | |
271 | } | |
272 | ||
273 | ||
274 | //============================================================================== | |
275 | //= Addition<IntervalSet|IntervalMap> | |
276 | //============================================================================== | |
277 | //------------------------------------------------------------------------------ | |
278 | //- T& op +=(T&, c P&) T:{S}|{M} P:{e i}|{b p} | |
279 | //------------------------------------------------------------------------------ | |
280 | /* \par \b Requires: \c OperandT is an addable derivative type of \c Type. | |
281 | \b Effects: \c operand is added to \c object. | |
282 | \par \b Returns: A reference to \c object. | |
283 | \b Complexity: | |
284 | \code | |
285 | \ OperandT: | |
286 | \ element segment | |
287 | Type: | |
288 | interval container O(log n) O(n) | |
289 | ||
290 | interval_set amortized | |
291 | spearate_interval_set O(log n) | |
292 | ||
293 | n = object.interval_count() | |
294 | \endcode | |
295 | ||
296 | For the addition of \b elements or \b segments | |
297 | complexity is \b logarithmic or \b linear respectively. | |
298 | For \c interval_sets and \c separate_interval_sets addition of segments | |
299 | is \b amortized \b logarithmic. | |
300 | */ | |
301 | template<class Type, class OperandT> | |
302 | typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type& | |
303 | operator += (Type& object, const OperandT& operand) | |
304 | { | |
305 | return icl::add(object, operand); | |
306 | } | |
307 | ||
308 | ||
309 | //------------------------------------------------------------------------------ | |
310 | //- T& op +=(T&, c P&) T:{S}|{M} P:{S'}|{M'} | |
311 | //------------------------------------------------------------------------------ | |
312 | /** \par \b Requires: \c OperandT is an interval container addable to \c Type. | |
313 | \b Effects: \c operand is added to \c object. | |
314 | \par \b Returns: A reference to \c object. | |
315 | \b Complexity: loglinear */ | |
316 | template<class Type, class OperandT> | |
317 | typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type& | |
318 | operator += (Type& object, const OperandT& operand) | |
319 | { | |
320 | typename Type::iterator prior_ = object.end(); | |
321 | ICL_const_FORALL(typename OperandT, elem_, operand) | |
322 | prior_ = icl::add(object, prior_, *elem_); | |
323 | ||
324 | return object; | |
325 | } | |
326 | ||
327 | ||
328 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
329 | //------------------------------------------------------------------------------ | |
330 | //- T op + (T, c P&) T:{S}|{M} P:{e i S}|{b p M} | |
331 | //------------------------------------------------------------------------------ | |
332 | /** \par \b Requires: \c object and \c operand are addable. | |
333 | \b Effects: \c operand is added to \c object. | |
334 | \par \b Efficieny: There is one additional copy of | |
335 | \c Type \c object compared to inplace \c operator \c += */ | |
336 | template<class Type, class OperandT> | |
337 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
338 | operator + (Type object, const OperandT& operand) | |
339 | { | |
340 | return object += operand; | |
341 | } | |
342 | ||
343 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
344 | ||
345 | template<class Type, class OperandT> | |
346 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
347 | operator + (const Type& object, const OperandT& operand) | |
348 | { | |
349 | Type temp = object; | |
350 | return boost::move(temp += operand); | |
351 | } | |
352 | ||
353 | template<class Type, class OperandT> | |
354 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
355 | operator + (Type&& object, const OperandT& operand) | |
356 | { | |
357 | return boost::move(object += operand); | |
358 | } | |
359 | ||
360 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
361 | ||
362 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
363 | //------------------------------------------------------------------------------ | |
364 | //- T op + (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'} | |
365 | //------------------------------------------------------------------------------ | |
366 | /** \par \b Requires: \c object and \c operand are addable. | |
367 | \b Effects: \c operand is added to \c object. | |
368 | \par \b Efficieny: There is one additional copy of | |
369 | \c Type \c object compared to inplace \c operator \c += */ | |
370 | template<class Type, class OperandT> | |
371 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
372 | operator + (const OperandT& operand, Type object) | |
373 | { | |
374 | return object += operand; | |
375 | } | |
376 | ||
377 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
378 | ||
379 | template<class Type, class OperandT> | |
380 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
381 | operator + (const OperandT& operand, const Type& object) | |
382 | { | |
383 | Type temp = object; | |
384 | return boost::move(temp += operand); | |
385 | } | |
386 | ||
387 | template<class Type, class OperandT> | |
388 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
389 | operator + (const OperandT& operand, Type&& object) | |
390 | { | |
391 | return boost::move(object += operand); | |
392 | } | |
393 | ||
394 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
395 | ||
396 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
397 | //------------------------------------------------------------------------------ | |
398 | //- T op + (T, c P&) T:{S}|{M} P:{S}|{M} | |
399 | //------------------------------------------------------------------------------ | |
400 | /** \par \b Requires: \c object and \c operand are addable. | |
401 | \b Effects: \c operand is added to \c object. | |
402 | \par \b Efficieny: There is one additional copy of | |
403 | \c Type \c object compared to inplace \c operator \c += */ | |
404 | template<class Type> | |
405 | typename enable_if<is_interval_container<Type>, Type>::type | |
406 | operator + (Type object, const Type& operand) | |
407 | { | |
408 | return object += operand; | |
409 | } | |
410 | ||
411 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
412 | ||
413 | template<class Type> | |
414 | typename enable_if<is_interval_container<Type>, Type>::type | |
415 | operator + (const Type& object, const Type& operand) | |
416 | { | |
417 | Type temp = object; | |
418 | return boost::move(temp += operand); | |
419 | } | |
420 | ||
421 | template<class Type> | |
422 | typename enable_if<is_interval_container<Type>, Type>::type | |
423 | operator + (Type&& object, const Type& operand) | |
424 | { | |
425 | return boost::move(object += operand); | |
426 | } | |
427 | ||
428 | template<class Type> | |
429 | typename enable_if<is_interval_container<Type>, Type>::type | |
430 | operator + (const Type& operand, Type&& object) | |
431 | { | |
432 | return boost::move(object += operand); | |
433 | } | |
434 | ||
435 | template<class Type> | |
436 | typename enable_if<is_interval_container<Type>, Type>::type | |
437 | operator + (Type&& object, Type&& operand) | |
438 | { | |
439 | return boost::move(object += operand); | |
440 | } | |
441 | ||
442 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
443 | ||
444 | //------------------------------------------------------------------------------ | |
445 | //- Addition |=, | | |
446 | //------------------------------------------------------------------------------ | |
447 | ||
448 | //------------------------------------------------------------------------------ | |
449 | //- T& op |=(c P&) T:{S}|{M} P:{e i}|{b p} | |
450 | //------------------------------------------------------------------------------ | |
451 | /** \par \b Requires: Types \c Type and \c OperandT are addable. | |
452 | \par \b Effects: \c operand is added to \c object. | |
453 | \par \b Returns: A reference to \c object. | |
454 | \b Complexity: | |
455 | \code | |
456 | \ OperandT: interval | |
457 | \ element segment container | |
458 | Type: | |
459 | interval container O(log n) O(n) O(m log(n+m)) | |
460 | ||
461 | interval_set amortized | |
462 | spearate_interval_set O(log n) | |
463 | ||
464 | n = object.interval_count() | |
465 | m = operand.interval_count() | |
466 | \endcode | |
467 | ||
468 | For the addition of \b elements, \b segments and \b interval \b containers | |
469 | complexity is \b logarithmic, \b linear and \b loglinear respectively. | |
470 | For \c interval_sets and \c separate_interval_sets addition of segments | |
471 | is \b amortized \b logarithmic. | |
472 | */ | |
473 | template<class Type, class OperandT> | |
474 | typename enable_if<is_right_intra_combinable<Type, OperandT>, Type>::type& | |
475 | operator |= (Type& object, const OperandT& operand) | |
476 | { | |
477 | return object += operand; | |
478 | } | |
479 | ||
480 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
481 | //------------------------------------------------------------------------------ | |
482 | //- T op | (T, c P&) T:{S}|{M} P:{e i S}|{b p M} | |
483 | //------------------------------------------------------------------------------ | |
484 | /** \par \b Requires: \c object and \c operand are addable. | |
485 | \b Effects: \c operand is added to \c object. | |
486 | \par \b Efficieny: There is one additional copy of | |
487 | \c Type \c object compared to inplace \c operator \c |= */ | |
488 | template<class Type, class OperandT> | |
489 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
490 | operator | (Type object, const OperandT& operand) | |
491 | { | |
492 | return object += operand; | |
493 | } | |
494 | ||
495 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
496 | ||
497 | template<class Type, class OperandT> | |
498 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
499 | operator | (const Type& object, const OperandT& operand) | |
500 | { | |
501 | Type temp = object; | |
502 | return boost::move(temp += operand); | |
503 | } | |
504 | ||
505 | template<class Type, class OperandT> | |
506 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
507 | operator | (Type&& object, const OperandT& operand) | |
508 | { | |
509 | return boost::move(object += operand); | |
510 | } | |
511 | ||
512 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
513 | ||
514 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
515 | //------------------------------------------------------------------------------ | |
516 | //- T op | (T, c P&) T:{S}|{M} P:{S}|{M} | |
517 | //------------------------------------------------------------------------------ | |
518 | /** \par \b Requires: \c object and \c operand are addable. | |
519 | \b Effects: \c operand is added to \c object. | |
520 | \par \b Efficieny: There is one additional copy of | |
521 | \c Type \c object compared to inplace \c operator \c |= */ | |
522 | template<class Type, class OperandT> | |
523 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
524 | operator | (const OperandT& operand, Type object) | |
525 | { | |
526 | return object += operand; | |
527 | } | |
528 | ||
529 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
530 | ||
531 | template<class Type, class OperandT> | |
532 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
533 | operator | (const OperandT& operand, const Type& object) | |
534 | { | |
535 | Type temp = object; | |
536 | return boost::move(temp += operand); | |
537 | } | |
538 | ||
539 | template<class Type, class OperandT> | |
540 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
541 | operator | (const OperandT& operand, Type&& object) | |
542 | { | |
543 | return boost::move(object += operand); | |
544 | } | |
545 | ||
546 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
547 | ||
548 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
549 | //------------------------------------------------------------------------------ | |
550 | //- T op | (T, c P&) T:{S}|{M} P:{S}|{M} | |
551 | //------------------------------------------------------------------------------ | |
552 | /** \par \b Requires: \c object and \c operand are addable. | |
553 | \b Effects: \c operand is added to \c object. | |
554 | \par \b Efficieny: There is one additional copy of | |
555 | \c Type \c object compared to inplace \c operator \c |= */ | |
556 | template<class Type> | |
557 | typename enable_if<is_interval_container<Type>, Type>::type | |
558 | operator | (Type object, const Type& operand) | |
559 | { | |
560 | return object += operand; | |
561 | } | |
562 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
563 | ||
564 | template<class Type> | |
565 | typename enable_if<is_interval_container<Type>, Type>::type | |
566 | operator | (const Type& object, const Type& operand) | |
567 | { | |
568 | Type temp = object; | |
569 | return boost::move(temp += operand); | |
570 | } | |
571 | ||
572 | template<class Type> | |
573 | typename enable_if<is_interval_container<Type>, Type>::type | |
574 | operator | (Type&& object, const Type& operand) | |
575 | { | |
576 | return boost::move(object += operand); | |
577 | } | |
578 | ||
579 | template<class Type> | |
580 | typename enable_if<is_interval_container<Type>, Type>::type | |
581 | operator | (const Type& operand, Type&& object) | |
582 | { | |
583 | return boost::move(object += operand); | |
584 | } | |
585 | ||
586 | template<class Type> | |
587 | typename enable_if<is_interval_container<Type>, Type>::type | |
588 | operator | (Type&& object, Type&& operand) | |
589 | { | |
590 | return boost::move(object += operand); | |
591 | } | |
592 | ||
593 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
594 | ||
595 | ||
596 | //============================================================================== | |
597 | //= Insertion<IntervalSet|IntervalSet> | |
598 | //============================================================================== | |
599 | //------------------------------------------------------------------------------ | |
600 | //- T& insert(T&, c P&) T:{S}|{M} P:{S'}|{M'} | |
601 | //------------------------------------------------------------------------------ | |
602 | template<class Type, class OperandT> | |
603 | typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type& | |
604 | insert(Type& object, const OperandT& operand) | |
605 | { | |
606 | typename Type::iterator prior_ = object.end(); | |
607 | ICL_const_FORALL(typename OperandT, elem_, operand) | |
608 | insert(object, prior_, *elem_); | |
609 | ||
610 | return object; | |
611 | } | |
612 | ||
613 | //============================================================================== | |
614 | //= Erasure<IntervalSet|IntervalSet> | |
615 | //============================================================================== | |
616 | //------------------------------------------------------------------------------ | |
617 | //- T& erase(T&, c P&) T:{S}|{M} P:{S'}|{S' M'} | |
618 | //------------------------------------------------------------------------------ | |
619 | template<class Type, class OperandT> | |
620 | typename enable_if<combines_right_to_interval_container<Type, OperandT>, | |
621 | Type>::type& | |
622 | erase(Type& object, const OperandT& operand) | |
623 | { | |
624 | typedef typename OperandT::const_iterator const_iterator; | |
625 | ||
626 | if(icl::is_empty(operand)) | |
627 | return object; | |
628 | ||
629 | const_iterator common_lwb, common_upb; | |
630 | if(!Set::common_range(common_lwb, common_upb, operand, object)) | |
631 | return object; | |
632 | ||
633 | const_iterator it_ = common_lwb; | |
634 | while(it_ != common_upb) | |
635 | icl::erase(object, *it_++); | |
636 | ||
637 | return object; | |
638 | } | |
639 | ||
640 | //============================================================================== | |
641 | //= Subtraction<IntervalSet|IntervalSet> | |
642 | //============================================================================== | |
643 | //------------------------------------------------------------------------------ | |
644 | //- T& op -= (c P&) T:{M} P:{M'} | |
645 | //------------------------------------------------------------------------------ | |
646 | /** \par \b Requires: Types \c Type and \c OperandT are subtractable. | |
647 | \par \b Effects: \c operand is subtracted from \c object. | |
648 | \par \b Returns: A reference to \c object. | |
649 | \b Complexity: | |
650 | \code | |
651 | \ OperandT: interval | |
652 | \ element segment container | |
653 | Type: | |
654 | interval container O(log n) O(n) O(m log(n+m)) | |
655 | ||
656 | amortized | |
657 | interval_sets O(log n) | |
658 | ||
659 | n = object.interval_count() | |
660 | m = operand.interval_count() | |
661 | \endcode | |
662 | ||
663 | For the subtraction of \em elements, \b segments and \b interval \b containers | |
664 | complexity is \b logarithmic, \b linear and \b loglinear respectively. | |
665 | For interval sets subtraction of segments | |
666 | is \b amortized \b logarithmic. | |
667 | */ | |
668 | template<class Type, class OperandT> | |
669 | typename enable_if<is_concept_compatible<is_interval_map, Type, OperandT>, | |
670 | Type>::type& | |
671 | operator -=(Type& object, const OperandT& operand) | |
672 | { | |
673 | ICL_const_FORALL(typename OperandT, elem_, operand) | |
674 | icl::subtract(object, *elem_); | |
675 | ||
676 | return object; | |
677 | } | |
678 | ||
679 | //------------------------------------------------------------------------------ | |
680 | //- T& op -= (c P&) T:{S}|{M} P:{e i}|{b p} | |
681 | //------------------------------------------------------------------------------ | |
682 | template<class Type, class OperandT> | |
683 | typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type& | |
684 | operator -= (Type& object, const OperandT& operand) | |
685 | { | |
686 | return icl::subtract(object, operand); | |
687 | } | |
688 | ||
689 | //------------------------------------------------------------------------------ | |
690 | //- T& op -= (c P&) T:{M} P:{e i} | |
691 | //------------------------------------------------------------------------------ | |
692 | template<class Type, class OperandT> | |
693 | typename enable_if<is_cross_derivative<Type, OperandT>, Type>::type& | |
694 | operator -= (Type& object, const OperandT& operand) | |
695 | { | |
696 | return icl::erase(object, operand); | |
697 | } | |
698 | ||
699 | //------------------------------------------------------------------------------ | |
700 | //- T& op -= (c P&) T:{S M} P:{S'} | |
701 | //------------------------------------------------------------------------------ | |
702 | template<class Type, class IntervalSetT> | |
703 | typename enable_if<combines_right_to_interval_set<Type, IntervalSetT>, | |
704 | Type>::type& | |
705 | operator -= (Type& object, const IntervalSetT& operand) | |
706 | { | |
707 | return erase(object, operand); | |
708 | } | |
709 | ||
710 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
711 | //------------------------------------------------------------------------------ | |
712 | //- T op - (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} | |
713 | //------------------------------------------------------------------------------ | |
714 | template<class Type, class OperandT> | |
715 | typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type | |
716 | operator - (Type object, const OperandT& operand) | |
717 | { | |
718 | return object -= operand; | |
719 | } | |
720 | ||
721 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
722 | ||
723 | template<class Type, class OperandT> | |
724 | typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type | |
725 | operator - (const Type& object, const OperandT& operand) | |
726 | { | |
727 | Type temp = object; | |
728 | return boost::move(temp -= operand); | |
729 | } | |
730 | ||
731 | template<class Type, class OperandT> | |
732 | typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type | |
733 | operator - (Type&& object, const OperandT& operand) | |
734 | { | |
735 | return boost::move(object -= operand); | |
736 | } | |
737 | ||
738 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
739 | ||
740 | //============================================================================== | |
741 | //= Intersection<IntervalSet|IntervalSet> | |
742 | //============================================================================== | |
743 | //------------------------------------------------------------------------------ | |
744 | //- void add_intersection(T&, c T&, c P&) T:{S M} P:{S'} | |
745 | //------------------------------------------------------------------------------ | |
746 | template<class Type, class OperandT> | |
747 | typename enable_if<mpl::and_<is_interval_set<Type>, | |
748 | combines_right_to_interval_set<Type, OperandT> >, | |
749 | void>::type | |
750 | add_intersection(Type& section, const Type& object, const OperandT& operand) | |
751 | { | |
752 | typedef typename OperandT::const_iterator const_iterator; | |
753 | ||
754 | if(operand.empty()) | |
755 | return; | |
756 | ||
757 | const_iterator common_lwb, common_upb; | |
758 | if(!Set::common_range(common_lwb, common_upb, operand, object)) | |
759 | return; | |
760 | ||
761 | const_iterator it_ = common_lwb; | |
762 | while(it_ != common_upb) | |
763 | icl::add_intersection(section, object, key_value<OperandT>(it_++)); | |
764 | } | |
765 | ||
766 | //------------------------------------------------------------------------------ | |
767 | //- T& op &=(T&, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} | |
768 | //------------------------------------------------------------------------------ | |
769 | template<class Type, class OperandT> | |
770 | typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type& | |
771 | operator &= (Type& object, const OperandT& operand) | |
772 | { | |
773 | Type intersection; | |
774 | add_intersection(intersection, object, operand); | |
775 | object.swap(intersection); | |
776 | return object; | |
777 | } | |
778 | ||
779 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
780 | //------------------------------------------------------------------------------ | |
781 | //- T op & (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser | |
782 | //------------------------------------------------------------------------------ | |
783 | template<class Type, class OperandT> | |
784 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
785 | operator & (Type object, const OperandT& operand) | |
786 | { | |
787 | return object &= operand; | |
788 | } | |
789 | ||
790 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
791 | ||
792 | template<class Type, class OperandT> | |
793 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
794 | operator & (const Type& object, const OperandT& operand) | |
795 | { | |
796 | Type temp = object; | |
797 | return boost::move(temp &= operand); | |
798 | } | |
799 | ||
800 | template<class Type, class OperandT> | |
801 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
802 | operator & (Type&& object, const OperandT& operand) | |
803 | { | |
804 | return boost::move(object &= operand); | |
805 | } | |
806 | ||
807 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
808 | ||
809 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
810 | //------------------------------------------------------------------------------ | |
811 | //- T op & (c P&, T) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser | |
812 | //------------------------------------------------------------------------------ | |
813 | template<class Type, class OperandT> | |
814 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
815 | operator & (const OperandT& operand, Type object) | |
816 | { | |
817 | return object &= operand; | |
818 | } | |
819 | ||
820 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
821 | ||
822 | template<class Type, class OperandT> | |
823 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
824 | operator & (const OperandT& operand, const Type& object) | |
825 | { | |
826 | Type temp = object; | |
827 | return boost::move(temp &= operand); | |
828 | } | |
829 | ||
830 | template<class Type, class OperandT> | |
831 | typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type | |
832 | operator & (const OperandT& operand, Type&& object) | |
833 | { | |
834 | return boost::move(object &= operand); | |
835 | } | |
836 | ||
837 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
838 | ||
839 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
840 | //------------------------------------------------------------------------------ | |
841 | //- T op & (T, c T&) T:{S M} | |
842 | //------------------------------------------------------------------------------ | |
843 | template<class Type> | |
844 | typename enable_if<is_interval_container<Type>, Type>::type | |
845 | operator & (Type object, const Type& operand) | |
846 | { | |
847 | return object &= operand; | |
848 | } | |
849 | ||
850 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
851 | ||
852 | template<class Type> | |
853 | typename enable_if<is_interval_container<Type>, Type>::type | |
854 | operator & (const Type& object, const Type& operand) | |
855 | { | |
856 | Type temp = object; | |
857 | return boost::move(temp &= operand); | |
858 | } | |
859 | ||
860 | template<class Type> | |
861 | typename enable_if<is_interval_container<Type>, Type>::type | |
862 | operator & (Type&& object, const Type& operand) | |
863 | { | |
864 | return boost::move(object &= operand); | |
865 | } | |
866 | ||
867 | template<class Type> | |
868 | typename enable_if<is_interval_container<Type>, Type>::type | |
869 | operator & (const Type& operand, Type&& object) | |
870 | { | |
871 | return boost::move(object &= operand); | |
872 | } | |
873 | ||
874 | template<class Type> | |
875 | typename enable_if<is_interval_container<Type>, Type>::type | |
876 | operator & (Type&& object, Type&& operand) | |
877 | { | |
878 | return boost::move(object &= operand); | |
879 | } | |
880 | ||
881 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
882 | ||
883 | //------------------------------------------------------------------------------ | |
884 | //- intersects<IntervalSet|IntervalMap> | |
885 | //------------------------------------------------------------------------------ | |
886 | //------------------------------------------------------------------------------ | |
887 | //- bool intersects(c T&, c P&) T:{S}|{M} P:{e i} | |
888 | //------------------------------------------------------------------------------ | |
889 | template<class Type, class CoType> | |
890 | typename enable_if<mpl::and_< is_interval_container<Type> | |
891 | , boost::is_same<CoType, typename domain_type_of<Type>::type> >, | |
892 | bool>::type | |
893 | intersects(const Type& left, const CoType& right) | |
894 | { | |
895 | return icl::contains(left, right); | |
896 | } | |
897 | ||
898 | template<class Type, class CoType> | |
899 | typename enable_if<mpl::and_< is_interval_container<Type> | |
900 | , boost::is_same<CoType, typename interval_type_of<Type>::type> >, | |
901 | bool>::type | |
902 | intersects(const Type& left, const CoType& right) | |
903 | { | |
904 | return icl::find(left, right) != left.end(); | |
905 | } | |
906 | ||
907 | ||
908 | template<class LeftT, class RightT> | |
909 | typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT> | |
910 | , mpl::or_<is_total<LeftT>, is_total<RightT> > > | |
911 | , bool>::type | |
912 | intersects(const LeftT&, const RightT&) | |
913 | { | |
914 | return true; | |
915 | } | |
916 | ||
917 | template<class LeftT, class RightT> | |
918 | typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT> | |
919 | , mpl::not_<mpl::or_< is_total<LeftT> | |
920 | , is_total<RightT> > > > | |
921 | , bool>::type | |
922 | intersects(const LeftT& left, const RightT& right) | |
923 | { | |
924 | typedef typename RightT::const_iterator const_iterator; | |
925 | LeftT intersection; | |
926 | ||
927 | const_iterator right_common_lower_, right_common_upper_; | |
928 | if(!Set::common_range(right_common_lower_, right_common_upper_, right, left)) | |
929 | return false; | |
930 | ||
931 | const_iterator it_ = right_common_lower_; | |
932 | while(it_ != right_common_upper_) | |
933 | { | |
934 | icl::add_intersection(intersection, left, *it_++); | |
935 | if(!icl::is_empty(intersection)) | |
936 | return true; | |
937 | } | |
938 | return false; | |
939 | } | |
940 | ||
941 | template<class LeftT, class RightT> | |
942 | typename enable_if<is_cross_combinable<LeftT, RightT>, bool>::type | |
943 | intersects(const LeftT& left, const RightT& right) | |
944 | { | |
945 | typedef typename RightT::const_iterator const_iterator; | |
946 | LeftT intersection; | |
947 | ||
948 | if(icl::is_empty(left) || icl::is_empty(right)) | |
949 | return false; | |
950 | ||
951 | const_iterator right_common_lower_, right_common_upper_; | |
952 | if(!Set::common_range(right_common_lower_, right_common_upper_, right, left)) | |
953 | return false; | |
954 | ||
955 | typename RightT::const_iterator it_ = right_common_lower_; | |
956 | while(it_ != right_common_upper_) | |
957 | { | |
958 | icl::add_intersection(intersection, left, key_value<RightT>(it_++)); | |
959 | if(!icl::is_empty(intersection)) | |
960 | return true; | |
961 | } | |
962 | ||
963 | return false; | |
964 | } | |
965 | ||
966 | /** \b Returns true, if \c left and \c right have no common elements. | |
967 | Intervals are interpreted as sequence of elements. | |
968 | \b Complexity: loglinear, if \c left and \c right are interval containers. */ | |
969 | template<class LeftT, class RightT> | |
970 | typename enable_if<is_inter_combinable<LeftT, RightT>, bool>::type | |
971 | disjoint(const LeftT& left, const RightT& right) | |
972 | { | |
973 | return !intersects(left, right); | |
974 | } | |
975 | ||
976 | /** \b Returns true, if \c left and \c right have no common elements. | |
977 | Intervals are interpreted as sequence of elements. | |
978 | \b Complexity: logarithmic, if \c AssociateT is an element type \c Type::element_type. | |
979 | linear, if \c AssociateT is a segment type \c Type::segment_type. */ | |
980 | template<class Type, class AssociateT> | |
981 | typename enable_if<is_inter_derivative<Type, AssociateT>, bool>::type | |
982 | disjoint(const Type& left, const AssociateT& right) | |
983 | { | |
984 | return !intersects(left,right); | |
985 | } | |
986 | ||
987 | ||
988 | //============================================================================== | |
989 | //= Symmetric difference<IntervalSet|IntervalSet> | |
990 | //============================================================================== | |
991 | //------------------------------------------------------------------------------ | |
992 | //- Symmetric difference ^=, ^ | |
993 | //------------------------------------------------------------------------------ | |
994 | //------------------------------------------------------------------------------ | |
995 | //- T& op ^=(T&, c P&) T:{S}|{M} P:{S'}|{M'} | |
996 | //------------------------------------------------------------------------------ | |
997 | template<class Type, class OperandT> | |
998 | typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type& | |
999 | operator ^= (Type& object, const OperandT& operand) | |
1000 | { | |
1001 | return icl::flip(object, operand); | |
1002 | } | |
1003 | ||
1004 | //------------------------------------------------------------------------------ | |
1005 | //- T& op ^=(T&, c P&) T:{S}|{M} P:{e i}|{b p} | |
1006 | //------------------------------------------------------------------------------ | |
1007 | template<class Type, class OperandT> | |
1008 | typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type& | |
1009 | operator ^= (Type& object, const OperandT& operand) | |
1010 | { | |
1011 | return icl::flip(object, operand); | |
1012 | } | |
1013 | ||
1014 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1015 | //------------------------------------------------------------------------------ | |
1016 | //- T op ^ (T, c P&) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser | |
1017 | //------------------------------------------------------------------------------ | |
1018 | template<class Type, class OperandT> | |
1019 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1020 | operator ^ (Type object, const OperandT& operand) | |
1021 | { | |
1022 | return object ^= operand; | |
1023 | } | |
1024 | ||
1025 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1026 | ||
1027 | template<class Type, class OperandT> | |
1028 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1029 | operator ^ (const Type& object, const OperandT& operand) | |
1030 | { | |
1031 | Type temp = object; | |
1032 | return boost::move(temp ^= operand); | |
1033 | } | |
1034 | ||
1035 | template<class Type, class OperandT> | |
1036 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1037 | operator ^ (Type&& object, const OperandT& operand) | |
1038 | { | |
1039 | return boost::move(object ^= operand); | |
1040 | } | |
1041 | ||
1042 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1043 | ||
1044 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1045 | //------------------------------------------------------------------------------ | |
1046 | //- T op ^ (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser | |
1047 | //------------------------------------------------------------------------------ | |
1048 | template<class Type, class OperandT> | |
1049 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1050 | operator ^ (const OperandT& operand, Type object) | |
1051 | { | |
1052 | return object ^= operand; | |
1053 | } | |
1054 | ||
1055 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1056 | ||
1057 | template<class Type, class OperandT> | |
1058 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1059 | operator ^ (const OperandT& operand, const Type& object) | |
1060 | { | |
1061 | Type temp = object; | |
1062 | return boost::move(temp ^= operand); | |
1063 | } | |
1064 | ||
1065 | template<class Type, class OperandT> | |
1066 | typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type | |
1067 | operator ^ (const OperandT& operand, Type&& object) | |
1068 | { | |
1069 | return boost::move(object ^= operand); | |
1070 | } | |
1071 | ||
1072 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1073 | ||
1074 | #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1075 | //------------------------------------------------------------------------------ | |
1076 | //- T op ^ (T, c T&) T:{S M} | |
1077 | //------------------------------------------------------------------------------ | |
1078 | template<class Type> | |
1079 | typename enable_if<is_interval_container<Type>, Type>::type | |
1080 | operator ^ (typename Type::overloadable_type object, const Type& operand) | |
1081 | { | |
1082 | return object ^= operand; | |
1083 | } | |
1084 | ||
1085 | #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1086 | ||
1087 | template<class Type> | |
1088 | typename enable_if<is_interval_container<Type>, Type>::type | |
1089 | operator ^ (const Type& object, const Type& operand) | |
1090 | { | |
1091 | Type temp = object; | |
1092 | return boost::move(temp ^= operand); | |
1093 | } | |
1094 | ||
1095 | template<class Type> | |
1096 | typename enable_if<is_interval_container<Type>, Type>::type | |
1097 | operator ^ (Type&& object, const Type& operand) | |
1098 | { | |
1099 | return boost::move(object ^= operand); | |
1100 | } | |
1101 | ||
1102 | template<class Type> | |
1103 | typename enable_if<is_interval_container<Type>, Type>::type | |
1104 | operator ^ (const Type& operand, Type&& object) | |
1105 | { | |
1106 | return boost::move(object ^= operand); | |
1107 | } | |
1108 | ||
1109 | template<class Type> | |
1110 | typename enable_if<is_interval_container<Type>, Type>::type | |
1111 | operator ^ (Type&& object, Type&& operand) | |
1112 | { | |
1113 | return boost::move(object ^= operand); | |
1114 | } | |
1115 | ||
1116 | #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
1117 | ||
1118 | //========================================================================== | |
1119 | //= Element Iteration <IntervalSet|IntervalMap> | |
1120 | //========================================================================== | |
1121 | //-------------------------------------------------------------------------- | |
1122 | //- Forward | |
1123 | //-------------------------------------------------------------------------- | |
1124 | template<class Type> | |
1125 | typename enable_if | |
1126 | <mpl::and_< is_interval_container<Type> | |
1127 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1128 | typename Type::element_iterator>::type | |
1129 | elements_begin(Type& object) | |
1130 | { | |
1131 | return typename Type::element_iterator(object.begin()); | |
1132 | } | |
1133 | ||
1134 | template<class Type> | |
1135 | typename enable_if | |
1136 | <mpl::and_< is_interval_container<Type> | |
1137 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1138 | typename Type::element_iterator>::type | |
1139 | elements_end(Type& object) | |
1140 | { | |
1141 | return typename Type::element_iterator(object.end()); | |
1142 | } | |
1143 | ||
1144 | template<class Type> | |
1145 | typename enable_if | |
1146 | <mpl::and_< is_interval_container<Type> | |
1147 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1148 | typename Type::element_const_iterator>::type | |
1149 | elements_begin(const Type& object) | |
1150 | { | |
1151 | return typename Type::element_const_iterator(object.begin()); | |
1152 | } | |
1153 | ||
1154 | template<class Type> | |
1155 | typename enable_if | |
1156 | <mpl::and_< is_interval_container<Type> | |
1157 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1158 | typename Type::element_const_iterator>::type | |
1159 | elements_end(const Type& object) | |
1160 | { | |
1161 | return typename Type::element_const_iterator(object.end()); | |
1162 | } | |
1163 | ||
1164 | //-------------------------------------------------------------------------- | |
1165 | //- Reverse | |
1166 | //-------------------------------------------------------------------------- | |
1167 | template<class Type> | |
1168 | typename enable_if | |
1169 | <mpl::and_< is_interval_container<Type> | |
1170 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1171 | typename Type::element_reverse_iterator>::type | |
1172 | elements_rbegin(Type& object) | |
1173 | { | |
1174 | return typename Type::element_reverse_iterator(object.rbegin()); | |
1175 | } | |
1176 | ||
1177 | template<class Type> | |
1178 | typename enable_if | |
1179 | <mpl::and_< is_interval_container<Type> | |
1180 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1181 | typename Type::element_reverse_iterator>::type | |
1182 | elements_rend(Type& object) | |
1183 | { | |
1184 | return typename Type::element_reverse_iterator(object.rend()); | |
1185 | } | |
1186 | ||
1187 | template<class Type> | |
1188 | typename enable_if | |
1189 | <mpl::and_< is_interval_container<Type> | |
1190 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1191 | typename Type::element_const_reverse_iterator>::type | |
1192 | elements_rbegin(const Type& object) | |
1193 | { | |
1194 | return typename Type::element_const_reverse_iterator(object.rbegin()); | |
1195 | } | |
1196 | ||
1197 | template<class Type> | |
1198 | typename enable_if | |
1199 | <mpl::and_< is_interval_container<Type> | |
1200 | , mpl::not_<is_continuous_interval<typename Type::interval_type> > >, | |
1201 | typename Type::element_const_reverse_iterator>::type | |
1202 | elements_rend(const Type& object) | |
1203 | { | |
1204 | return typename Type::element_const_reverse_iterator(object.rend()); | |
1205 | } | |
1206 | ||
1207 | }} // namespace boost icl | |
1208 | ||
1209 | #endif | |
1210 | ||
1211 |