Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/icl/concept/interval_associator.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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 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 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 |