os/ossrv/ossrv_pub/boost_apis/boost/numeric/interval/interval.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* Boost interval/interval.hpp header file
sl@0
     2
 *
sl@0
     3
 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
sl@0
     4
 *
sl@0
     5
 * Distributed under the Boost Software License, Version 1.0.
sl@0
     6
 * (See accompanying file LICENSE_1_0.txt or
sl@0
     7
 * copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
     8
 */
sl@0
     9
sl@0
    10
#ifndef BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
sl@0
    11
#define BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
sl@0
    12
sl@0
    13
#include <stdexcept>
sl@0
    14
#include <string>
sl@0
    15
#include <boost/numeric/interval/detail/interval_prototype.hpp>
sl@0
    16
sl@0
    17
namespace boost {
sl@0
    18
namespace numeric {
sl@0
    19
sl@0
    20
namespace interval_lib {
sl@0
    21
    
sl@0
    22
class comparison_error
sl@0
    23
  : public std::runtime_error 
sl@0
    24
{
sl@0
    25
public:
sl@0
    26
  comparison_error()
sl@0
    27
    : std::runtime_error("boost::interval: uncertain comparison")
sl@0
    28
  { }
sl@0
    29
};
sl@0
    30
sl@0
    31
} // namespace interval_lib
sl@0
    32
sl@0
    33
/*
sl@0
    34
 * interval class
sl@0
    35
 */
sl@0
    36
sl@0
    37
template<class T, class Policies>
sl@0
    38
class interval
sl@0
    39
{
sl@0
    40
private:
sl@0
    41
  struct interval_holder;
sl@0
    42
  struct number_holder;
sl@0
    43
public:
sl@0
    44
  typedef T base_type;
sl@0
    45
  typedef Policies traits_type;
sl@0
    46
sl@0
    47
  T const &lower() const;
sl@0
    48
  T const &upper() const;
sl@0
    49
sl@0
    50
  interval();
sl@0
    51
  interval(T const &v);
sl@0
    52
  template<class T1> interval(T1 const &v);
sl@0
    53
  interval(T const &l, T const &u);
sl@0
    54
  template<class T1, class T2> interval(T1 const &l, T2 const &u);
sl@0
    55
  interval(interval<T, Policies> const &r);
sl@0
    56
  template<class Policies1> interval(interval<T, Policies1> const &r);
sl@0
    57
  template<class T1, class Policies1> interval(interval<T1, Policies1> const &r);
sl@0
    58
sl@0
    59
  interval &operator=(T const &v);
sl@0
    60
  template<class T1> interval &operator=(T1 const &v);
sl@0
    61
  interval &operator=(interval<T, Policies> const &r);
sl@0
    62
  template<class Policies1> interval &operator=(interval<T, Policies1> const &r);
sl@0
    63
  template<class T1, class Policies1> interval &operator=(interval<T1, Policies1> const &r);
sl@0
    64
 
sl@0
    65
  void assign(const T& l, const T& u);
sl@0
    66
sl@0
    67
  static interval empty();
sl@0
    68
  static interval whole();
sl@0
    69
  static interval hull(const T& x, const T& y);
sl@0
    70
sl@0
    71
  interval& operator+= (const T& r);
sl@0
    72
  interval& operator+= (const interval& r);
sl@0
    73
  interval& operator-= (const T& r);
sl@0
    74
  interval& operator-= (const interval& r);
sl@0
    75
  interval& operator*= (const T& r);
sl@0
    76
  interval& operator*= (const interval& r);
sl@0
    77
  interval& operator/= (const T& r);
sl@0
    78
  interval& operator/= (const interval& r);
sl@0
    79
sl@0
    80
  bool operator< (const interval_holder& r) const;
sl@0
    81
  bool operator> (const interval_holder& r) const;
sl@0
    82
  bool operator<= (const interval_holder& r) const;
sl@0
    83
  bool operator>= (const interval_holder& r) const;
sl@0
    84
  bool operator== (const interval_holder& r) const;
sl@0
    85
  bool operator!= (const interval_holder& r) const;
sl@0
    86
sl@0
    87
  bool operator< (const number_holder& r) const;
sl@0
    88
  bool operator> (const number_holder& r) const;
sl@0
    89
  bool operator<= (const number_holder& r) const;
sl@0
    90
  bool operator>= (const number_holder& r) const;
sl@0
    91
  bool operator== (const number_holder& r) const;
sl@0
    92
  bool operator!= (const number_holder& r) const;
sl@0
    93
sl@0
    94
  // the following is for internal use only, it is not a published interface
sl@0
    95
  // nevertheless, it's public because friends don't always work correctly.
sl@0
    96
  interval(const T& l, const T& u, bool): low(l), up(u) {}
sl@0
    97
  void set_empty();
sl@0
    98
  void set_whole();
sl@0
    99
  void set(const T& l, const T& u);
sl@0
   100
sl@0
   101
private:
sl@0
   102
  struct interval_holder {
sl@0
   103
    template<class Policies2>
sl@0
   104
    interval_holder(const interval<T, Policies2>& r)
sl@0
   105
      : low(r.lower()), up(r.upper())
sl@0
   106
    {
sl@0
   107
      typedef typename Policies2::checking checking2;
sl@0
   108
      if (checking2::is_empty(low, up))
sl@0
   109
        throw interval_lib::comparison_error();
sl@0
   110
    }
sl@0
   111
sl@0
   112
    const T& low;
sl@0
   113
    const T& up;
sl@0
   114
  };
sl@0
   115
sl@0
   116
  struct number_holder {
sl@0
   117
    number_holder(const T& r) : val(r)
sl@0
   118
    {
sl@0
   119
      typedef typename Policies::checking checking;
sl@0
   120
      if (checking::is_nan(r))
sl@0
   121
        throw interval_lib::comparison_error();
sl@0
   122
    }
sl@0
   123
    
sl@0
   124
    const T& val;
sl@0
   125
  };
sl@0
   126
sl@0
   127
  typedef typename Policies::checking checking;
sl@0
   128
  typedef typename Policies::rounding rounding;
sl@0
   129
sl@0
   130
  T low;
sl@0
   131
  T up;
sl@0
   132
};
sl@0
   133
sl@0
   134
template<class T, class Policies> inline
sl@0
   135
interval<T, Policies>::interval():
sl@0
   136
  low(static_cast<T>(0)), up(static_cast<T>(0))
sl@0
   137
{}
sl@0
   138
sl@0
   139
template<class T, class Policies> inline
sl@0
   140
interval<T, Policies>::interval(T const &v): low(v), up(v)
sl@0
   141
{
sl@0
   142
  if (checking::is_nan(v)) set_empty();
sl@0
   143
}
sl@0
   144
sl@0
   145
template<class T, class Policies> template<class T1> inline
sl@0
   146
interval<T, Policies>::interval(T1 const &v)
sl@0
   147
{
sl@0
   148
  if (checking::is_nan(v)) set_empty();
sl@0
   149
  else {
sl@0
   150
    rounding rnd;
sl@0
   151
    low = rnd.conv_down(v);
sl@0
   152
    up  = rnd.conv_up  (v);
sl@0
   153
  }
sl@0
   154
}
sl@0
   155
sl@0
   156
template<class T, class Policies> template<class T1, class T2> inline
sl@0
   157
interval<T, Policies>::interval(T1 const &l, T2 const &u)
sl@0
   158
{
sl@0
   159
  if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) set_empty();
sl@0
   160
  else {
sl@0
   161
    rounding rnd;
sl@0
   162
    low = rnd.conv_down(l);
sl@0
   163
    up  = rnd.conv_up  (u);
sl@0
   164
  }
sl@0
   165
}
sl@0
   166
sl@0
   167
template<class T, class Policies> inline
sl@0
   168
interval<T, Policies>::interval(T const &l, T const &u): low(l), up(u)
sl@0
   169
{
sl@0
   170
  if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
sl@0
   171
    set_empty();
sl@0
   172
}
sl@0
   173
sl@0
   174
sl@0
   175
template<class T, class Policies> inline
sl@0
   176
interval<T, Policies>::interval(interval<T, Policies> const &r): low(r.lower()), up(r.upper())
sl@0
   177
{}
sl@0
   178
sl@0
   179
template<class T, class Policies> template<class Policies1> inline
sl@0
   180
interval<T, Policies>::interval(interval<T, Policies1> const &r): low(r.lower()), up(r.upper())
sl@0
   181
{
sl@0
   182
  typedef typename Policies1::checking checking1;
sl@0
   183
  if (checking1::is_empty(r.lower(), r.upper())) set_empty();
sl@0
   184
}
sl@0
   185
sl@0
   186
template<class T, class Policies> template<class T1, class Policies1> inline
sl@0
   187
interval<T, Policies>::interval(interval<T1, Policies1> const &r)
sl@0
   188
{
sl@0
   189
  typedef typename Policies1::checking checking1;
sl@0
   190
  if (checking1::is_empty(r.lower(), r.upper())) set_empty();
sl@0
   191
  else {
sl@0
   192
    rounding rnd;
sl@0
   193
    low = rnd.conv_down(r.lower());
sl@0
   194
    up  = rnd.conv_up  (r.upper());
sl@0
   195
  }
sl@0
   196
}
sl@0
   197
sl@0
   198
template<class T, class Policies> inline
sl@0
   199
interval<T, Policies> &interval<T, Policies>::operator=(T const &v)
sl@0
   200
{
sl@0
   201
  if (checking::is_nan(v)) set_empty();
sl@0
   202
  else low = up = v;
sl@0
   203
  return *this;
sl@0
   204
}
sl@0
   205
sl@0
   206
template<class T, class Policies> template<class T1> inline
sl@0
   207
interval<T, Policies> &interval<T, Policies>::operator=(T1 const &v)
sl@0
   208
{
sl@0
   209
  if (checking::is_nan(v)) set_empty();
sl@0
   210
  else {
sl@0
   211
    rounding rnd;
sl@0
   212
    low = rnd.conv_down(v);
sl@0
   213
    up  = rnd.conv_up  (v);
sl@0
   214
  }
sl@0
   215
  return *this;
sl@0
   216
}
sl@0
   217
sl@0
   218
template<class T, class Policies> inline
sl@0
   219
interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies> const &r)
sl@0
   220
{
sl@0
   221
  low = r.lower();
sl@0
   222
  up  = r.upper();
sl@0
   223
  return *this;
sl@0
   224
}
sl@0
   225
sl@0
   226
template<class T, class Policies> template<class Policies1> inline
sl@0
   227
interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies1> const &r)
sl@0
   228
{
sl@0
   229
  typedef typename Policies1::checking checking1;
sl@0
   230
  if (checking1::is_empty(r.lower(), r.upper())) set_empty();
sl@0
   231
  else {
sl@0
   232
    low = r.lower();
sl@0
   233
    up  = r.upper();
sl@0
   234
  }
sl@0
   235
  return *this;
sl@0
   236
}
sl@0
   237
