]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/icl/include/boost/icl/concept/interval.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / icl / include / boost / icl / concept / interval.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_HPP_JOFA_100323
9#define BOOST_ICL_CONCEPT_INTERVAL_HPP_JOFA_100323
10
11#include <boost/assert.hpp>
12#include <boost/utility/enable_if.hpp>
13#include <boost/mpl/and.hpp>
14#include <boost/mpl/or.hpp>
15#include <boost/mpl/not.hpp>
16#include <boost/icl/detail/design_config.hpp>
17#include <boost/icl/type_traits/unit_element.hpp>
18#include <boost/icl/type_traits/identity_element.hpp>
19#include <boost/icl/type_traits/infinity.hpp>
20#include <boost/icl/type_traits/succ_pred.hpp>
21#include <boost/icl/type_traits/is_numeric.hpp>
22#include <boost/icl/type_traits/is_discrete.hpp>
23#include <boost/icl/type_traits/is_continuous.hpp>
24#include <boost/icl/type_traits/is_asymmetric_interval.hpp>
25#include <boost/icl/type_traits/is_discrete_interval.hpp>
26#include <boost/icl/type_traits/is_continuous_interval.hpp>
27
28#include <boost/icl/concept/interval_bounds.hpp>
29#include <boost/icl/interval_traits.hpp>
30#include <boost/icl/dynamic_interval_traits.hpp>
31
32
33namespace boost{namespace icl
34{
35
36//==============================================================================
37//= Ordering
38//==============================================================================
39template<class Type>
40inline typename enable_if<is_interval<Type>, bool>::type
41domain_less(const typename interval_traits<Type>::domain_type& left,
42 const typename interval_traits<Type>::domain_type& right)
43{
44 return typename interval_traits<Type>::domain_compare()(left, right);
45}
46
47template<class Type>
48inline typename enable_if<is_interval<Type>, bool>::type
49domain_less_equal(const typename interval_traits<Type>::domain_type& left,
50 const typename interval_traits<Type>::domain_type& right)
51{
52 return !(typename interval_traits<Type>::domain_compare()(right, left));
53}
54
55template<class Type>
56inline typename enable_if<is_interval<Type>, bool>::type
57domain_equal(const typename interval_traits<Type>::domain_type& left,
58 const typename interval_traits<Type>::domain_type& right)
59{
60 typedef typename interval_traits<Type>::domain_compare domain_compare;
61 return !(domain_compare()(left, right)) && !(domain_compare()(right, left));
62}
63
64template<class Type>
65inline typename enable_if< is_interval<Type>
66 , typename interval_traits<Type>::domain_type>::type
67domain_next(const typename interval_traits<Type>::domain_type value)
68{
69 typedef typename interval_traits<Type>::domain_type domain_type;
70 typedef typename interval_traits<Type>::domain_compare domain_compare;
71 return icl::successor<domain_type,domain_compare>::apply(value);
72}
73
74template<class Type>
75inline typename enable_if< is_interval<Type>
76 , typename interval_traits<Type>::domain_type>::type
77domain_prior(const typename interval_traits<Type>::domain_type value)
78{
79 typedef typename interval_traits<Type>::domain_type domain_type;
80 typedef typename interval_traits<Type>::domain_compare domain_compare;
81 return icl::predecessor<domain_type,domain_compare>::apply(value);
82}
83
84//==============================================================================
85//= Construct<Interval> singleton
86//==============================================================================
87template<class Type>
88typename enable_if
89<
90 mpl::and_< is_static_right_open<Type>
91 , is_discrete<typename interval_traits<Type>::domain_type> >
92 , Type
93>::type
94singleton(const typename interval_traits<Type>::domain_type& value)
95{
96 //ASSERT: This always creates an interval with exactly one element
97 return interval_traits<Type>::construct(value, domain_next<Type>(value));
98}
99
100template<class Type>
101typename enable_if
102<
103 mpl::and_< is_static_left_open<Type>
104 , is_discrete<typename interval_traits<Type>::domain_type> >
105 , Type
106>::type
107singleton(const typename interval_traits<Type>::domain_type& value)
108{
109 //ASSERT: This always creates an interval with exactly one element
110 typedef typename interval_traits<Type>::domain_type domain_type;
111 typedef typename interval_traits<Type>::domain_compare domain_compare;
112 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
113 ::is_less_than(value) ));
114
115 return interval_traits<Type>::construct(domain_prior<Type>(value), value);
116}
117
118template<class Type>
119typename enable_if<is_discrete_static_open<Type>, Type>::type
120singleton(const typename interval_traits<Type>::domain_type& value)
121{
122 //ASSERT: This always creates an interval with exactly one element
123 typedef typename interval_traits<Type>::domain_type domain_type;
124 typedef typename interval_traits<Type>::domain_compare domain_compare;
125 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
126 ::is_less_than(value)));
127
128 return interval_traits<Type>::construct( domain_prior<Type>(value)
129 , domain_next<Type>(value));
130}
131
132template<class Type>
133typename enable_if<is_discrete_static_closed<Type>, Type>::type
134singleton(const typename interval_traits<Type>::domain_type& value)
135{
136 //ASSERT: This always creates an interval with exactly one element
137 return interval_traits<Type>::construct(value, value);
138}
139
140template<class Type>
141typename enable_if<has_dynamic_bounds<Type>, Type>::type
142singleton(const typename interval_traits<Type>::domain_type& value)
143{
144 return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed());
145}
146
147namespace detail
148{
149
150//==============================================================================
151//= Construct<Interval> unit_trail == generalized singleton
152// The smallest interval on an incrementable (and decrementable) type that can
153// be constructed using ++ and -- and such that it contains a given value.
154// If 'Type' is discrete, 'unit_trail' and 'singleton' are identical. So we
155// can view 'unit_trail' as a generalized singleton for static intervals of
156// continuous types.
157//==============================================================================
158template<class Type>
159typename enable_if
160<
161 mpl::and_< is_static_right_open<Type>
162 , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> >
163 , Type
164>::type
165unit_trail(const typename interval_traits<Type>::domain_type& value)
166{
167 return interval_traits<Type>::construct(value, domain_next<Type>(value));
168}
169
170template<class Type>
171typename enable_if
172<
173 mpl::and_< is_static_left_open<Type>
174 , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> >
175 , Type
176>::type
177unit_trail(const typename interval_traits<Type>::domain_type& value)
178{
179 typedef typename interval_traits<Type>::domain_type domain_type;
180 typedef typename interval_traits<Type>::domain_compare domain_compare;
181 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
182 ::is_less_than(value) ));
183
184 return interval_traits<Type>::construct(domain_prior<Type>(value), value);
185}
186
187template<class Type>
188typename enable_if
189<
190 mpl::and_< is_static_open<Type>
191 , is_discrete<typename interval_traits<Type>::domain_type> >
192 , Type
193>::type
194unit_trail(const typename interval_traits<Type>::domain_type& value)
195{
196 typedef typename interval_traits<Type>::domain_type domain_type;
197 typedef typename interval_traits<Type>::domain_compare domain_compare;
198 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
199 ::is_less_than(value)));
200
201 return interval_traits<Type>::construct( domain_prior<Type>(value)
202 , domain_next<Type>(value));
203}
204
205template<class Type>
206typename enable_if
207<
208 mpl::and_< is_static_closed<Type>
209 , is_discrete<typename interval_traits<Type>::domain_type> >
210 , Type
211>::type
212unit_trail(const typename interval_traits<Type>::domain_type& value)
213{
214 return interval_traits<Type>::construct(value, value);
215}
216
217//NOTE: statically bounded closed or open intervals of continuous domain types
218// are NOT supported by ICL. They can not be used with interval containers
219// consistently.
220
221
222template<class Type>
223typename enable_if<has_dynamic_bounds<Type>, Type>::type
224unit_trail(const typename interval_traits<Type>::domain_type& value)
225{
226 return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed());
227}
228
229} //namespace detail
230
231//==============================================================================
232//= Construct<Interval> multon
233//==============================================================================
234template<class Type>
235typename enable_if<has_static_bounds<Type>, Type>::type
236construct(const typename interval_traits<Type>::domain_type& low,
237 const typename interval_traits<Type>::domain_type& up )
238{
239 return interval_traits<Type>::construct(low, up);
240}
241
242template<class Type>
243typename enable_if<has_dynamic_bounds<Type>, Type>::type
244construct(const typename interval_traits<Type>::domain_type& low,
245 const typename interval_traits<Type>::domain_type& up,
246 interval_bounds bounds = interval_bounds::right_open())
247{
248 return dynamic_interval_traits<Type>::construct(low, up, bounds);
249}
250
251
252//- construct form bounded values ----------------------------------------------
253template<class Type>
254typename enable_if<has_dynamic_bounds<Type>, Type>::type
255construct(const typename Type::bounded_domain_type& low,
256 const typename Type::bounded_domain_type& up)
257{
258 return dynamic_interval_traits<Type>::construct_bounded(low, up);
259}
260
261template<class Type>
262typename enable_if<is_interval<Type>, Type>::type
263span(const typename interval_traits<Type>::domain_type& left,
264 const typename interval_traits<Type>::domain_type& right)
265{
266 if(interval_traits<Type>::domain_compare()(left,right))
267 return construct<Type>(left, right);
268 else
269 return construct<Type>(right, left);
270}
271
272
273//==============================================================================
274template<class Type>
275typename enable_if<is_static_right_open<Type>, Type>::type
276hull(const typename interval_traits<Type>::domain_type& left,
277 const typename interval_traits<Type>::domain_type& right)
278{
279 if(interval_traits<Type>::domain_compare()(left,right))
280 return construct<Type>(left, domain_next<Type>(right));
281 else
282 return construct<Type>(right, domain_next<Type>(left));
283}
284
285template<class Type>
286typename enable_if<is_static_left_open<Type>, Type>::type
287hull(const typename interval_traits<Type>::domain_type& left,
288 const typename interval_traits<Type>::domain_type& right)
289{
290 typedef typename interval_traits<Type>::domain_type domain_type;
291 typedef typename interval_traits<Type>::domain_compare domain_compare;
292 if(interval_traits<Type>::domain_compare()(left,right))
293 {
294 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
295 ::is_less_than(left) ));
296 return construct<Type>(domain_prior<Type>(left), right);
297 }
298 else
299 {
300 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
301 ::is_less_than(right) ));
302 return construct<Type>(domain_prior<Type>(right), left);
303 }
304}
305
306template<class Type>
307typename enable_if<is_static_closed<Type>, Type>::type
308hull(const typename interval_traits<Type>::domain_type& left,
309 const typename interval_traits<Type>::domain_type& right)
310{
311 if(interval_traits<Type>::domain_compare()(left,right))
312 return construct<Type>(left, right);
313 else
314 return construct<Type>(right, left);
315}
316
317template<class Type>
318typename enable_if<is_static_open<Type>, Type>::type
319hull(const typename interval_traits<Type>::domain_type& left,
320 const typename interval_traits<Type>::domain_type& right)
321{
322 typedef typename interval_traits<Type>::domain_type domain_type;
323 typedef typename interval_traits<Type>::domain_compare domain_compare;
324 if(interval_traits<Type>::domain_compare()(left,right))
325 {
326 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
327 ::is_less_than(left) ));
328 return construct<Type>( domain_prior<Type>(left)
329 , domain_next<Type>(right));
330 }
331 else
332 {
333 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
334 ::is_less_than(right) ));
335 return construct<Type>( domain_prior<Type>(right)
336 , domain_next<Type>(left));
337 }
338}
339
340template<class Type>
341typename enable_if<has_dynamic_bounds<Type>, Type>::type
342hull(const typename interval_traits<Type>::domain_type& left,
343 const typename interval_traits<Type>::domain_type& right)
344{
345 if(interval_traits<Type>::domain_compare()(left,right))
346 return construct<Type>(left, right, interval_bounds::closed());
347 else
348 return construct<Type>(right, left, interval_bounds::closed());
349}
350
351//==============================================================================
352//= Selection
353//==============================================================================
354
355template<class Type>
356inline typename enable_if<is_interval<Type>,
357 typename interval_traits<Type>::domain_type>::type
358lower(const Type& object)
359{
360 return interval_traits<Type>::lower(object);
361}
362
363template<class Type>
364inline typename enable_if<is_interval<Type>,
365 typename interval_traits<Type>::domain_type>::type
366upper(const Type& object)
367{
368 return interval_traits<Type>::upper(object);
369}
370
371
372//- first ----------------------------------------------------------------------
373template<class Type>
374inline typename
375enable_if< mpl::or_<is_static_right_open<Type>, is_static_closed<Type> >
376 , typename interval_traits<Type>::domain_type>::type
377first(const Type& object)
378{
379 return lower(object);
380}
381
382template<class Type>
383inline typename
384enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_open<Type> >
385 , is_discrete<typename interval_traits<Type>::domain_type> >
386 , typename interval_traits<Type>::domain_type>::type
387first(const Type& object)
388{
389 return domain_next<Type>(lower(object));
390}
391
392template<class Type>
393inline typename enable_if<is_discrete_interval<Type>,
394 typename interval_traits<Type>::domain_type>::type
395first(const Type& object)
396{
397 return is_left_closed(object.bounds()) ?
398 lower(object) :
399 domain_next<Type>(lower(object));
400}
401
402//- last -----------------------------------------------------------------------
403template<class Type>
404inline typename
405enable_if< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> >
406 , typename interval_traits<Type>::domain_type>::type
407last(const Type& object)
408{
409 return upper(object);
410}
411
412template<class Type>
413inline typename
414enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> >
415 , is_discrete<typename interval_traits<Type>::domain_type> >
416 , typename interval_traits<Type>::domain_type>::type
417last(const Type& object)
418{
419 typedef typename interval_traits<Type>::domain_type domain_type;
420 typedef typename interval_traits<Type>::domain_compare domain_compare;
421 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
422 ::is_less_than(upper(object)) ));
423 return domain_prior<Type>(upper(object));
424}
425
426template<class Type>
427inline typename enable_if<is_discrete_interval<Type>,
428 typename interval_traits<Type>::domain_type>::type
429last(const Type& object)
430{
431 typedef typename interval_traits<Type>::domain_type domain_type;
432 typedef typename interval_traits<Type>::domain_compare domain_compare;
433 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
434 ::is_less_than_or(upper(object), is_right_closed(object.bounds())) ));
435 return is_right_closed(object.bounds()) ?
436 upper(object) :
437 domain_prior<Type>(upper(object));
438}
439
440//- last_next ------------------------------------------------------------------
441template<class Type>
442inline typename
443enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> >
444 , is_discrete<typename interval_traits<Type>::domain_type> >
445 , typename interval_traits<Type>::domain_type>::type
446last_next(const Type& object)
447{
448 return domain_next<Type>(upper(object));
449}
450
451template<class Type>
452inline typename
453enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> >
454 , is_discrete<typename interval_traits<Type>::domain_type> >
455 , typename interval_traits<Type>::domain_type>::type
456last_next(const Type& object)
457{
458 //CL typedef typename interval_traits<Type>::domain_type domain_type;
459 return upper(object); // NOTE: last_next is implemented to avoid calling pred(object)
460} // For unsigned integral types this may cause underflow.
461
462template<class Type>
463inline typename enable_if<is_discrete_interval<Type>,
464 typename interval_traits<Type>::domain_type>::type
465last_next(const Type& object)
466{
467 return is_right_closed(object.bounds()) ?
468 domain_next<Type>(upper(object)):
469 upper(object) ;
470}
471
472//------------------------------------------------------------------------------
473template<class Type>
474typename enable_if<has_dynamic_bounds<Type>,
475 typename Type::bounded_domain_type>::type
476bounded_lower(const Type& object)
477{
478 return typename
479 Type::bounded_domain_type(lower(object), object.bounds().left());
480}
481
482template<class Type>
483typename enable_if<has_dynamic_bounds<Type>,
484 typename Type::bounded_domain_type>::type
485reverse_bounded_lower(const Type& object)
486{
487 return typename
488 Type::bounded_domain_type(lower(object),
489 object.bounds().reverse_left());
490}
491
492template<class Type>
493typename enable_if<has_dynamic_bounds<Type>,
494 typename Type::bounded_domain_type>::type
495bounded_upper(const Type& object)
496{
497 return typename
498 Type::bounded_domain_type(upper(object),
499 object.bounds().right());
500}
501
502template<class Type>
503typename enable_if<has_dynamic_bounds<Type>,
504 typename Type::bounded_domain_type>::type
505reverse_bounded_upper(const Type& object)
506{
507 return typename
508 Type::bounded_domain_type(upper(object),
509 object.bounds().reverse_right());
510}
511
512//- bounds ---------------------------------------------------------------------
513template<class Type>
514inline typename enable_if<has_dynamic_bounds<Type>, interval_bounds>::type
515bounds(const Type& object)
516{
517 return object.bounds();
518}
519
520template<class Type>
521inline typename enable_if<has_static_bounds<Type>, interval_bounds>::type
522bounds(const Type&)
523{
524 return interval_bounds(interval_bound_type<Type>::value);
525}
526
527
528//==============================================================================
529//= Emptieness
530//==============================================================================
531/** Is the interval empty? */
532template<class Type>
533typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
534is_empty(const Type& object)
535{
536 return domain_less_equal<Type>(upper(object), lower(object));
537}
538
539template<class Type>
540typename boost::enable_if<is_static_closed<Type>, bool>::type
541is_empty(const Type& object)
542{
543 return domain_less<Type>(upper(object), lower(object));
544}
545
546template<class Type>
547typename boost::enable_if<is_static_open<Type>, bool>::type
548is_empty(const Type& object)
549{
550 return domain_less_equal<Type>(upper(object), lower(object) )
551 || domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object)));
552}
553
554template<class Type>
555typename boost::enable_if<is_discrete_interval<Type>, bool>::type
556is_empty(const Type& object)
557{
558 if(object.bounds() == interval_bounds::closed())
559 return domain_less<Type>(upper(object), lower(object));
560 else if(object.bounds() == interval_bounds::open())
561 return domain_less_equal<Type>(upper(object), lower(object) )
562 || domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object)));
563 else
564 return domain_less_equal<Type>(upper(object), lower(object));
565}
566
567template<class Type>
568typename boost::enable_if<is_continuous_interval<Type>, bool>::type
569is_empty(const Type& object)
570{
571 return domain_less<Type>(upper(object), lower(object))
572 || ( domain_equal<Type>(upper(object), lower(object))
573 && object.bounds() != interval_bounds::closed() );
574}
575
576//==============================================================================
577//= Orderings, containedness (non empty)
578//==============================================================================
579namespace non_empty
580{
581
582 template<class Type>
583 inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
584 exclusive_less(const Type& left, const Type& right)
585 {
586 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
587 return domain_less_equal<Type>(upper(left), lower(right));
588 }
589
590 template<class Type>
591 inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type
592 exclusive_less(const Type& left, const Type& right)
593 {
594 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
595 return domain_less<Type>(last(left), first(right));
596 }
597
598 template<class Type>
599 inline typename boost::
600 enable_if<has_symmetric_bounds<Type>, bool>::type
601 exclusive_less(const Type& left, const Type& right)
602 {
603 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
604 return domain_less<Type>(last(left), first(right));
605 }
606
607 template<class Type>
608 inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type
609 exclusive_less(const Type& left, const Type& right)
610 {
611 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
612 return domain_less <Type>(upper(left), lower(right))
613 || ( domain_equal<Type>(upper(left), lower(right))
614 && inner_bounds(left,right) != interval_bounds::open() );
615 }
616
617 template<class Type>
618 inline typename boost::enable_if<is_interval<Type>, bool>::type
619 contains(const Type& super, const Type& sub)
620 {
621 return lower_less_equal(super,sub) && upper_less_equal(sub,super);
622 }
623
624
625} //namespace non_empty
626
627
628//- contains -------------------------------------------------------------------
629template<class Type>
630inline typename boost::enable_if<is_interval<Type>, bool>::type
631contains(const Type& super, const Type& sub)
632{
633 return icl::is_empty(sub) || non_empty::contains(super, sub);
634}
635
636template<class Type>
637typename boost::enable_if<is_discrete_static<Type>, bool>::type
638contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
639{
640 return domain_less_equal<Type>(icl::first(super), element )
641 && domain_less_equal<Type>( element, icl::last(super));
642}
643
644template<class Type>
645typename boost::enable_if<is_continuous_left_open<Type>, bool>::type
646contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
647{
648 return domain_less <Type>(icl::lower(super), element )
649 && domain_less_equal<Type>( element, icl::upper(super));
650}
651
652template<class Type>
653typename boost::enable_if<is_continuous_right_open<Type>, bool>::type
654contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
655{
656 return domain_less_equal<Type>(icl::lower(super), element )
657 && domain_less <Type>( element, icl::upper(super));
658}
659
660template<class Type>
661typename boost::enable_if<has_dynamic_bounds<Type>, bool>::type
662contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
663{
664 return
665 (is_left_closed(super.bounds())
666 ? domain_less_equal<Type>(lower(super), element)
667 : domain_less<Type>(lower(super), element))
668 &&
669 (is_right_closed(super.bounds())
670 ? domain_less_equal<Type>(element, upper(super))
671 : domain_less<Type>(element, upper(super)));
672}
673
674//- within ---------------------------------------------------------------------
675template<class Type>
676inline typename boost::enable_if<is_interval<Type>, bool>::type
677within(const Type& sub, const Type& super)
678{
679 return contains(super,sub);
680}
681
682
683//==============================================================================
684//= Equivalences and Orderings
685//==============================================================================
686//- exclusive_less -------------------------------------------------------------
687/** Maximal element of <tt>left</tt> is less than the minimal element of
688 <tt>right</tt> */
689template<class Type>
690inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
691exclusive_less(const Type& left, const Type& right)
692{
693 return icl::is_empty(left) || icl::is_empty(right)
694 || domain_less_equal<Type>(upper(left), lower(right));
695}
696
697template<class Type>
698inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type
699exclusive_less(const Type& left, const Type& right)
700{
701 return icl::is_empty(left) || icl::is_empty(right)
702 || domain_less<Type>(last(left), first(right));
703}
704
705template<class Type>
706inline typename boost::
707enable_if<has_symmetric_bounds<Type>, bool>::type
708exclusive_less(const Type& left, const Type& right)
709{
710 return icl::is_empty(left) || icl::is_empty(right)
711 || domain_less<Type>(last(left), first(right));
712}
713
714template<class Type>
715inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type
716exclusive_less(const Type& left, const Type& right)
717{
718 return icl::is_empty(left) || icl::is_empty(right)
719 || domain_less<Type>(upper(left), lower(right))
720 || ( domain_equal<Type>(upper(left), lower(right))
721 && inner_bounds(left,right) != interval_bounds::open() );
722}
723
724
725//------------------------------------------------------------------------------
726template<class Type>
727typename boost::enable_if<has_static_bounds<Type>, bool>::type
728lower_less(const Type& left, const Type& right)
729{
730 return domain_less<Type>(lower(left), lower(right));
731}
732
733template<class Type>
734typename boost::enable_if<is_discrete_interval<Type>, bool>::type
735lower_less(const Type& left, const Type& right)
736{
737 return domain_less<Type>(first(left), first(right));
738}
739
740template<class Type>
741typename boost::enable_if<is_continuous_interval<Type>, bool>::type
742lower_less(const Type& left, const Type& right)
743{
744 if(left_bounds(left,right) == interval_bounds::right_open()) //'[(' == 10
745 return domain_less_equal<Type>(lower(left), lower(right));
746 else
747 return domain_less<Type>(lower(left), lower(right));
748}
749
750
751//------------------------------------------------------------------------------
752template<class Type>
753typename boost::enable_if<has_static_bounds<Type>, bool>::type
754upper_less(const Type& left, const Type& right)
755{
756 return domain_less<Type>(upper(left), upper(right));
757}
758
759template<class Type>
760typename boost::enable_if<is_discrete_interval<Type>, bool>::type
761upper_less(const Type& left, const Type& right)
762{
763 return domain_less<Type>(last(left), last(right));
764}
765
766template<class Type>
767typename boost::enable_if<is_continuous_interval<Type>, bool>::type
768upper_less(const Type& left, const Type& right)
769{
770 if(right_bounds(left,right) == interval_bounds::left_open())
771 return domain_less_equal<Type>(upper(left), upper(right));
772 else
773 return domain_less<Type>(upper(left), upper(right));
774}
775
776//------------------------------------------------------------------------------
777template<class Type>
778typename boost::enable_if<has_dynamic_bounds<Type>,
779 typename Type::bounded_domain_type >::type
780lower_min(const Type& left, const Type& right)
781{
782 return lower_less(left, right) ? bounded_lower(left) : bounded_lower(right);
783}
784
785//------------------------------------------------------------------------------
786template<class Type>
787typename boost::enable_if<has_dynamic_bounds<Type>,
788 typename Type::bounded_domain_type >::type
789lower_max(const Type& left, const Type& right)
790{
791 return lower_less(left, right) ? bounded_lower(right) : bounded_lower(left);
792}
793
794//------------------------------------------------------------------------------
795template<class Type>
796typename boost::enable_if<has_dynamic_bounds<Type>,
797 typename Type::bounded_domain_type >::type
798upper_max(const Type& left, const Type& right)
799{
800 return upper_less(left, right) ? bounded_upper(right) : bounded_upper(left);
801}
802
803//------------------------------------------------------------------------------
804template<class Type>
805typename boost::enable_if<has_dynamic_bounds<Type>,
806 typename Type::bounded_domain_type >::type
807upper_min(const Type& left, const Type& right)
808{
809 return upper_less(left, right) ? bounded_upper(left) : bounded_upper(right);
810}
811
812
813//------------------------------------------------------------------------------
814template<class Type>
815typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
816lower_equal(const Type& left, const Type& right)
817{
818 return domain_equal<Type>(lower(left), lower(right));
819}
820
821template<class Type>
822typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
823lower_equal(const Type& left, const Type& right)
824{
825 return domain_equal<Type>(first(left), first(right));
826}
827
828template<class Type>
829typename boost::enable_if<is_discrete_interval<Type>, bool>::type
830lower_equal(const Type& left, const Type& right)
831{
832 return domain_equal<Type>(first(left), first(right));
833}
834
835template<class Type>
836typename boost::enable_if<is_continuous_interval<Type>, bool>::type
837lower_equal(const Type& left, const Type& right)
838{
839 return (left.bounds().left()==right.bounds().left())
840 && domain_equal<Type>(lower(left), lower(right));
841}
842
843
844//------------------------------------------------------------------------------
845template<class Type>
846typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
847upper_equal(const Type& left, const Type& right)
848{
849 return domain_equal<Type>(upper(left), upper(right));
850}
851
852template<class Type>
853typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
854upper_equal(const Type& left, const Type& right)
855{
856 return domain_equal<Type>(last(left), last(right));
857}
858
859template<class Type>
860typename boost::enable_if<is_discrete_interval<Type>, bool>::type
861upper_equal(const Type& left, const Type& right)
862{
863 return domain_equal<Type>(last(left), last(right));
864}
865
866template<class Type>
867typename boost::enable_if<is_continuous_interval<Type>, bool>::type
868upper_equal(const Type& left, const Type& right)
869{
870 return (left.bounds().right()==right.bounds().right())
871 && domain_equal<Type>(upper(left), upper(right));
872}
873
874//------------------------------------------------------------------------------
875template<class Type>
876typename boost::enable_if<is_interval<Type>, bool>::type
877lower_less_equal(const Type& left, const Type& right)
878{
879 return lower_less(left,right) || lower_equal(left,right);
880}
881
882template<class Type>
883typename boost::enable_if<is_interval<Type>, bool>::type
884upper_less_equal(const Type& left, const Type& right)
885{
886 return upper_less(left,right) || upper_equal(left,right);
887}
888
889
890//- operator == ----------------------------------------------------------------
891template<class Type>
892typename boost::enable_if<is_interval<Type>, bool>::type
893operator == (const Type& left, const Type& right)
894{
895 return (icl::is_empty(left) && icl::is_empty(right))
896 || (lower_equal(left,right) && upper_equal(left,right));
897}
898
899template<class Type>
900typename boost::enable_if<is_interval<Type>, bool>::type
901operator != (const Type& left, const Type& right)
902{
903 return !(left == right);
904}
905
906//- operator < -----------------------------------------------------------------
907template<class Type>
908typename boost::enable_if<is_interval<Type>, bool>::type
909operator < (const Type& left, const Type& right)
910{
911 if(icl::is_empty(left))
912 return !icl::is_empty(right);
913 else
914 return lower_less(left,right)
915 || (lower_equal(left,right) && upper_less(left,right));
916}
917
918template<class Type>
919inline typename boost::enable_if<is_interval<Type>, bool>::type
920operator > (const Type& left, const Type& right)
921{
922 return right < left;
923}
924
925
926
927//------------------------------------------------------------------------------
928template<class Type>
929typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
930touches(const Type& left, const Type& right)
931{
932 return domain_equal<Type>(upper(left), lower(right));
933}
934
935template<class Type>
936typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
937touches(const Type& left, const Type& right)
938{
939 return domain_equal<Type>(last_next(left), first(right));
940}
941
942template<class Type>
943typename boost::enable_if<is_discrete_interval<Type>, bool>::type
944touches(const Type& left, const Type& right)
945{
946 return domain_equal<Type>(domain_next<Type>(last(left)), first(right));
947}
948
949template<class Type>
950typename boost::enable_if<is_continuous_interval<Type>, bool>::type
951touches(const Type& left, const Type& right)
952{
953 return is_complementary(inner_bounds(left,right))
954 && domain_equal<Type>(upper(left), lower(right));
955}
956
957
958//==============================================================================
959//= Size
960//==============================================================================
961//- cardinality ----------------------------------------------------------------
962
963template<class Type>
964typename boost::enable_if<is_continuous_interval<Type>,
965 typename size_type_of<interval_traits<Type> >::type>::type
966cardinality(const Type& object)
967{
968 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
969 if(icl::is_empty(object))
970 return icl::identity_element<SizeT>::value();
971 else if( object.bounds() == interval_bounds::closed()
972 && domain_equal<Type>(lower(object), upper(object)))
973 return icl::unit_element<SizeT>::value();
974 else
975 return icl::infinity<SizeT>::value();
976}
977
978template<class Type>
979typename boost::enable_if<is_discrete_interval<Type>,
980 typename size_type_of<interval_traits<Type> >::type>::type
981cardinality(const Type& object)
982{
983 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
984 return icl::is_empty(object) ? identity_element<SizeT>::value()
985 : static_cast<SizeT>(last_next(object) - first(object));
986}
987
988template<class Type>
989typename boost::enable_if<is_continuous_asymmetric<Type>,
990 typename size_type_of<interval_traits<Type> >::type>::type
991cardinality(const Type& object)
992{
993 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
994 if(icl::is_empty(object))
995 return icl::identity_element<SizeT>::value();
996 else
997 return icl::infinity<SizeT>::value();
998}
999
1000template<class Type>
1001typename boost::enable_if<is_discrete_asymmetric<Type>,
1002 typename size_type_of<interval_traits<Type> >::type>::type
1003cardinality(const Type& object)
1004{
1005 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1006 return icl::is_empty(object) ? identity_element<SizeT>::value()
1007 : static_cast<SizeT>(last_next(object) - first(object));
1008}
1009
1010template<class Type>
1011typename boost::enable_if<has_symmetric_bounds<Type>,
1012 typename size_type_of<interval_traits<Type> >::type>::type
1013cardinality(const Type& object)
1014{
1015 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1016 return icl::is_empty(object) ? identity_element<SizeT>::value()
1017 : static_cast<SizeT>(last_next(object) - first(object));
1018}
1019
1020
1021
1022//- size -----------------------------------------------------------------------
1023template<class Type>
1024inline typename enable_if<is_interval<Type>,
1025 typename size_type_of<interval_traits<Type> >::type>::type
1026size(const Type& object)
1027{
1028 return cardinality(object);
1029}
1030
1031//- length ---------------------------------------------------------------------
1032template<class Type>
1033inline typename boost::enable_if<is_continuous_interval<Type>,
1034 typename difference_type_of<interval_traits<Type> >::type>::type
1035length(const Type& object)
1036{
1037 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1038 return icl::is_empty(object) ? identity_element<DiffT>::value()
1039 : upper(object) - lower(object);
1040}
1041
1042template<class Type>
1043inline typename boost::enable_if<is_discrete_interval<Type>,
1044 typename difference_type_of<interval_traits<Type> >::type>::type
1045length(const Type& object)
1046{
1047 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1048 return icl::is_empty(object) ? identity_element<DiffT>::value()
1049 : last_next(object) - first(object);
1050}
1051
1052template<class Type>
1053typename boost::enable_if<is_continuous_asymmetric<Type>,
1054 typename difference_type_of<interval_traits<Type> >::type>::type
1055length(const Type& object)
1056{
1057 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1058 return icl::is_empty(object) ? identity_element<DiffT>::value()
1059 : upper(object) - lower(object);
1060}
1061
1062template<class Type>
1063inline typename boost::enable_if<is_discrete_static<Type>,
1064 typename difference_type_of<interval_traits<Type> >::type>::type
1065length(const Type& object)
1066{
1067 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1068 return icl::is_empty(object) ? identity_element<DiffT>::value()
1069 : last_next(object) - first(object);
1070}
1071
1072//- iterative_size -------------------------------------------------------------
1073template<class Type>
1074inline typename enable_if<is_interval<Type>,
1075 typename size_type_of<interval_traits<Type> >::type>::type
1076iterative_size(const Type&)
1077{
1078 return 2;
1079}
1080
1081
1082//==============================================================================
1083//= Addition
1084//==============================================================================
1085//- hull -----------------------------------------------------------------------
1086/** \c hull returns the smallest interval containing \c left and \c right. */
1087template<class Type>
1088typename boost::enable_if<has_static_bounds<Type>, Type>::type
1089hull(Type left, const Type& right)
1090{
1091 typedef typename interval_traits<Type>::domain_compare domain_compare;
1092
1093 if(icl::is_empty(right))
1094 return left;
1095 else if(icl::is_empty(left))
1096 return right;
1097
1098 return
1099 construct<Type>
1100 (
1101 (std::min)(lower(left), lower(right), domain_compare()),
1102 (std::max)(upper(left), upper(right), domain_compare())
1103 );
1104}
1105
1106template<class Type>
1107typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1108hull(Type left, const Type& right)
1109{
1110 if(icl::is_empty(right))
1111 return left;
1112 else if(icl::is_empty(left))
1113 return right;
1114
1115 return dynamic_interval_traits<Type>::construct_bounded
1116 (
1117 lower_min(left, right),
1118 upper_max(left, right)
1119 );
1120}
1121
1122//==============================================================================
1123//= Subtraction
1124//==============================================================================
1125//- left_subtract --------------------------------------------------------------
1126/** subtract \c left_minuend from the \c right interval on it's left side.
1127 Return the difference: The part of \c right right of \c left_minuend.
1128\code
1129right_over = right - left_minuend; //on the left.
1130... d) : right
1131... c) : left_minuend
1132 [c d) : right_over
1133\endcode
1134*/
1135template<class Type>
1136typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1137left_subtract(Type right, const Type& left_minuend)
1138{
1139 if(exclusive_less(left_minuend, right))
1140 return right;
1141
1142 return construct<Type>(upper(left_minuend), upper(right));
1143}
1144
1145template<class Type>
1146typename boost::enable_if<is_static_closed<Type>, Type>::type
1147left_subtract(Type right, const Type& left_minuend)
1148{
1149 if(exclusive_less(left_minuend, right))
1150 return right;
1151 else if(upper_less_equal(right, left_minuend))
1152 return identity_element<Type>::value();
1153
1154 return construct<Type>(domain_next<Type>(upper(left_minuend)), upper(right));
1155}
1156
1157template<class Type>
1158typename boost::enable_if<is_static_open<Type>, Type>::type
1159left_subtract(Type right, const Type& left_minuend)
1160{
1161 if(exclusive_less(left_minuend, right))
1162 return right;
1163
1164 return construct<Type>(domain_prior<Type>(upper(left_minuend)), upper(right));
1165}
1166
1167template<class Type>
1168typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1169left_subtract(Type right, const Type& left_minuend)
1170{
1171 if(exclusive_less(left_minuend, right))
1172 return right;
1173 return dynamic_interval_traits<Type>::construct_bounded
1174 ( reverse_bounded_upper(left_minuend), bounded_upper(right) );
1175}
1176
1177
1178//- right_subtract -------------------------------------------------------------
1179/** subtract \c right_minuend from the \c left interval on it's right side.
1180 Return the difference: The part of \c left left of \c right_minuend.
1181\code
1182left_over = left - right_minuend; //on the right side.
1183[a ... : left
1184 [b ... : right_minuend
1185[a b) : left_over
1186\endcode
1187*/
1188template<class Type>
1189typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1190right_subtract(Type left, const Type& right_minuend)
1191{
1192 if(exclusive_less(left, right_minuend))
1193 return left;
1194 return construct<Type>(lower(left), lower(right_minuend));
1195}
1196
1197template<class Type>
1198typename boost::enable_if<is_static_closed<Type>, Type>::type
1199right_subtract(Type left, const Type& right_minuend)
1200{
1201 if(exclusive_less(left, right_minuend))
1202 return left;
1203 else if(lower_less_equal(right_minuend, left))
1204 return identity_element<Type>::value();
1205
1206 return construct<Type>(lower(left), domain_prior<Type>(lower(right_minuend)));
1207}
1208
1209template<class Type>
1210typename boost::enable_if<is_static_open<Type>, Type>::type
1211right_subtract(Type left, const Type& right_minuend)
1212{
1213 if(exclusive_less(left, right_minuend))
1214 return left;
1215
1216 return construct<Type>(lower(left), domain_next<Type>(lower(right_minuend)));
1217}
1218
1219template<class Type>
1220typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1221right_subtract(Type left, const Type& right_minuend)
1222{
1223 if(exclusive_less(left, right_minuend))
1224 return left;
1225
1226 return dynamic_interval_traits<Type>::construct_bounded
1227 ( bounded_lower(left), reverse_bounded_lower(right_minuend) );
1228}
1229
1230//==============================================================================
1231//= Intersection
1232//==============================================================================
1233//- operator & -----------------------------------------------------------------
1234/** Returns the intersection of \c left and \c right interval. */
1235template<class Type>
1236typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1237operator & (Type left, const Type& right)
1238{
1239 typedef typename interval_traits<Type>::domain_compare domain_compare;
1240
1241 if(icl::is_empty(left) || icl::is_empty(right))
1242 return identity_element<Type>::value();
1243 else
1244 return
1245 construct<Type>
1246 (
1247 (std::max)(icl::lower(left), icl::lower(right), domain_compare()),
1248 (std::min)(icl::upper(left), icl::upper(right), domain_compare())
1249 );
1250}
1251
1252template<class Type>
1253typename boost::enable_if<has_symmetric_bounds<Type>, Type>::type
1254operator & (Type left, const Type& right)
1255{
1256 typedef typename interval_traits<Type>::domain_compare domain_compare;
1257
1258 if(icl::is_empty(left) || icl::is_empty(right))
1259 return identity_element<Type>::value();
1260 else
1261 return
1262 construct<Type>
1263 (
1264 (std::max)(icl::lower(left), icl::lower(right), domain_compare()),
1265 (std::min)(icl::upper(left), icl::upper(right), domain_compare())
1266 );
1267}
1268
1269template<class Type>
1270typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1271operator & (Type left, const Type& right)
1272{
1273 if(icl::is_empty(left) || icl::is_empty(right))
1274 return identity_element<Type>::value();
1275 else
1276 return dynamic_interval_traits<Type>::construct_bounded
1277 (
1278 lower_max(left, right),
1279 upper_min(left, right)
1280 );
1281}
1282
1283
1284//- intersects -----------------------------------------------------------------
1285template<class Type>
1286typename boost::enable_if<is_interval<Type>, bool>::type
1287intersects(const Type& left, const Type& right)
1288{
1289 return !( icl::is_empty(left) || icl::is_empty(right)
1290 || exclusive_less(left,right) || exclusive_less(right,left));
1291}
1292
1293//- disjoint -------------------------------------------------------------------
1294template<class Type>
1295typename boost::enable_if<is_interval<Type>, bool>::type
1296disjoint(const Type& left, const Type& right)
1297{
1298 return icl::is_empty(left) || icl::is_empty(right)
1299 || exclusive_less(left,right) || exclusive_less(right,left);
1300}
1301
1302//==============================================================================
1303//= Complement
1304//==============================================================================
1305
1306template<class Type>
1307typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1308inner_complement(const Type& left, const Type& right)
1309{
1310 if(icl::is_empty(left) || icl::is_empty(right))
1311 return identity_element<Type>::value();
1312 else if(exclusive_less(left, right))
1313 return construct<Type>(upper(left), lower(right));
1314 else if(exclusive_less(right, left))
1315 return construct<Type>(upper(right), lower(left));
1316 else
1317 return identity_element<Type>::value();
1318}
1319
1320template<class Type>
1321typename boost::enable_if<is_discrete_static_closed<Type>, Type>::type
1322inner_complement(const Type& left, const Type& right)
1323{
1324 if(icl::is_empty(left) || icl::is_empty(right))
1325 return identity_element<Type>::value();
1326 else if(exclusive_less(left, right))
1327 return construct<Type>(domain_next<Type>(upper(left)), domain_prior<Type>(lower(right)));
1328 else if(exclusive_less(right, left))
1329 return construct<Type>(domain_next<Type>(upper(right)), domain_prior<Type>(lower(left)));
1330 else
1331 return identity_element<Type>::value();
1332}
1333
1334template<class Type>
1335typename boost::enable_if<is_discrete_static_open<Type>, Type>::type
1336inner_complement(const Type& left, const Type& right)
1337{
1338 if(icl::is_empty(left) || icl::is_empty(right))
1339 return identity_element<Type>::value();
1340 else if(exclusive_less(left, right))
1341 return construct<Type>(last(left), first(right));
1342 else if(exclusive_less(right, left))
1343 return construct<Type>(last(right), first(left));
1344 else
1345 return identity_element<Type>::value();
1346}
1347
1348template<class Type>
1349typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1350inner_complement(const Type& left, const Type& right)
1351{
1352 if(icl::is_empty(left) || icl::is_empty(right))
1353 return identity_element<Type>::value();
1354 else if(exclusive_less(left, right))
1355 return right_subtract(left_subtract(hull(left, right), left), right);
1356 else if(exclusive_less(right, left))
1357 return right_subtract(left_subtract(hull(right, left), right), left);
1358 else
1359 return identity_element<Type>::value();
1360}
1361
1362template<class Type>
1363inline typename boost::enable_if<is_interval<Type>, Type>::type
1364between(const Type& left, const Type& right)
1365{
1366 return inner_complement(left, right);
1367}
1368
1369
1370
1371//==============================================================================
1372//= Distance
1373//==============================================================================
1374template<class Type>
1375typename boost::
1376enable_if< mpl::and_< is_interval<Type>
1377 , has_difference<typename interval_traits<Type>::domain_type>
1378 , is_discrete<typename interval_traits<Type>::domain_type>
1379 >
1380 , typename difference_type_of<interval_traits<Type> >::type>::type
1381distance(const Type& x1, const Type& x2)
1382{
1383 typedef typename difference_type_of<interval_traits<Type> >::type difference_type;
1384
1385 if(icl::is_empty(x1) || icl::is_empty(x2))
1386 return icl::identity_element<difference_type>::value();
1387 else if(domain_less<Type>(last(x1), first(x2)))
1388 return static_cast<difference_type>(icl::pred(first(x2) - last(x1)));
1389 else if(domain_less<Type>(last(x2), first(x1)))
1390 return static_cast<difference_type>(icl::pred(first(x1) - last(x2)));
1391 else
1392 return icl::identity_element<difference_type>::value();
1393}
1394
1395template<class Type>
1396typename boost::
1397enable_if< mpl::and_< is_interval<Type>
1398 , has_difference<typename interval_traits<Type>::domain_type>
1399 , is_continuous<typename interval_traits<Type>::domain_type>
1400 >
1401 , typename difference_type_of<interval_traits<Type> >::type>::type
1402distance(const Type& x1, const Type& x2)
1403{
1404 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1405
1406 if(icl::is_empty(x1) || icl::is_empty(x2))
1407 return icl::identity_element<DiffT>::value();
1408 else if(domain_less<Type>(upper(x1), lower(x2)))
1409 return lower(x2) - upper(x1);
1410 else if(domain_less<Type>(upper(x2), lower(x1)))
1411 return lower(x1) - upper(x2);
1412 else
1413 return icl::identity_element<DiffT>::value();
1414}
1415
1416//==============================================================================
1417//= Streaming, representation
1418//==============================================================================
1419template<class Type>
1420typename boost::
1421 enable_if< mpl::or_< is_static_left_open<Type>
1422 , is_static_open<Type> >, std::string>::type
1423left_bracket(const Type&) { return "("; }
1424
1425template<class Type>
1426typename boost::
1427 enable_if< mpl::or_< is_static_right_open<Type>
1428 , is_static_closed<Type> >, std::string>::type
1429left_bracket(const Type&) { return "["; }
1430
1431template<class Type>
1432typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type
1433left_bracket(const Type& object)
1434{
1435 return left_bracket(object.bounds());
1436}
1437
1438//------------------------------------------------------------------------------
1439template<class Type>
1440typename boost::
1441 enable_if< mpl::or_< is_static_right_open<Type>
1442 , is_static_open<Type> >, std::string>::type
1443right_bracket(const Type&) { return ")"; }
1444
1445template<class Type>
1446typename boost::
1447 enable_if< mpl::or_< is_static_left_open<Type>
1448 , is_static_closed<Type> >, std::string>::type
1449right_bracket(const Type&) { return "]"; }
1450
1451template<class Type>
1452typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type
1453right_bracket(const Type& object)
1454{
1455 return right_bracket(object.bounds());
1456}
1457
1458//------------------------------------------------------------------------------
1459template<class CharType, class CharTraits, class Type>
1460typename boost::enable_if<is_interval<Type>,
1461 std::basic_ostream<CharType, CharTraits> >::type&
1462operator << (std::basic_ostream<CharType, CharTraits> &stream, Type const& object)
1463{
1464 if(boost::icl::is_empty(object))
1465 return stream << left_bracket<Type>(object) << right_bracket<Type>(object);
1466 else
1467 return stream << left_bracket<Type>(object)
1468 << interval_traits<Type>::lower(object)
1469 << ","
1470 << interval_traits<Type>::upper(object)
1471 << right_bracket<Type>(object) ;
1472}
1473
1474}} // namespace icl boost
1475
1476#endif
1477