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&); 44 static T empty_lower(); 45 static T empty_upper(); 46 static bool is_empty(const T&, const T&); 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<T>::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<class T> 89struct checking_base; 90template<class T, class Checking = checking_base<T>, class Exception = exception_create_empty<T> > 91struct checking_no_empty; 92template<class T, class Checking = checking_base<T> > 93struct checking_no_nan; 94template<class T, class Checking = checking_base<T>, class Exception = exception_invalid_number<T> > 95struct checking_catch_nan; 96 97template<class T> struct exception_create_empty { T operator()(); }; 98template<class T> 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<T></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<=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<T></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<T, 209 checking_no_empty<T> ></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<T, checking_no_empty<T> ></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<T></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<T></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<T></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 © 2002 Guillaume Melquiond, Sylvain Pion, Hervé 244 Brönnimann, Polytechnic University<br> 245 Copyright © 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