sl@0
   238
template<class T, class Policies> template<class T1, class Policies1> inline
sl@0
   239
interval<T, Policies> &interval<T, Policies>::operator=(interval<T1, Policies1> const &r)
sl@0
   240
{
sl@0
   241
  typedef typename Policies1::checking checking1;
sl@0
   242
  if (checking1::is_empty(r.lower(), r.upper())) set_empty();
sl@0
   243
  else {
sl@0
   244
    rounding rnd;
sl@0
   245
    low = rnd.conv_down(r.lower());
sl@0
   246
    up  = rnd.conv_up  (r.upper());
sl@0
   247
  }
sl@0
   248
  return *this;
sl@0
   249
}
sl@0
   250
sl@0
   251
template<class T, class Policies> inline
sl@0
   252
void interval<T, Policies>::assign(const T& l, const T& u)
sl@0
   253
{
sl@0
   254
  if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
sl@0
   255
    set_empty();
sl@0
   256
  else set(l, u);
sl@0
   257
}
sl@0
   258
sl@0
   259
template<class T, class Policies> inline
sl@0
   260
void interval<T, Policies>::set(const T& l, const T& u)
sl@0
   261
{
sl@0
   262
  low = l;
sl@0
   263
  up  = u;
sl@0
   264
}
sl@0
   265
