• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2"http://www.w3.org/TR/html4/loose.dtd">
3
4<html>
5<head>
6  <meta http-equiv="Content-Language" content="en-us">
7  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
8  <link rel="stylesheet" type="text/css" href="../../../../boost.css">
9
10  <title>Checking policies</title>
11</head>
12
13<body>
14  <h1>Checking policies</h1>
15
16  <p>A checking policy controls how the <code>interval</code> class will deal
17  with special cases like: empty intervals, infinite numbers, invalid
18  values.</p>
19
20  <p>For example, let's consider <code>operator+(interval, T)</code>. The
21  second argument could be an invalid value (for a floating-point number, it
22  is a NaN). What to do in such a case? First, we could say that the second
23  argument can never be an invalid number. Second, we could also say such a
24  situation can arise but is forbidden. Third, we could allow such values and
25  generate an empty interval when encountered. And there is many other
26  possibilities.</p>
27
28  <p>It is the reason why such a policy is used: there is a lot of
29  interesting behaviors and it would be sad to arbitrarily select one of
30  these.</p>
31
32  <h2>Requirements</h2>
33
34  <p>The checking class should satisfy the following requirement (in the form
35  of an interface):</p>
36  <pre>
37/* requirements for checking policy */
38struct checking
39{
40  static T pos_inf();
41  static T neg_inf();
42  static T nan();
43  static bool is_nan(const T&amp;);
44  static T empty_lower();
45  static T empty_upper();
46  static bool is_empty(const T&amp;, const T&amp;);
47};
48</pre>
49
50  <p>The first two functions, <code>pos_inf</code> and <code>neg_inf</code>,
51  are invoked each time the library has to create the infinite bound of an
52  interval. For example, <code>interval::whole</code> computes
53  <code>interval(checking::neg_inf(), checking::pos_inf())</code>. If
54  infinite values are allowed and
55  <code>std::numeric_limits&lt;T&gt;::infinity()</code> returns a correct
56  value, such a value can be used.</p>
57
58  <p>Next comes <code>nan</code>. This function is used each time a function
59  need to return a value of type <code>T</code> but is unable to compute it.
60  It only happens when one of the arguments of the function is invalid. For
61  example, if you ask what the median value of an empty interval is,
62  <code>nan</code> will be used. But please remember: <code>lower</code> and
63  <code>upper</code> directly return the value stocked in the interval; so,
64  if the interval is empty, <code>lower</code> will not answer
65  <code>by</code> a call to <code>checking::nan</code> (but will return the
66  same value than <code>checking::empty_lower</code> could return).</p>
67
68  <p><code>empty_lower</code> and <code>empty_upper</code> respectively
69  return the lower and upper bound of the empty interval. There is no
70  requirements for <code>empty_lower</code> and <code>empty_upper</code> to
71  return the same value than <code>checking::nan</code>. For example, if the
72  type <code>T</code> does not have any invalid value, the
73  <code>empty_</code> functions can return the [1;0] interval.</p>
74
75  <p><code>is_nan</code> is used to test if a value of type <code>T</code> is
76  invalid or not. <code>is_empty</code> tests if the interval formed by the
77  two arguments is empty or not. Such tests will generally be at the
78  beginning of each function which involves an argument of type
79  <code>T</code>. If one of the inputs is declared invalid, the the function
80  will try to produce an invalid value or an input interval.</p>
81
82  <h2>Synopsis</h2>
83  <pre>
84namespace boost {
85namespace numeric {
86namespace interval_lib {
87
88template&lt;class T&gt;
89struct checking_base;
90template&lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_create_empty&lt;T&gt; &gt;
91struct checking_no_empty;
92template&lt;class T, class Checking = checking_base&lt;T&gt; &gt;
93struct checking_no_nan;
94template&lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_invalid_number&lt;T&gt; &gt;
95struct checking_catch_nan;
96
97template&lt;class T&gt; struct exception_create_empty { T operator()(); };
98template&lt;class T&gt; struct exception_invalid_number { void operator()(); };
99
100} // namespace numeric
101} // namespace interval_lib
102} // namespace boost
103</pre>
104
105  <h2>Predefined classes</h2>
106
107  <p>In order to simplify the customization of the policy, some templates are
108  already defined in the library.</p>
109
110  <p>First of all, there is <code>checking_base</code>. Thanks to the
111  information provided by <code>std::numeric_limits&lt;T&gt;</code>, this
112  class is able to generate a base for the policy. If <code>T</code> has
113  quiet NaNs (as said by <code>numeric_limits::has_quiet_NaN</code>), then
114  the value is used for <code>nan</code>, <code>empty_lower</code>,
115  <code>empty_upper</code>; and a basic test is used for <code>is_nan</code>
116  (it is <code>x!=x</code>). If <code>T</code> does not have quiet NaNs, then
117  <code>nan</code> is an <code>assert(false)</code>, the empty interval is
118  [1,0], and <code>is_nan</code> always return <code>false</code>. As for
119  <code>nan</code>, <code>pos_inf</code> returns
120  <code>numeric_limits::infinity()</code> if possible, or is an
121  <code>assert(false</code>) otherwise. <code>neg_inf</code> returns the
122  opposite. Finally, <code>is_empty(T l,T u)</code> is always defined by
123  <code>!(l&lt;=u)</code>.</p>
124
125  <p>Next comes <code>checking_no_empty</code>. Using it means that each time
126  an empty interval should be produced (by <code>empty_lower</code> and
127  <code>empty_upper</code>), the function object given by the
128  <code>Exception</code> argument of the template is invoked and the value it
129  returns is propagated. So, if <code>Exception</code> is appropriately
130  defined (for example it could throw an exception, hence the name of the
131  argument), you can be sure no empty interval will ever be created. So
132  <code>is_empty</code> will always return <code>false</code> (since there is
133  no need to test for an empty interval). And as explained before, in that
134  case we can also replace <code>nan</code> by an <code>assert(false)</code>;
135  you will be sure no invalid number will ever be produced. If this template
136  is not used, it implicitly means that all the functions can produce empty
137  intervals and they correctly deal with empty interval arguments.</p>
138
139  <p>Finally there are <code>checking_no_nan</code> and
140  <code>checking_catch_nan</code>. The first one expresses the functions of
141  the library will never get an invalid number as argument. So
142  <code>is_nan</code> will only return <code>false</code>. The other one
143  means the arguments can be an invalid number but in that case,
144  <code>is_nan</code> will call the function object <code>Exception</code>
145  and return <code>false</code>. Indeed, this template means invalid numbers
146  should never make their way through to the body of the function. If none of
147  this two templates is used, it implicitly means that all the functions can
148  get invalid number arguments and they will correctly deal with them.</p>
149
150  <p><code>exception_create_empty</code> throws
151  <code>std::runtime_error</code> with the message <code>"boost::interval:
152  empty interval created"</code> and <code>exception_invalid_number</code>
153  throws <code>std::invalid_argument</code> with the message
154  <code>"boost::interval: invalid number"</code>.</p>
155
156  <h2>Customizing your own checking policy</h2>
157
158  <p>In order to define a suitable policy, you need to correctly say what you
159  expect from your interval class. First of all, are you interested in
160  getting empty intervals at the end of a calculus? If you do not want to
161  obtain empty intervals, <code>empty_lower</code> and
162  <code>empty_upper</code> have to fail when invoked (they can throw an
163  exception, set a flag, etc). However, if no function is able to produce an
164  empty interval, it is no more necessary to do the test, so
165  <code>is_empty</code> may always return <code>false</code>. In this case, a
166  good compiler will do a lot of optimizations.</p>
167
168  <p>You could also be interested in getting empty intervals at the end of
169  the calculus. For example, if you need to transform an array of unsure
170  values (or intervals) in a new array of intervals, you may not want to stop
171  the conversion at the first encountered problem. So
172  <code>empty_lower</code> and <code>empty_upper</code> need to return
173  suitable values in order to define an empty interval (you can use an upper
174  bound which is not greater or equal than the lower bound for example); and
175  <code>is_empty</code> must be able to distinguish empty intervals from the
176  valid intervals.</p>
177
178  <p>Another important question is: is it possible that some base numbers
179  (objects of type <code>T</code>) are invalid? And if it is possible, are
180  they allowed or not ? If it is not possible, no test is necessary;
181  <code>is_nan</code> may always return <code>false</code>. In this case too,
182  a good compiler will do a lot of optimizations. If function arguments can
183  hold invalid numbers, two cases must be considered according to whether
184  they are allowed or not. If they are allowed, <code>is_nan</code> just has
185  to test if they are invalid or not. If they are forbidden,
186  <code>is_nan</code> should fail (exception, assert, etc.) when invoked on
187  an invalid argument and return <code>false</code> otherwise. The value
188  returned by <code>nan</code> does not have any interest since the interval
189  functions are guaranteed not to produce invalid interval bounds unless the
190  user passes invalid numbers to the constructors. So you can put an assert
191  inside if you do not trust the library. :-)</p>
192
193  <p>And finally, you need to decide what to do with <code>nan</code> if it
194  has not already been decided at the beginning, and with
195  <code>pos_inf</code> and <code>neg_inf</code>. These functions should
196  return a value or start an exceptional behavior (especially if the base
197  type does not have corresponding values).</p>
198
199  <h2>Some examples</h2>
200
201  <ul>
202    <li>If you need a checking policy that allows the library to correctly
203    manipulate data, even if they contain invalid numbers and empty
204    intervals, then <code>checking_base&lt;T&gt;</code> is a
205    possibility.</li>
206
207    <li>If you do not want empty intervals to be created and are not sure all
208    the numbers are valid, then <code>checking_catch_nan&lt;T,
209    checking_no_empty&lt;T&gt; &gt;</code> can help you.</li>
210
211    <li>If all the numbers will be valid and if no empty interval is supposed
212    to be created (or if you do not want them to be created), then you can
213    use <code>checking_no_nan&lt;T, checking_no_empty&lt;T&gt; &gt;</code>.
214    Please note that if <code>T</code> does not have a way to represent
215    invalid numbers, then this policy will behave the same way as
216    <code>checking_no_empty&lt;T&gt;</code>. This is the default policy and
217    it is also called <code>interval_lib::checking_strict</code>.</li>
218
219    <li>If all numerical data are valid but the algorithm can produce and
220    manipulate empty intervals, then <code>checking_no_nan&lt;T&gt;</code>
221    should be used.</li>
222
223    <li>Similarly, if invalid data have to be signaled and the algorithm can
224    manipulate empty intervals, the <code>checking_catch_nan&lt;T&gt;</code>
225    is a solution.</li>
226
227    <li>If you do not mind having undefined results when an empty interval or
228    an interval number is produced, your best bet is to create your own
229    policy by overloading <code>checking_base</code> and modifying
230    <code>is_nan</code> et <code>is_empty</code> in order for them to always
231    return <code>false</code>. It is probably the fastest checking policy
232    available; however, it suffers from its deficient security.</li>
233  </ul>
234  <hr>
235
236  <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
237  "../../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
238  height="31" width="88"></a></p>
239
240  <p>Revised
241  <!--webbot bot="Timestamp" s-type="EDITED" s-format="%Y-%m-%d" startspan -->2006-12-24<!--webbot bot="Timestamp" endspan i-checksum="12172" --></p>
242
243  <p><i>Copyright &copy; 2002 Guillaume Melquiond, Sylvain Pion, Herv&eacute;
244  Br&ouml;nnimann, Polytechnic University<br>
245  Copyright &copy; 2003-2004 Guillaume Melquiond</i></p>
246
247  <p><i>Distributed under the Boost Software License, Version 1.0. (See
248  accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
249  or copy at <a href=
250  "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
251</body>
252</html>
253