File indexing completed on 2024-11-15 09:14:05
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ICL_CONCEPT_INTERVAL_HPP_JOFA_100323
0009 #define BOOST_ICL_CONCEPT_INTERVAL_HPP_JOFA_100323
0010
0011 #include <boost/assert.hpp>
0012 #include <boost/core/ignore_unused.hpp>
0013 #include <boost/utility/enable_if.hpp>
0014 #include <boost/mpl/and.hpp>
0015 #include <boost/mpl/or.hpp>
0016 #include <boost/mpl/not.hpp>
0017 #include <boost/icl/detail/design_config.hpp>
0018 #include <boost/icl/type_traits/unit_element.hpp>
0019 #include <boost/icl/type_traits/identity_element.hpp>
0020 #include <boost/icl/type_traits/infinity.hpp>
0021 #include <boost/icl/type_traits/succ_pred.hpp>
0022 #include <boost/icl/type_traits/is_numeric.hpp>
0023 #include <boost/icl/type_traits/is_discrete.hpp>
0024 #include <boost/icl/type_traits/is_continuous.hpp>
0025 #include <boost/icl/type_traits/is_asymmetric_interval.hpp>
0026 #include <boost/icl/type_traits/is_discrete_interval.hpp>
0027 #include <boost/icl/type_traits/is_continuous_interval.hpp>
0028
0029 #include <boost/icl/concept/interval_bounds.hpp>
0030 #include <boost/icl/interval_traits.hpp>
0031 #include <boost/icl/dynamic_interval_traits.hpp>
0032
0033 #include <algorithm>
0034
0035 namespace boost{namespace icl
0036 {
0037
0038
0039
0040
0041 template<class Type>
0042 inline typename enable_if<is_interval<Type>, bool>::type
0043 domain_less(const typename interval_traits<Type>::domain_type& left,
0044 const typename interval_traits<Type>::domain_type& right)
0045 {
0046 return typename interval_traits<Type>::domain_compare()(left, right);
0047 }
0048
0049 template<class Type>
0050 inline typename enable_if<is_interval<Type>, bool>::type
0051 domain_less_equal(const typename interval_traits<Type>::domain_type& left,
0052 const typename interval_traits<Type>::domain_type& right)
0053 {
0054 return !(typename interval_traits<Type>::domain_compare()(right, left));
0055 }
0056
0057 template<class Type>
0058 inline typename enable_if<is_interval<Type>, bool>::type
0059 domain_equal(const typename interval_traits<Type>::domain_type& left,
0060 const typename interval_traits<Type>::domain_type& right)
0061 {
0062 typedef typename interval_traits<Type>::domain_compare domain_compare;
0063 return !(domain_compare()(left, right)) && !(domain_compare()(right, left));
0064 }
0065
0066 template<class Type>
0067 inline typename enable_if< is_interval<Type>
0068 , typename interval_traits<Type>::domain_type>::type
0069 domain_next(const typename interval_traits<Type>::domain_type value)
0070 {
0071 typedef typename interval_traits<Type>::domain_type domain_type;
0072 typedef typename interval_traits<Type>::domain_compare domain_compare;
0073 return icl::successor<domain_type,domain_compare>::apply(value);
0074 }
0075
0076 template<class Type>
0077 inline typename enable_if< is_interval<Type>
0078 , typename interval_traits<Type>::domain_type>::type
0079 domain_prior(const typename interval_traits<Type>::domain_type value)
0080 {
0081 typedef typename interval_traits<Type>::domain_type domain_type;
0082 typedef typename interval_traits<Type>::domain_compare domain_compare;
0083 return icl::predecessor<domain_type,domain_compare>::apply(value);
0084 }
0085
0086
0087
0088
0089 template<class Type>
0090 typename enable_if
0091 <
0092 mpl::and_< is_static_right_open<Type>
0093 , is_discrete<typename interval_traits<Type>::domain_type> >
0094 , Type
0095 >::type
0096 singleton(const typename interval_traits<Type>::domain_type& value)
0097 {
0098
0099 return interval_traits<Type>::construct(value, domain_next<Type>(value));
0100 }
0101
0102 template<class Type>
0103 typename enable_if
0104 <
0105 mpl::and_< is_static_left_open<Type>
0106 , is_discrete<typename interval_traits<Type>::domain_type> >
0107 , Type
0108 >::type
0109 singleton(const typename interval_traits<Type>::domain_type& value)
0110 {
0111
0112 typedef typename interval_traits<Type>::domain_type domain_type;
0113 typedef typename interval_traits<Type>::domain_compare domain_compare;
0114 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0115 ::is_less_than(value) ));
0116 boost::ignore_unused<domain_type, domain_compare>();
0117
0118 return interval_traits<Type>::construct(domain_prior<Type>(value), value);
0119 }
0120
0121 template<class Type>
0122 typename enable_if<is_discrete_static_open<Type>, Type>::type
0123 singleton(const typename interval_traits<Type>::domain_type& value)
0124 {
0125
0126 typedef typename interval_traits<Type>::domain_type domain_type;
0127 typedef typename interval_traits<Type>::domain_compare domain_compare;
0128 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0129 ::is_less_than(value)));
0130 boost::ignore_unused<domain_type, domain_compare>();
0131
0132 return interval_traits<Type>::construct( domain_prior<Type>(value)
0133 , domain_next<Type>(value));
0134 }
0135
0136 template<class Type>
0137 typename enable_if<is_discrete_static_closed<Type>, Type>::type
0138 singleton(const typename interval_traits<Type>::domain_type& value)
0139 {
0140
0141 return interval_traits<Type>::construct(value, value);
0142 }
0143
0144 template<class Type>
0145 typename enable_if<has_dynamic_bounds<Type>, Type>::type
0146 singleton(const typename interval_traits<Type>::domain_type& value)
0147 {
0148 return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed());
0149 }
0150
0151 namespace detail
0152 {
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 template<class Type>
0163 typename enable_if
0164 <
0165 mpl::and_< is_static_right_open<Type>
0166 , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> >
0167 , Type
0168 >::type
0169 unit_trail(const typename interval_traits<Type>::domain_type& value)
0170 {
0171 return interval_traits<Type>::construct(value, domain_next<Type>(value));
0172 }
0173
0174 template<class Type>
0175 typename enable_if
0176 <
0177 mpl::and_< is_static_left_open<Type>
0178 , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> >
0179 , Type
0180 >::type
0181 unit_trail(const typename interval_traits<Type>::domain_type& value)
0182 {
0183 typedef typename interval_traits<Type>::domain_type domain_type;
0184 typedef typename interval_traits<Type>::domain_compare domain_compare;
0185 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0186 ::is_less_than(value) ));
0187 boost::ignore_unused<domain_type, domain_compare>();
0188
0189 return interval_traits<Type>::construct(domain_prior<Type>(value), value);
0190 }
0191
0192 template<class Type>
0193 typename enable_if
0194 <
0195 mpl::and_< is_static_open<Type>
0196 , is_discrete<typename interval_traits<Type>::domain_type> >
0197 , Type
0198 >::type
0199 unit_trail(const typename interval_traits<Type>::domain_type& value)
0200 {
0201 typedef typename interval_traits<Type>::domain_type domain_type;
0202 typedef typename interval_traits<Type>::domain_compare domain_compare;
0203 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0204 ::is_less_than(value)));
0205 boost::ignore_unused<domain_type, domain_compare>();
0206
0207 return interval_traits<Type>::construct( domain_prior<Type>(value)
0208 , domain_next<Type>(value));
0209 }
0210
0211 template<class Type>
0212 typename enable_if
0213 <
0214 mpl::and_< is_static_closed<Type>
0215 , is_discrete<typename interval_traits<Type>::domain_type> >
0216 , Type
0217 >::type
0218 unit_trail(const typename interval_traits<Type>::domain_type& value)
0219 {
0220 return interval_traits<Type>::construct(value, value);
0221 }
0222
0223
0224
0225
0226
0227
0228 template<class Type>
0229 typename enable_if<has_dynamic_bounds<Type>, Type>::type
0230 unit_trail(const typename interval_traits<Type>::domain_type& value)
0231 {
0232 return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed());
0233 }
0234
0235 }
0236
0237
0238
0239
0240 template<class Type>
0241 typename enable_if<has_static_bounds<Type>, Type>::type
0242 construct(const typename interval_traits<Type>::domain_type& low,
0243 const typename interval_traits<Type>::domain_type& up )
0244 {
0245 return interval_traits<Type>::construct(low, up);
0246 }
0247
0248 template<class Type>
0249 typename enable_if<has_dynamic_bounds<Type>, Type>::type
0250 construct(const typename interval_traits<Type>::domain_type& low,
0251 const typename interval_traits<Type>::domain_type& up,
0252 interval_bounds bounds = interval_bounds::right_open())
0253 {
0254 return dynamic_interval_traits<Type>::construct(low, up, bounds);
0255 }
0256
0257
0258
0259 template<class Type>
0260 typename enable_if<has_dynamic_bounds<Type>, Type>::type
0261 construct(const typename Type::bounded_domain_type& low,
0262 const typename Type::bounded_domain_type& up)
0263 {
0264 return dynamic_interval_traits<Type>::construct_bounded(low, up);
0265 }
0266
0267 template<class Type>
0268 typename enable_if<is_interval<Type>, Type>::type
0269 span(const typename interval_traits<Type>::domain_type& left,
0270 const typename interval_traits<Type>::domain_type& right)
0271 {
0272 typedef typename interval_traits<Type>::domain_compare domain_compare;
0273 if(domain_compare()(left,right))
0274 return construct<Type>(left, right);
0275 else
0276 return construct<Type>(right, left);
0277 }
0278
0279
0280
0281 template<class Type>
0282 typename enable_if<is_static_right_open<Type>, Type>::type
0283 hull(const typename interval_traits<Type>::domain_type& left,
0284 const typename interval_traits<Type>::domain_type& right)
0285 {
0286 typedef typename interval_traits<Type>::domain_compare domain_compare;
0287 if(domain_compare()(left,right))
0288 return construct<Type>(left, domain_next<Type>(right));
0289 else
0290 return construct<Type>(right, domain_next<Type>(left));
0291 }
0292
0293 template<class Type>
0294 typename enable_if<is_static_left_open<Type>, Type>::type
0295 hull(const typename interval_traits<Type>::domain_type& left,
0296 const typename interval_traits<Type>::domain_type& right)
0297 {
0298 typedef typename interval_traits<Type>::domain_type domain_type;
0299 typedef typename interval_traits<Type>::domain_compare domain_compare;
0300 boost::ignore_unused<domain_type>();
0301
0302 if(domain_compare()(left,right))
0303 {
0304 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0305 ::is_less_than(left) ));
0306 return construct<Type>(domain_prior<Type>(left), right);
0307 }
0308 else
0309 {
0310 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0311 ::is_less_than(right) ));
0312 return construct<Type>(domain_prior<Type>(right), left);
0313 }
0314 }
0315
0316 template<class Type>
0317 typename enable_if<is_static_closed<Type>, Type>::type
0318 hull(const typename interval_traits<Type>::domain_type& left,
0319 const typename interval_traits<Type>::domain_type& right)
0320 {
0321 typedef typename interval_traits<Type>::domain_compare domain_compare;
0322 if(domain_compare()(left,right))
0323 return construct<Type>(left, right);
0324 else
0325 return construct<Type>(right, left);
0326 }
0327
0328 template<class Type>
0329 typename enable_if<is_static_open<Type>, Type>::type
0330 hull(const typename interval_traits<Type>::domain_type& left,
0331 const typename interval_traits<Type>::domain_type& right)
0332 {
0333 typedef typename interval_traits<Type>::domain_type domain_type;
0334 typedef typename interval_traits<Type>::domain_compare domain_compare;
0335 boost::ignore_unused<domain_type>();
0336
0337 if(domain_compare()(left,right))
0338 {
0339 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0340 ::is_less_than(left) ));
0341 return construct<Type>( domain_prior<Type>(left)
0342 , domain_next<Type>(right));
0343 }
0344 else
0345 {
0346 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0347 ::is_less_than(right) ));
0348 return construct<Type>( domain_prior<Type>(right)
0349 , domain_next<Type>(left));
0350 }
0351 }
0352
0353 template<class Type>
0354 typename enable_if<has_dynamic_bounds<Type>, Type>::type
0355 hull(const typename interval_traits<Type>::domain_type& left,
0356 const typename interval_traits<Type>::domain_type& right)
0357 {
0358 typedef typename interval_traits<Type>::domain_compare domain_compare;
0359 if(domain_compare()(left,right))
0360 return construct<Type>(left, right, interval_bounds::closed());
0361 else
0362 return construct<Type>(right, left, interval_bounds::closed());
0363 }
0364
0365
0366
0367
0368
0369 template<class Type>
0370 inline typename enable_if<is_interval<Type>,
0371 typename interval_traits<Type>::domain_type>::type
0372 lower(const Type& object)
0373 {
0374 return interval_traits<Type>::lower(object);
0375 }
0376
0377 template<class Type>
0378 inline typename enable_if<is_interval<Type>,
0379 typename interval_traits<Type>::domain_type>::type
0380 upper(const Type& object)
0381 {
0382 return interval_traits<Type>::upper(object);
0383 }
0384
0385
0386
0387 template<class Type>
0388 inline typename
0389 enable_if< mpl::or_<is_static_right_open<Type>, is_static_closed<Type> >
0390 , typename interval_traits<Type>::domain_type>::type
0391 first(const Type& object)
0392 {
0393 return lower(object);
0394 }
0395
0396 template<class Type>
0397 inline typename
0398 enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_open<Type> >
0399 , is_discrete<typename interval_traits<Type>::domain_type> >
0400 , typename interval_traits<Type>::domain_type>::type
0401 first(const Type& object)
0402 {
0403 return domain_next<Type>(lower(object));
0404 }
0405
0406 template<class Type>
0407 inline typename enable_if<is_discrete_interval<Type>,
0408 typename interval_traits<Type>::domain_type>::type
0409 first(const Type& object)
0410 {
0411 return is_left_closed(object.bounds()) ?
0412 lower(object) :
0413 domain_next<Type>(lower(object));
0414 }
0415
0416
0417 template<class Type>
0418 inline typename
0419 enable_if< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> >
0420 , typename interval_traits<Type>::domain_type>::type
0421 last(const Type& object)
0422 {
0423 return upper(object);
0424 }
0425
0426 template<class Type>
0427 inline typename
0428 enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> >
0429 , is_discrete<typename interval_traits<Type>::domain_type> >
0430 , typename interval_traits<Type>::domain_type>::type
0431 last(const Type& object)
0432 {
0433 typedef typename interval_traits<Type>::domain_type domain_type;
0434 typedef typename interval_traits<Type>::domain_compare domain_compare;
0435 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0436 ::is_less_than(upper(object)) ));
0437 boost::ignore_unused<domain_type, domain_compare>();
0438
0439 return domain_prior<Type>(upper(object));
0440 }
0441
0442 template<class Type>
0443 inline typename enable_if<is_discrete_interval<Type>,
0444 typename interval_traits<Type>::domain_type>::type
0445 last(const Type& object)
0446 {
0447 typedef typename interval_traits<Type>::domain_type domain_type;
0448 typedef typename interval_traits<Type>::domain_compare domain_compare;
0449 BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value>
0450 ::is_less_than_or(upper(object), is_right_closed(object.bounds())) ));
0451 boost::ignore_unused<domain_type, domain_compare>();
0452
0453 return is_right_closed(object.bounds()) ?
0454 upper(object) :
0455 domain_prior<Type>(upper(object));
0456 }
0457
0458
0459 template<class Type>
0460 inline typename
0461 enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> >
0462 , is_discrete<typename interval_traits<Type>::domain_type> >
0463 , typename interval_traits<Type>::domain_type>::type
0464 last_next(const Type& object)
0465 {
0466 return domain_next<Type>(upper(object));
0467 }
0468
0469 template<class Type>
0470 inline typename
0471 enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> >
0472 , is_discrete<typename interval_traits<Type>::domain_type> >
0473 , typename interval_traits<Type>::domain_type>::type
0474 last_next(const Type& object)
0475 {
0476
0477 return upper(object);
0478 }
0479
0480 template<class Type>
0481 inline typename enable_if<is_discrete_interval<Type>,
0482 typename interval_traits<Type>::domain_type>::type
0483 last_next(const Type& object)
0484 {
0485 return is_right_closed(object.bounds()) ?
0486 domain_next<Type>(upper(object)):
0487 upper(object) ;
0488 }
0489
0490
0491 template<class Type>
0492 typename enable_if<has_dynamic_bounds<Type>,
0493 typename Type::bounded_domain_type>::type
0494 bounded_lower(const Type& object)
0495 {
0496 return typename
0497 Type::bounded_domain_type(lower(object), object.bounds().left());
0498 }
0499
0500 template<class Type>
0501 typename enable_if<has_dynamic_bounds<Type>,
0502 typename Type::bounded_domain_type>::type
0503 reverse_bounded_lower(const Type& object)
0504 {
0505 return typename
0506 Type::bounded_domain_type(lower(object),
0507 object.bounds().reverse_left());
0508 }
0509
0510 template<class Type>
0511 typename enable_if<has_dynamic_bounds<Type>,
0512 typename Type::bounded_domain_type>::type
0513 bounded_upper(const Type& object)
0514 {
0515 return typename
0516 Type::bounded_domain_type(upper(object),
0517 object.bounds().right());
0518 }
0519
0520 template<class Type>
0521 typename enable_if<has_dynamic_bounds<Type>,
0522 typename Type::bounded_domain_type>::type
0523 reverse_bounded_upper(const Type& object)
0524 {
0525 return typename
0526 Type::bounded_domain_type(upper(object),
0527 object.bounds().reverse_right());
0528 }
0529
0530
0531 template<class Type>
0532 inline typename enable_if<has_dynamic_bounds<Type>, interval_bounds>::type
0533 bounds(const Type& object)
0534 {
0535 return object.bounds();
0536 }
0537
0538 template<class Type>
0539 inline typename enable_if<has_static_bounds<Type>, interval_bounds>::type
0540 bounds(const Type&)
0541 {
0542 return interval_bounds(interval_bound_type<Type>::value);
0543 }
0544
0545
0546
0547
0548
0549
0550 template<class Type>
0551 typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0552 is_empty(const Type& object)
0553 {
0554 return domain_less_equal<Type>(upper(object), lower(object));
0555 }
0556
0557 template<class Type>
0558 typename boost::enable_if<is_static_closed<Type>, bool>::type
0559 is_empty(const Type& object)
0560 {
0561 return domain_less<Type>(upper(object), lower(object));
0562 }
0563
0564 template<class Type>
0565 typename boost::enable_if<is_static_open<Type>, bool>::type
0566 is_empty(const Type& object)
0567 {
0568 return domain_less_equal<Type>(upper(object), lower(object) )
0569 || domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object)));
0570 }
0571
0572 template<class Type>
0573 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0574 is_empty(const Type& object)
0575 {
0576 if(object.bounds() == interval_bounds::closed())
0577 return domain_less<Type>(upper(object), lower(object));
0578 else if(object.bounds() == interval_bounds::open())
0579 return domain_less_equal<Type>(upper(object), lower(object) )
0580 || domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object)));
0581 else
0582 return domain_less_equal<Type>(upper(object), lower(object));
0583 }
0584
0585 template<class Type>
0586 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0587 is_empty(const Type& object)
0588 {
0589 return domain_less<Type>(upper(object), lower(object))
0590 || ( domain_equal<Type>(upper(object), lower(object))
0591 && object.bounds() != interval_bounds::closed() );
0592 }
0593
0594
0595
0596
0597
0598
0599
0600 template<class Type>
0601 inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0602 exclusive_less(const Type& left, const Type& right)
0603 {
0604 return icl::is_empty(left) || icl::is_empty(right)
0605 || domain_less_equal<Type>(upper(left), lower(right));
0606 }
0607
0608 template<class Type>
0609 inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0610 exclusive_less(const Type& left, const Type& right)
0611 {
0612 return icl::is_empty(left) || icl::is_empty(right)
0613 || domain_less<Type>(last(left), first(right));
0614 }
0615
0616 template<class Type>
0617 inline typename boost::
0618 enable_if<has_symmetric_bounds<Type>, bool>::type
0619 exclusive_less(const Type& left, const Type& right)
0620 {
0621 return icl::is_empty(left) || icl::is_empty(right)
0622 || domain_less<Type>(last(left), first(right));
0623 }
0624
0625 template<class Type>
0626 inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0627 exclusive_less(const Type& left, const Type& right)
0628 {
0629 return icl::is_empty(left) || icl::is_empty(right)
0630 || domain_less<Type>(upper(left), lower(right))
0631 || ( domain_equal<Type>(upper(left), lower(right))
0632 && inner_bounds(left,right) != interval_bounds::open() );
0633 }
0634
0635
0636
0637 template<class Type>
0638 typename boost::enable_if<has_static_bounds<Type>, bool>::type
0639 lower_less(const Type& left, const Type& right)
0640 {
0641 return domain_less<Type>(lower(left), lower(right));
0642 }
0643
0644 template<class Type>
0645 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0646 lower_less(const Type& left, const Type& right)
0647 {
0648 return domain_less<Type>(first(left), first(right));
0649 }
0650
0651 template<class Type>
0652 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0653 lower_less(const Type& left, const Type& right)
0654 {
0655 if(left_bounds(left,right) == interval_bounds::right_open())
0656 return domain_less_equal<Type>(lower(left), lower(right));
0657 else
0658 return domain_less<Type>(lower(left), lower(right));
0659 }
0660
0661
0662
0663 template<class Type>
0664 typename boost::enable_if<has_static_bounds<Type>, bool>::type
0665 upper_less(const Type& left, const Type& right)
0666 {
0667 return domain_less<Type>(upper(left), upper(right));
0668 }
0669
0670 template<class Type>
0671 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0672 upper_less(const Type& left, const Type& right)
0673 {
0674 return domain_less<Type>(last(left), last(right));
0675 }
0676
0677 template<class Type>
0678 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0679 upper_less(const Type& left, const Type& right)
0680 {
0681 if(right_bounds(left,right) == interval_bounds::left_open())
0682 return domain_less_equal<Type>(upper(left), upper(right));
0683 else
0684 return domain_less<Type>(upper(left), upper(right));
0685 }
0686
0687
0688 template<class Type>
0689 typename boost::enable_if<has_dynamic_bounds<Type>,
0690 typename Type::bounded_domain_type >::type
0691 lower_min(const Type& left, const Type& right)
0692 {
0693 return lower_less(left, right) ? bounded_lower(left) : bounded_lower(right);
0694 }
0695
0696
0697 template<class Type>
0698 typename boost::enable_if<has_dynamic_bounds<Type>,
0699 typename Type::bounded_domain_type >::type
0700 lower_max(const Type& left, const Type& right)
0701 {
0702 return lower_less(left, right) ? bounded_lower(right) : bounded_lower(left);
0703 }
0704
0705
0706 template<class Type>
0707 typename boost::enable_if<has_dynamic_bounds<Type>,
0708 typename Type::bounded_domain_type >::type
0709 upper_max(const Type& left, const Type& right)
0710 {
0711 return upper_less(left, right) ? bounded_upper(right) : bounded_upper(left);
0712 }
0713
0714
0715 template<class Type>
0716 typename boost::enable_if<has_dynamic_bounds<Type>,
0717 typename Type::bounded_domain_type >::type
0718 upper_min(const Type& left, const Type& right)
0719 {
0720 return upper_less(left, right) ? bounded_upper(left) : bounded_upper(right);
0721 }
0722
0723
0724
0725 template<class Type>
0726 typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0727 lower_equal(const Type& left, const Type& right)
0728 {
0729 return domain_equal<Type>(lower(left), lower(right));
0730 }
0731
0732 template<class Type>
0733 typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
0734 lower_equal(const Type& left, const Type& right)
0735 {
0736 return domain_equal<Type>(first(left), first(right));
0737 }
0738
0739 template<class Type>
0740 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0741 lower_equal(const Type& left, const Type& right)
0742 {
0743 return domain_equal<Type>(first(left), first(right));
0744 }
0745
0746 template<class Type>
0747 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0748 lower_equal(const Type& left, const Type& right)
0749 {
0750 return (left.bounds().left()==right.bounds().left())
0751 && domain_equal<Type>(lower(left), lower(right));
0752 }
0753
0754
0755
0756 template<class Type>
0757 typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0758 upper_equal(const Type& left, const Type& right)
0759 {
0760 return domain_equal<Type>(upper(left), upper(right));
0761 }
0762
0763 template<class Type>
0764 typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
0765 upper_equal(const Type& left, const Type& right)
0766 {
0767 return domain_equal<Type>(last(left), last(right));
0768 }
0769
0770 template<class Type>
0771 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0772 upper_equal(const Type& left, const Type& right)
0773 {
0774 return domain_equal<Type>(last(left), last(right));
0775 }
0776
0777 template<class Type>
0778 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0779 upper_equal(const Type& left, const Type& right)
0780 {
0781 return (left.bounds().right()==right.bounds().right())
0782 && domain_equal<Type>(upper(left), upper(right));
0783 }
0784
0785
0786 template<class Type>
0787 typename boost::enable_if<is_interval<Type>, bool>::type
0788 lower_less_equal(const Type& left, const Type& right)
0789 {
0790 return lower_less(left,right) || lower_equal(left,right);
0791 }
0792
0793 template<class Type>
0794 typename boost::enable_if<is_interval<Type>, bool>::type
0795 upper_less_equal(const Type& left, const Type& right)
0796 {
0797 return upper_less(left,right) || upper_equal(left,right);
0798 }
0799
0800
0801
0802
0803 namespace non_empty
0804 {
0805
0806 template<class Type>
0807 inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0808 exclusive_less(const Type& left, const Type& right)
0809 {
0810 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
0811 return domain_less_equal<Type>(upper(left), lower(right));
0812 }
0813
0814 template<class Type>
0815 inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0816 exclusive_less(const Type& left, const Type& right)
0817 {
0818 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
0819 return domain_less<Type>(last(left), first(right));
0820 }
0821
0822 template<class Type>
0823 inline typename boost::
0824 enable_if<has_symmetric_bounds<Type>, bool>::type
0825 exclusive_less(const Type& left, const Type& right)
0826 {
0827 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
0828 return domain_less<Type>(last(left), first(right));
0829 }
0830
0831 template<class Type>
0832 inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0833 exclusive_less(const Type& left, const Type& right)
0834 {
0835 BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right)));
0836 return domain_less <Type>(upper(left), lower(right))
0837 || ( domain_equal<Type>(upper(left), lower(right))
0838 && inner_bounds(left,right) != interval_bounds::open() );
0839 }
0840
0841 template<class Type>
0842 inline typename boost::enable_if<is_interval<Type>, bool>::type
0843 contains(const Type& super, const Type& sub)
0844 {
0845 return lower_less_equal(super,sub) && upper_less_equal(sub,super);
0846 }
0847
0848 }
0849
0850
0851 template<class Type>
0852 inline typename boost::enable_if<is_interval<Type>, bool>::type
0853 contains(const Type& super, const Type& sub)
0854 {
0855 return icl::is_empty(sub) || non_empty::contains(super, sub);
0856 }
0857
0858 template<class Type>
0859 typename boost::enable_if<is_discrete_static<Type>, bool>::type
0860 contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
0861 {
0862 return domain_less_equal<Type>(icl::first(super), element )
0863 && domain_less_equal<Type>( element, icl::last(super));
0864 }
0865
0866 template<class Type>
0867 typename boost::enable_if<is_continuous_left_open<Type>, bool>::type
0868 contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
0869 {
0870 return domain_less <Type>(icl::lower(super), element )
0871 && domain_less_equal<Type>( element, icl::upper(super));
0872 }
0873
0874 template<class Type>
0875 typename boost::enable_if<is_continuous_right_open<Type>, bool>::type
0876 contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
0877 {
0878 return domain_less_equal<Type>(icl::lower(super), element )
0879 && domain_less <Type>( element, icl::upper(super));
0880 }
0881
0882 template<class Type>
0883 typename boost::enable_if<has_dynamic_bounds<Type>, bool>::type
0884 contains(const Type& super, const typename interval_traits<Type>::domain_type& element)
0885 {
0886 return
0887 (is_left_closed(super.bounds())
0888 ? domain_less_equal<Type>(lower(super), element)
0889 : domain_less<Type>(lower(super), element))
0890 &&
0891 (is_right_closed(super.bounds())
0892 ? domain_less_equal<Type>(element, upper(super))
0893 : domain_less<Type>(element, upper(super)));
0894 }
0895
0896
0897 template<class Type>
0898 inline typename boost::enable_if<is_interval<Type>, bool>::type
0899 within(const Type& sub, const Type& super)
0900 {
0901 return contains(super,sub);
0902 }
0903
0904
0905 template<class Type>
0906 typename boost::enable_if<is_interval<Type>, bool>::type
0907 operator == (const Type& left, const Type& right)
0908 {
0909 return (icl::is_empty(left) && icl::is_empty(right))
0910 || (lower_equal(left,right) && upper_equal(left,right));
0911 }
0912
0913 template<class Type>
0914 typename boost::enable_if<is_interval<Type>, bool>::type
0915 operator != (const Type& left, const Type& right)
0916 {
0917 return !(left == right);
0918 }
0919
0920
0921 template<class Type>
0922 typename boost::enable_if<is_interval<Type>, bool>::type
0923 operator < (const Type& left, const Type& right)
0924 {
0925 return (!icl::is_empty(left) && !icl::is_empty(right))
0926 && ( lower_less(left,right)
0927 || (lower_equal(left,right) && upper_less(left,right)) );
0928 }
0929
0930 template<class Type>
0931 inline typename boost::enable_if<is_interval<Type>, bool>::type
0932 operator > (const Type& left, const Type& right)
0933 {
0934 return right < left;
0935 }
0936
0937
0938 template<class Type>
0939 inline typename boost::enable_if<is_interval<Type>, bool>::type
0940 operator <= (const Type& left, const Type& right)
0941 {
0942 if(icl::is_empty(left) || icl::is_empty(right))
0943 return false;
0944
0945 return !(left > right);
0946 }
0947
0948 template<class Type>
0949 inline typename boost::enable_if<is_interval<Type>, bool>::type
0950 operator >= (const Type& left, const Type& right)
0951 {
0952 if(icl::is_empty(left) || icl::is_empty(right))
0953 return false;
0954
0955 return !(left < right);
0956 }
0957
0958
0959
0960
0961 template<class Type>
0962 typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type
0963 touches(const Type& left, const Type& right)
0964 {
0965 return domain_equal<Type>(upper(left), lower(right));
0966 }
0967
0968 template<class Type>
0969 typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type
0970 touches(const Type& left, const Type& right)
0971 {
0972 return domain_equal<Type>(last_next(left), first(right));
0973 }
0974
0975 template<class Type>
0976 typename boost::enable_if<is_discrete_interval<Type>, bool>::type
0977 touches(const Type& left, const Type& right)
0978 {
0979 return domain_equal<Type>(domain_next<Type>(last(left)), first(right));
0980 }
0981
0982 template<class Type>
0983 typename boost::enable_if<is_continuous_interval<Type>, bool>::type
0984 touches(const Type& left, const Type& right)
0985 {
0986 return is_complementary(inner_bounds(left,right))
0987 && domain_equal<Type>(upper(left), lower(right));
0988 }
0989
0990
0991
0992
0993
0994
0995
0996 template<class Type>
0997 typename boost::enable_if<is_continuous_interval<Type>,
0998 typename size_type_of<interval_traits<Type> >::type>::type
0999 cardinality(const Type& object)
1000 {
1001 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1002 if(icl::is_empty(object))
1003 return icl::identity_element<SizeT>::value();
1004 else if( object.bounds() == interval_bounds::closed()
1005 && domain_equal<Type>(lower(object), upper(object)))
1006 return icl::unit_element<SizeT>::value();
1007 else
1008 return icl::infinity<SizeT>::value();
1009 }
1010
1011 template<class Type>
1012 typename boost::enable_if<is_discrete_interval<Type>,
1013 typename size_type_of<interval_traits<Type> >::type>::type
1014 cardinality(const Type& object)
1015 {
1016 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1017 return icl::is_empty(object) ? identity_element<SizeT>::value()
1018 : static_cast<SizeT>(last_next(object) - first(object));
1019 }
1020
1021 template<class Type>
1022 typename boost::enable_if<is_continuous_asymmetric<Type>,
1023 typename size_type_of<interval_traits<Type> >::type>::type
1024 cardinality(const Type& object)
1025 {
1026 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1027 if(icl::is_empty(object))
1028 return icl::identity_element<SizeT>::value();
1029 else
1030 return icl::infinity<SizeT>::value();
1031 }
1032
1033 template<class Type>
1034 typename boost::enable_if<is_discrete_asymmetric<Type>,
1035 typename size_type_of<interval_traits<Type> >::type>::type
1036 cardinality(const Type& object)
1037 {
1038 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1039 return icl::is_empty(object) ? identity_element<SizeT>::value()
1040 : static_cast<SizeT>(last_next(object) - first(object));
1041 }
1042
1043 template<class Type>
1044 typename boost::enable_if<has_symmetric_bounds<Type>,
1045 typename size_type_of<interval_traits<Type> >::type>::type
1046 cardinality(const Type& object)
1047 {
1048 typedef typename size_type_of<interval_traits<Type> >::type SizeT;
1049 return icl::is_empty(object) ? identity_element<SizeT>::value()
1050 : static_cast<SizeT>(last_next(object) - first(object));
1051 }
1052
1053
1054
1055
1056 template<class Type>
1057 inline typename enable_if<is_interval<Type>,
1058 typename size_type_of<interval_traits<Type> >::type>::type
1059 size(const Type& object)
1060 {
1061 return cardinality(object);
1062 }
1063
1064
1065 template<class Type>
1066 inline typename boost::enable_if<is_continuous_interval<Type>,
1067 typename difference_type_of<interval_traits<Type> >::type>::type
1068 length(const Type& object)
1069 {
1070 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1071 return icl::is_empty(object) ? identity_element<DiffT>::value()
1072 : upper(object) - lower(object);
1073 }
1074
1075 template<class Type>
1076 inline typename boost::enable_if<is_discrete_interval<Type>,
1077 typename difference_type_of<interval_traits<Type> >::type>::type
1078 length(const Type& object)
1079 {
1080 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1081 return icl::is_empty(object) ? identity_element<DiffT>::value()
1082 : last_next(object) - first(object);
1083 }
1084
1085 template<class Type>
1086 typename boost::enable_if<is_continuous_asymmetric<Type>,
1087 typename difference_type_of<interval_traits<Type> >::type>::type
1088 length(const Type& object)
1089 {
1090 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1091 return icl::is_empty(object) ? identity_element<DiffT>::value()
1092 : upper(object) - lower(object);
1093 }
1094
1095 template<class Type>
1096 inline typename boost::enable_if<is_discrete_static<Type>,
1097 typename difference_type_of<interval_traits<Type> >::type>::type
1098 length(const Type& object)
1099 {
1100 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1101 return icl::is_empty(object) ? identity_element<DiffT>::value()
1102 : last_next(object) - first(object);
1103 }
1104
1105
1106 template<class Type>
1107 inline typename enable_if<is_interval<Type>,
1108 typename size_type_of<interval_traits<Type> >::type>::type
1109 iterative_size(const Type&)
1110 {
1111 return 2;
1112 }
1113
1114
1115
1116
1117
1118
1119
1120 template<class Type>
1121 typename boost::enable_if<has_static_bounds<Type>, Type>::type
1122 hull(Type left, const Type& right)
1123 {
1124 typedef typename interval_traits<Type>::domain_compare domain_compare;
1125
1126 if(icl::is_empty(right))
1127 return left;
1128 else if(icl::is_empty(left))
1129 return right;
1130
1131 return
1132 construct<Type>
1133 (
1134 (std::min)(lower(left), lower(right), domain_compare()),
1135 (std::max)(upper(left), upper(right), domain_compare())
1136 );
1137 }
1138
1139 template<class Type>
1140 typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1141 hull(Type left, const Type& right)
1142 {
1143 if(icl::is_empty(right))
1144 return left;
1145 else if(icl::is_empty(left))
1146 return right;
1147
1148 return dynamic_interval_traits<Type>::construct_bounded
1149 (
1150 lower_min(left, right),
1151 upper_max(left, right)
1152 );
1153 }
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 template<class Type>
1169 typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1170 left_subtract(Type right, const Type& left_minuend)
1171 {
1172 if(exclusive_less(left_minuend, right))
1173 return right;
1174
1175 return construct<Type>(upper(left_minuend), upper(right));
1176 }
1177
1178 template<class Type>
1179 typename boost::enable_if<is_static_closed<Type>, Type>::type
1180 left_subtract(Type right, const Type& left_minuend)
1181 {
1182 if(exclusive_less(left_minuend, right))
1183 return right;
1184 else if(upper_less_equal(right, left_minuend))
1185 return identity_element<Type>::value();
1186
1187 return construct<Type>(domain_next<Type>(upper(left_minuend)), upper(right));
1188 }
1189
1190 template<class Type>
1191 typename boost::enable_if<is_static_open<Type>, Type>::type
1192 left_subtract(Type right, const Type& left_minuend)
1193 {
1194 if(exclusive_less(left_minuend, right))
1195 return right;
1196
1197 return construct<Type>(domain_prior<Type>(upper(left_minuend)), upper(right));
1198 }
1199
1200 template<class Type>
1201 typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1202 left_subtract(Type right, const Type& left_minuend)
1203 {
1204 if(exclusive_less(left_minuend, right))
1205 return right;
1206 return dynamic_interval_traits<Type>::construct_bounded
1207 ( reverse_bounded_upper(left_minuend), bounded_upper(right) );
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 template<class Type>
1222 typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1223 right_subtract(Type left, const Type& right_minuend)
1224 {
1225 if(exclusive_less(left, right_minuend))
1226 return left;
1227 return construct<Type>(lower(left), lower(right_minuend));
1228 }
1229
1230 template<class Type>
1231 typename boost::enable_if<is_static_closed<Type>, Type>::type
1232 right_subtract(Type left, const Type& right_minuend)
1233 {
1234 if(exclusive_less(left, right_minuend))
1235 return left;
1236 else if(lower_less_equal(right_minuend, left))
1237 return identity_element<Type>::value();
1238
1239 return construct<Type>(lower(left), domain_prior<Type>(lower(right_minuend)));
1240 }
1241
1242 template<class Type>
1243 typename boost::enable_if<is_static_open<Type>, Type>::type
1244 right_subtract(Type left, const Type& right_minuend)
1245 {
1246 if(exclusive_less(left, right_minuend))
1247 return left;
1248
1249 return construct<Type>(lower(left), domain_next<Type>(lower(right_minuend)));
1250 }
1251
1252 template<class Type>
1253 typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1254 right_subtract(Type left, const Type& right_minuend)
1255 {
1256 if(exclusive_less(left, right_minuend))
1257 return left;
1258
1259 return dynamic_interval_traits<Type>::construct_bounded
1260 ( bounded_lower(left), reverse_bounded_lower(right_minuend) );
1261 }
1262
1263
1264
1265
1266
1267
1268 template<class Type>
1269 typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1270 operator & (Type left, const Type& right)
1271 {
1272 typedef typename interval_traits<Type>::domain_compare domain_compare;
1273
1274 if(icl::is_empty(left) || icl::is_empty(right))
1275 return identity_element<Type>::value();
1276 else
1277 return
1278 construct<Type>
1279 (
1280 (std::max)(icl::lower(left), icl::lower(right), domain_compare()),
1281 (std::min)(icl::upper(left), icl::upper(right), domain_compare())
1282 );
1283 }
1284
1285 template<class Type>
1286 typename boost::enable_if<has_symmetric_bounds<Type>, Type>::type
1287 operator & (Type left, const Type& right)
1288 {
1289 typedef typename interval_traits<Type>::domain_compare domain_compare;
1290
1291 if(icl::is_empty(left) || icl::is_empty(right))
1292 return identity_element<Type>::value();
1293 else
1294 return
1295 construct<Type>
1296 (
1297 (std::max)(icl::lower(left), icl::lower(right), domain_compare()),
1298 (std::min)(icl::upper(left), icl::upper(right), domain_compare())
1299 );
1300 }
1301
1302 template<class Type>
1303 typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1304 operator & (Type left, const Type& right)
1305 {
1306 if(icl::is_empty(left) || icl::is_empty(right))
1307 return identity_element<Type>::value();
1308 else
1309 return dynamic_interval_traits<Type>::construct_bounded
1310 (
1311 lower_max(left, right),
1312 upper_min(left, right)
1313 );
1314 }
1315
1316
1317
1318 template<class Type>
1319 typename boost::enable_if<is_interval<Type>, bool>::type
1320 intersects(const Type& left, const Type& right)
1321 {
1322 return !( icl::is_empty(left) || icl::is_empty(right)
1323 || exclusive_less(left,right) || exclusive_less(right,left));
1324 }
1325
1326
1327 template<class Type>
1328 typename boost::enable_if<is_interval<Type>, bool>::type
1329 disjoint(const Type& left, const Type& right)
1330 {
1331 return icl::is_empty(left) || icl::is_empty(right)
1332 || exclusive_less(left,right) || exclusive_less(right,left);
1333 }
1334
1335
1336
1337
1338
1339 template<class Type>
1340 typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type
1341 inner_complement(const Type& left, const Type& right)
1342 {
1343 if(icl::is_empty(left) || icl::is_empty(right))
1344 return identity_element<Type>::value();
1345 else if(exclusive_less(left, right))
1346 return construct<Type>(upper(left), lower(right));
1347 else if(exclusive_less(right, left))
1348 return construct<Type>(upper(right), lower(left));
1349 else
1350 return identity_element<Type>::value();
1351 }
1352
1353 template<class Type>
1354 typename boost::enable_if<is_discrete_static_closed<Type>, Type>::type
1355 inner_complement(const Type& left, const Type& right)
1356 {
1357 if(icl::is_empty(left) || icl::is_empty(right))
1358 return identity_element<Type>::value();
1359 else if(exclusive_less(left, right))
1360 return construct<Type>(domain_next<Type>(upper(left)), domain_prior<Type>(lower(right)));
1361 else if(exclusive_less(right, left))
1362 return construct<Type>(domain_next<Type>(upper(right)), domain_prior<Type>(lower(left)));
1363 else
1364 return identity_element<Type>::value();
1365 }
1366
1367 template<class Type>
1368 typename boost::enable_if<is_discrete_static_open<Type>, Type>::type
1369 inner_complement(const Type& left, const Type& right)
1370 {
1371 if(icl::is_empty(left) || icl::is_empty(right))
1372 return identity_element<Type>::value();
1373 else if(exclusive_less(left, right))
1374 return construct<Type>(last(left), first(right));
1375 else if(exclusive_less(right, left))
1376 return construct<Type>(last(right), first(left));
1377 else
1378 return identity_element<Type>::value();
1379 }
1380
1381 template<class Type>
1382 typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type
1383 inner_complement(const Type& left, const Type& right)
1384 {
1385 if(icl::is_empty(left) || icl::is_empty(right))
1386 return identity_element<Type>::value();
1387 else if(exclusive_less(left, right))
1388 return right_subtract(left_subtract(hull(left, right), left), right);
1389 else if(exclusive_less(right, left))
1390 return right_subtract(left_subtract(hull(right, left), right), left);
1391 else
1392 return identity_element<Type>::value();
1393 }
1394
1395 template<class Type>
1396 inline typename boost::enable_if<is_interval<Type>, Type>::type
1397 between(const Type& left, const Type& right)
1398 {
1399 return inner_complement(left, right);
1400 }
1401
1402
1403
1404
1405
1406
1407 template<class Type>
1408 typename boost::
1409 enable_if< mpl::and_< is_interval<Type>
1410 , has_difference<typename interval_traits<Type>::domain_type>
1411 , is_discrete<typename interval_traits<Type>::domain_type>
1412 >
1413 , typename difference_type_of<interval_traits<Type> >::type>::type
1414 distance(const Type& x1, const Type& x2)
1415 {
1416 typedef typename difference_type_of<interval_traits<Type> >::type difference_type;
1417
1418 if(icl::is_empty(x1) || icl::is_empty(x2))
1419 return icl::identity_element<difference_type>::value();
1420 else if(domain_less<Type>(last(x1), first(x2)))
1421 return static_cast<difference_type>(icl::pred(first(x2) - last(x1)));
1422 else if(domain_less<Type>(last(x2), first(x1)))
1423 return static_cast<difference_type>(icl::pred(first(x1) - last(x2)));
1424 else
1425 return icl::identity_element<difference_type>::value();
1426 }
1427
1428 template<class Type>
1429 typename boost::
1430 enable_if< mpl::and_< is_interval<Type>
1431 , has_difference<typename interval_traits<Type>::domain_type>
1432 , is_continuous<typename interval_traits<Type>::domain_type>
1433 >
1434 , typename difference_type_of<interval_traits<Type> >::type>::type
1435 distance(const Type& x1, const Type& x2)
1436 {
1437 typedef typename difference_type_of<interval_traits<Type> >::type DiffT;
1438
1439 if(icl::is_empty(x1) || icl::is_empty(x2))
1440 return icl::identity_element<DiffT>::value();
1441 else if(domain_less<Type>(upper(x1), lower(x2)))
1442 return lower(x2) - upper(x1);
1443 else if(domain_less<Type>(upper(x2), lower(x1)))
1444 return lower(x1) - upper(x2);
1445 else
1446 return icl::identity_element<DiffT>::value();
1447 }
1448
1449
1450
1451
1452 template<class Type>
1453 typename boost::
1454 enable_if< mpl::or_< is_static_left_open<Type>
1455 , is_static_open<Type> >, std::string>::type
1456 left_bracket(const Type&) { return "("; }
1457
1458 template<class Type>
1459 typename boost::
1460 enable_if< mpl::or_< is_static_right_open<Type>
1461 , is_static_closed<Type> >, std::string>::type
1462 left_bracket(const Type&) { return "["; }
1463
1464 template<class Type>
1465 typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type
1466 left_bracket(const Type& object)
1467 {
1468 return left_bracket(object.bounds());
1469 }
1470
1471
1472 template<class Type>
1473 typename boost::
1474 enable_if< mpl::or_< is_static_right_open<Type>
1475 , is_static_open<Type> >, std::string>::type
1476 right_bracket(const Type&) { return ")"; }
1477
1478 template<class Type>
1479 typename boost::
1480 enable_if< mpl::or_< is_static_left_open<Type>
1481 , is_static_closed<Type> >, std::string>::type
1482 right_bracket(const Type&) { return "]"; }
1483
1484 template<class Type>
1485 typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type
1486 right_bracket(const Type& object)
1487 {
1488 return right_bracket(object.bounds());
1489 }
1490
1491
1492 template<class CharType, class CharTraits, class Type>
1493 typename boost::enable_if<is_interval<Type>,
1494 std::basic_ostream<CharType, CharTraits> >::type&
1495 operator << (std::basic_ostream<CharType, CharTraits> &stream, Type const& object)
1496 {
1497 if(boost::icl::is_empty(object))
1498 return stream << left_bracket<Type>(object) << right_bracket<Type>(object);
1499 else
1500 return stream << left_bracket<Type>(object)
1501 << interval_traits<Type>::lower(object)
1502 << ","
1503 << interval_traits<Type>::upper(object)
1504 << right_bracket<Type>(object) ;
1505 }
1506
1507 }}
1508
1509 #endif