sl@0
   266
template<class T, class Policies> inline
sl@0
   267
void interval<T, Policies>::set_empty()
sl@0
   268
{
sl@0
   269
  low = checking::empty_lower();
sl@0
   270
  up  = checking::empty_upper();
sl@0
   271
}
sl@0
   272
sl@0
   273
template<class T, class Policies> inline
sl@0
   274
void interval<T, Policies>::set_whole()
sl@0
   275
{
sl@0
   276
  low = checking::neg_inf();
sl@0
   277
  up  = checking::pos_inf();
sl@0
   278
}
sl@0
   279
sl@0
   280
template<class T, class Policies> inline
sl@0
   281
interval<T, Policies> interval<T, Policies>::hull(const T& x, const T& y)
sl@0
   282
{
sl@0
   283
  bool bad_x = checking::is_nan(x);
sl@0
   284
  bool bad_y = checking::is_nan(y);
sl@0
   285
  if (bad_x)
sl@0
   286
    if (bad_y) return interval::empty();
sl@0
   287
    else       return interval(y, y, true);
sl@0
   288
  else
sl@0
   289
    if (bad_y) return interval(x, x, true);
sl@0
   290
  if (x <= y) return interval(x, y, true);
sl@0
   291
  else        return interval(y, x, true);
sl@0
   292
}
sl@0
   293
