1<?xml version="1.0" encoding="UTF-8"?> 2<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN" 3"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> 4<section id="safe_numerics.safe_numeric_concept"> 5 <title>SafeNumeric<T></title> 6 7 <?dbhtml stop-chunking?> 8 9 <section> 10 <title>Description</title> 11 12 <para>This holds an arithmetic value which can be used as a replacement 13 for built-in C++ arithmetic values. These types differ from their built-in 14 counter parts in that the are guaranteed not to produce invalid arithmetic 15 results. These operations return safe types rather than built-in 16 types.</para> 17 </section> 18 19 <section> 20 <title>Refinement of</title> 21 22 <para><link linkend="safe_numerics.numeric">Numeric</link> or <link 23 linkend="safe_numerics.integer">Integer</link></para> 24 </section> 25 26 <section> 27 <title>Notation</title> 28 29 <informaltable> 30 <tgroup cols="2"> 31 <colspec align="left" colwidth="3*"/> 32 33 <colspec align="left" colwidth="10*"/> 34 35 <thead> 36 <row> 37 <entry align="left">Symbol</entry> 38 39 <entry align="left">Description</entry> 40 </row> 41 </thead> 42 43 <tbody> 44 <row> 45 <entry><code>T, U</code></entry> 46 47 <entry>Types fulfilling <link 48 linkend="safe_numerics.numeric">Numeric</link> or <link 49 linkend="safe_numerics.integer">Integer</link> type 50 requirements.</entry> 51 </row> 52 53 <row> 54 <entry>t, u</entry> 55 56 <entry>objects of types T, U</entry> 57 </row> 58 59 <row> 60 <entry>S</entry> 61 62 <entry>A type fulfilling SafeNumeric type requirements</entry> 63 </row> 64 65 <row> 66 <entry>s, s1, s2</entry> 67 68 <entry>objects of types S</entry> 69 </row> 70 71 <row> 72 <entry>op</entry> 73 74 <entry>C++ infix operator supported by underlying type T</entry> 75 </row> 76 77 <row> 78 <entry>prefix_op</entry> 79 80 <entry>C++ prefix operator: -, +, ~, ++, -- supported by 81 underlying type T</entry> 82 </row> 83 84 <row> 85 <entry>postfix_op</entry> 86 87 <entry>C++ postfix operator:++, -- supported by underlying type 88 T</entry> 89 </row> 90 91 <row> 92 <entry>assign_op</entry> 93 94 <entry>C++ assignment operator</entry> 95 </row> 96 </tbody> 97 </tgroup> 98 </informaltable> 99 </section> 100 101 <section> 102 <title>Valid Expressions</title> 103 104 <para><informaltable> 105 <tgroup cols="3"> 106 <colspec align="left" colwidth="3*"/> 107 108 <colspec align="left" colwidth="2*"/> 109 110 <colspec align="left" colwidth="8*"/> 111 112 <thead> 113 <row> 114 <entry align="left">Expression</entry> 115 116 <entry align="left">Result Type</entry> 117 118 <entry>Description</entry> 119 </row> 120 </thead> 121 122 <tbody> 123 <row> 124 <entry><code>s op t</code></entry> 125 126 <entry>unspecified S</entry> 127 128 <entry><para>invoke C++ operator op and return another 129 SafeNumeric type.</para></entry> 130 </row> 131 132 <row> 133 <entry><code>t op s</code></entry> 134 135 <entry>unspecified S</entry> 136 137 <entry><para>invoke C++ operator op and return another 138 SafeNumeric type.</para></entry> 139 </row> 140 141 <row> 142 <entry><code>s1 op s2</code></entry> 143 144 <entry>unspecified S</entry> 145 146 <entry><para>invoke C++ operator op and return another 147 SafeNumeric type.</para></entry> 148 </row> 149 150 <row> 151 <entry><code>prefix_op S</code></entry> 152 153 <entry>unspecified S</entry> 154 155 <entry><para>invoke C++ operator <code>prefix_op</code> and 156 return another SafeNumeric type.</para></entry> 157 </row> 158 159 <row> 160 <entry><code>S postfix_op</code></entry> 161 162 <entry>unspecified S</entry> 163 164 <entry><para>invoke C++ operator <code>postfix_op</code> and 165 return another SafeNumeric type.</para></entry> 166 </row> 167 168 <row> 169 <entry><code>s assign_op t</code></entry> 170 171 <entry>S &</entry> 172 173 <entry><para>convert t to type S and assign it to s. 174 </para></entry> 175 </row> 176 177 <row> 178 <entry><code>t assign_op s</code></entry> 179 180 <entry>T &</entry> 181 182 <entry><para>convert s to type T and assign it to s. If the 183 value t cannot be represented as an instance of type S, it is an 184 error.</para></entry> 185 </row> 186 187 <row> 188 <entry><code>S(t)</code></entry> 189 190 <entry>S</entry> 191 192 <entry><para>construct an instance of S from a value of type T. 193 In this case, T is referred to as the base type of S. If the 194 value t cannot be represented as an instance of type S, it is an 195 exception condition is invoked. </para></entry> 196 </row> 197 198 <row> 199 <entry><code>S</code></entry> 200 201 <entry>S</entry> 202 203 <entry><para>construct an uninitialized instance of 204 S.</para></entry> 205 </row> 206 207 <row> 208 <entry><code>T(s)</code></entry> 209 210 <entry>T</entry> 211 212 <entry><para>implicit conversion of the value of s to type T. If 213 the value of s cannot be correctly represented as a type T, an 214 exception condition is invoked.</para></entry> 215 </row> 216 217 <row> 218 <entry><code>static_cast<T>(s)</code></entry> 219 220 <entry>T</entry> 221 222 <entry><para>convert the value of s to type T. If the value of s 223 cannot be correctly represented as a type T, an exception 224 condition is invoked. </para></entry> 225 </row> 226 227 <row> 228 <entry><code>is_safe<S></code></entry> 229 230 <entry><code>std::true_type</code></entry> 231 232 <entry><para>type trait to query whether any type S fulfills the 233 requirements for a SafeNumeric type.</para></entry> 234 </row> 235 236 <row> 237 <entry><code>base_type<S>::type</code></entry> 238 239 <entry>T</entry> 240 241 <entry><para>Retrieve the base type of a given safe 242 type.</para></entry> 243 </row> 244 245 <row> 246 <entry><code>base_value(s)</code></entry> 247 248 <entry>T</entry> 249 250 <entry><para>Retrieve the value of an instance of a safe type. 251 This is equivalent to 252 <code>static_cast<base_type<S>>(s)</code>.</para></entry> 253 </row> 254 </tbody> 255 </tgroup> 256 </informaltable></para> 257 258 <itemizedlist> 259 <listitem> 260 <para>The result of any binary operation where one or both of the 261 operands is a SafeNumeric type is also a SafeNumeric type.</para> 262 </listitem> 263 264 <listitem> 265 <para>All the expressions in the above table are 266 <code>constexpr</code> expressions.</para> 267 </listitem> 268 269 <listitem> 270 <para>Binary expressions which are not assignments and whose operands 271 are both safe types require that promotion and exception policies of 272 the operands be identical.</para> 273 </listitem> 274 275 <listitem> 276 <para><code>Operations on safe types are supported if and only if the 277 same operation is supported on the underlying types. For example, the 278 binary operations |</code>, <code>&</code>, <code>^</code> and 279 <code>~</code> operations defined for safe unsigned integer types. But 280 they are not defined for floating point types. Currently the are also 281 defined for signed integer types. It's not clear that this is the 282 correct decision. On one hand, usage of these operators on signed 283 types is almost certainly an error in program logic. But trapping this 284 as an error conflicts with the goal of making safe types "drop-in" 285 replacements for the corresponding built-in types. In light of this, 286 these operators are currently supported as they are for normal 287 built-in types.</para> 288 </listitem> 289 290 <listitem> 291 <para>Safe Numeric types will be implicitly converted to built-in 292 types when appropriate. Here's an example:<programlisting>void f(int); 293 294int main(){ 295 long x; 296 f(x); // OK - builtin implicit version 297 safe<long> y; 298 f(y); 299 return 0; 300}</programlisting>This behavior supports the concept of 301 <code>safe<T></code> as being a "drop-in" replacement for a 302 <code>T</code>.</para> 303 </listitem> 304 </itemizedlist> 305 </section> 306 307 <section> 308 <title>Invariants</title> 309 310 <para>The fundamental requirement of a SafeNumeric type is that it 311 implements all C++ operations permitted on its base type in a way the 312 prevents the return of an incorrect arithmetic result. Various 313 implementations of this concept may handle circumstances which produce 314 such results differently (throw exception, compile time trap, etc..). But 315 no implementation should return an arithmetically incorrect result.</para> 316 </section> 317 318 <section> 319 <title>Models</title> 320 321 <para><code>safe<T></code></para> 322 323 <para><code>safe_signed_range<-11, 11></code></para> 324 325 <para><code>safe_unsigned_range<0, 11></code></para> 326 327 <para><code>safe_signed_literal<4></code></para> 328 </section> 329 330 <section> 331 <title>Header</title> 332 333 <para><ulink 334 url="../../include/boost/safe_numerics/concept/safe_numeric.hpp"><code>#include 335 <boost/numeric/safe_numerics/concepts/safe_numeric.hpp></code></ulink></para> 336 </section> 337</section> 338