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