annotate DEPENDENCIES/generic/include/boost/icl/concept/interval.hpp @ 133:4acb5d8d80b6 tip

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