sl@0
   294
template<class T, class Policies> inline
sl@0
   295
interval<T, Policies> interval<T, Policies>::empty()
sl@0
   296
{
sl@0
   297
  return interval<T, Policies>(checking::empty_lower(),
sl@0
   298
                               checking::empty_upper(), true);
sl@0
   299
}
sl@0
   300
sl@0
   301
template<class T, class Policies> inline
sl@0
   302
interval<T, Policies> interval<T, Policies>::whole()
sl@0
   303
{
sl@0
   304
  return interval<T, Policies>(checking::neg_inf(), checking::pos_inf(), true);
sl@0
   305
}
sl@0
   306
sl@0
   307
template<class T, class Policies> inline
sl@0
   308
const T& interval<T, Policies>::lower() const
sl@0
   309
{
sl@0
   310
  return low;
sl@0
   311
}
sl@0
   312
sl@0
   313
template<class T, class Policies> inline
sl@0
   314
const T& interval<T, Policies>::upper() const
sl@0
   315
{
sl@0
   316
  return up;
sl@0
   317
}
sl@0
   318
sl@0
   319
/*
sl@0
   320
 * interval/interval comparisons
sl@0
   321
 */
sl@0
   322
sl@0
   323
template<class T, class Policies> inline
sl@0
   324
bool interval<T, Policies>::operator< (const interval_holder& r) const
sl@0
   325
{
sl@0
   326
  if (!checking::is_empty(low, up)) {
sl@0
   327
    if (up < r.low) return true;
sl@0
   328
    else if (low >= r.up) return false;
sl@0
   329
  }
sl@0
   330
  throw interval_lib::comparison_error();
sl@0
   331
}
sl@0
   332
sl@0
   333
template<class T, class Policies> inline
sl@0
   334
bool interval<T, Policies>::operator> (const interval_holder& r) const
sl@0
   335
{
sl@0
   336
  if (!checking::is_empty(low, up)) {
sl@0
   337
    if (low > r.up) return true;
sl@0
   338
    else if (up <= r.low) return false;
sl@0
   339
  }
sl@0
   340
  throw interval_lib::comparison_error();
sl@0
   341
}
sl@0
   342
sl@0
   343
template<class T, class Policies> inline
sl@0
   344
bool interval<T, Policies>::operator<= (const interval_holder& r) const
sl@0
   345
{
sl@0
   346
  if (!checking::is_empty(low, up)) {
sl@0
   347
    if (up <= r.low) return true;
sl@0
   348
    else if (low > r.up) return false;
sl@0
   349
  }
sl@0
   350
  throw interval_lib::comparison_error();
sl@0
   351
}
sl@0
   352
sl@0
   353
template<class T, class Policies> inline
sl@0
   354
bool interval<T, Policies>::operator>= (const interval_holder& r) const
sl@0
   355
{
sl@0
   356
  if (!checking::is_empty(low, up)) {
sl@0
   357
    if (low >= r.up) return true;
sl@0
   358
    else if (up < r.low) return false;
sl@0
   359
  }
sl@0
   360
  throw interval_lib::comparison_error();
sl@0
   361
}
sl@0
   362
sl@0
   363
template<class T, class Policies> inline
sl@0
   364
bool interval<T, Policies>::operator== (const interval_holder& r) const
sl@0
   365
{
sl@0
   366
  if (!checking::is_empty(low, up)) {
sl@0
   367
    if (up == r.low && low == r.up) return true;
sl@0
   368
    else if (up < r.low || low > r.up) return false;
sl@0
   369
  }
sl@0
   370
  throw interval_lib::comparison_error();
sl@0
   371
}
sl@0
   372
sl@0
   373
template<class T, class Policies> inline
sl@0
   374
bool interval<T, Policies>::operator!= (const interval_holder& r) const
sl@0
   375
{
sl@0
   376
  if (!checking::is_empty(low, up)) {
sl@0
   377
    if (up < r.low || low > r.up) return true;
sl@0
   378
    else if (up == r.low && low == r.up) return false;
sl@0
   379
  }
sl@0
   380
  throw interval_lib::comparison_error();
sl@0
   381
}
sl@0
   382
sl@0
   383
/*
sl@0
   384
 * interval/number comparisons
sl@0
   385
 */
sl@0
   386
sl@0
   387
template<class T, class Policies> inline
sl@0
   388
bool interval<T, Policies>::operator< (const number_holder& r) const
sl@0
   389
{
sl@0
   390
  if (!checking::is_empty(low, up)) {
sl@0
   391
    if (up < r.val) return true;
sl@0
   392
    else if (low >= r.val) return false;
sl@0
   393
  }
sl@0
   394
  throw interval_lib::comparison_error();
sl@0
   395
}
sl@0
   396
sl@0
   397
template<class T, class Policies> inline
sl@0
   398
bool interval<T, Policies>::operator> (const number_holder& r) const
sl@0
   399
{
sl@0
   400
  if (!checking::is_empty(low, up)) {
sl@0
   401
    if (low > r.val) return true;
sl@0
   402
    else if (up <= r.val) return false;
sl@0
   403
  }
sl@0
   404
  throw interval_lib::comparison_error();
sl@0
   405
}
sl@0
   406
sl@0
   407
template<class T, class Policies> inline
sl@0
   408
bool interval<T, Policies>::operator<= (const number_holder& r) const
sl@0
   409
{
sl@0
   410
  if (!checking::is_empty(low, up)) {
sl@0
   411
    if (up <= r.val) return true;
sl@0
   412
    else if (low > r.val) return false;
sl@0
   413
  }
sl@0
   414
  throw interval_lib::comparison_error();
sl@0
   415
}
sl@0
   416
sl@0
   417
template<class T, class Policies> inline
sl@0
   418
bool interval<T, Policies>::operator>= (const number_holder& r) const
sl@0
   419
{
sl@0
   420
  if (!checking::is_empty(low, up)) {
sl@0
   421
    if (low >= r.val) return true;
sl@0
   422
    else if (up < r.val) return false;
sl@0
   423
  }
sl@0
   424
  throw interval_lib::comparison_error();
sl@0
   425
}
sl@0
   426
sl@0
   427
template<class T, class Policies> inline
sl@0
   428
bool interval<T, Policies>::operator== (const number_holder& r) const
sl@0
   429
{
sl@0
   430
  if (!checking::is_empty(low, up)) {
sl@0
   431
    if (up == r.val && low == r.val) return true;
sl@0
   432
    else if (up < r.val || low > r.val) return false;
sl@0
   433
  }
sl@0
   434
  throw interval_lib::comparison_error();
sl@0
   435
}
sl@0
   436
sl@0
   437
template<class T, class Policies> inline
sl@0
   438
bool interval<T, Policies>::operator!= (const number_holder& r) const
sl@0
   439
{
sl@0
   440
  if (!checking::is_empty(low, up)) {
sl@0
   441
    if (up < r.val || low > r.val) return true;
sl@0
   442
    else if (up == r.val && low == r.val) return false;
sl@0
   443
  }
sl@0
   444
  throw interval_lib::comparison_error();
sl@0
   445
}
sl@0
   446
sl@0
   447
} // namespace numeric
sl@0
   448
} // namespace boost
sl@0
   449
sl@0
   450
#endif // BOOST_NUMERIC_INTERVAL_INTERVAL_HPP