<!-- saved from url=(0022)http://internet.e-mail -->
<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>I</title>
</head>

<body>

  <p><b>Author:</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  Fernando Cacciola<br>
  <b>Contact:</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mailto:fernando.cacciola@gmail.com">fernando.cacciola@gmail.com</a><br>
  <b>Organization:&nbsp;&nbsp;&nbsp; </b>SciSoft<br>
  <b>Date:</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2005-08-29<br>
  <b>Number:</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  N1879=05-0139</p>
  <h1>A proposal to add a general purpose ranged-checked numeric_cast&lt;&gt; (Revision 1)</h1>
  <h1><b><i>Motivation and Scope</i></b></h1>
  <p>An <b>out-of-range</b> conversion occurs when a source value cannot be 
  presented in a destination type, not even approximately between 2 adjacent 
  destination values. </p>
  <p>If the destination type is unsigned, the conversion, even if logically 
  out-of-range, if always defined (4.7.2) as the least congruent unsigned value.</p>
  <p>If the destination type is a signed integer, the result of an out-of-range 
  conversion is implementation-defined (4.7.3).</p>
  <p>If the destination type is floating-point, or the source type is 
  floating-point and the destination type integer, an out-of-range conversion is 
  undefined-behavior (4.8.1,4.9.1).</p>
  <p>Clearly, out-of-range conversions are a problem because they can involve 
  from implementation-defined to undefined behavior. Even signed to unsigned 
  conversion can be a problem because the resulting value, even if well defined, 
  can be as wrong as any arbitrary unrelated value.</p>
  <p>Numerical applications, ranging from sophisticated scientific software to 
  modeling to accounting to simple number manipulation can rarely disregard the 
  problems associated with out-of-range conversions. In consequence, most such 
  applications incorporate ad-hoc out-of-range checking code and protocols.</p>
  <p>Furthermore, most C++ users are unaware of these rules. For instance, most 
  C++ programmers are unaware that an out-of-range floating point conversion is 
  undefined behavior (...and can for instance cause the client's hard disk to 
  be wiped out entirely, as the say goes)</p>
  <p>Generic Programming came into C++ along with the need for a numerical 
  conversion utility providing well-defined behavior for all generic conversion 
  cases (all combinations of source and destination types). So much in fact, 
  that the Boost project launched, 6 years ago, with such an utility as part of 
  its initial offering. </p>
  <p>Whether <code>boost::numeric_cast&lt;&gt;</code> or any other in-house facility, most 
  numerical applications have been using range-checked numeric conversions from 
  a long time.</p>
  <p>But there is a problem: properly determining whether a source value is in 
  range for a given destination type is tricky because involves comparing a 
  value of a type with the boundary values of a different type, task that itself 
  requires a numeric conversion. This is in fact so difficult that <code>boost::numeric_cast&lt;&gt;</code> had it wrong for certain cases for years, even after 
  a number of revisions.</p>
  <p>A <code>numeric_cast&lt;&gt;</code> is therefore a perfect candidate for 
  standardization because 
  it is widely needed but its implementation much too difficult to ask users to 
  roll their own (or <i>need</i> one from a non standard library)</p>
  <p>The <a href="http://www.boost.org/libs/numeric/conversion/doc/index.html">Boost Numeric Conversion Library</a> introduced 
  a re-implementation of <code>boost::numeric_cast&lt;&gt;</code> which using metaprogramming fixed all 
  the range-checking problems of the initial version and even gained 
  compile-time optimizations by totally avoiding the range-check when 
  unnecessary. </p>
  <p>That library, which serves as a reference implementation, developed the 
  right concepts that are needed to formulate a proper range-checking logic for 
  any combination of types (that is, a formulation that prevents the conversions 
  needed by the check itself to be out-of-range). It also shown that 
  template-metaprogramming can be used to optimize away the range-checking when 
  unneeded.</p>
  <p>The Boost library uses a policy-based design that offers users a wide 
  latitude of choices (user-defined-types support, custom out-of-range handling, 
  float to integer rounders, etc), but the facility proposed in this paper for 
  standardization is a simplified version more in the spirit of the original 
  <code>boost numeric_cast&lt;&gt;</code></p>
  <p>The proposed <code>numeric_cast&lt;T&gt;(s)</code> shall give the same result as 
  <code>static_cast&lt;T&gt;(s)</code> (that is, the conversion itself is a just standard 
  conversion) but with an added out-of-range check which implementations are 
  required to bypass if unneeded (the proposed text defines exactly when is this 
  the case). The out-of-range check is itself performed separately by 
  another proposed function: <code>bool is_out_of_range&lt;T&gt;(s)</code> which users can call if they 
  need a domain-specific out-of-range response. If <code>numeric_cast&lt;T&gt;(s)</code> detects an 
  out of range condition, an out-of-range <i>installable handler</i> is called.</p>
  <h1><i><b>Impact On the Standard</b></i></h1>
  <p>The proposed text is intended to allow upcoming numeric types like 
  decimal types, big integers, rationals, etc to be usable with the facility. 
  To that effect, the proposed text includes some definitions which encompasses these 
  eventually-standard types. Additionally, the proposed text intends to allow a 
  C++ program to extend the standard <code>numeric_cast&lt;&gt;</code> for user-defined-types.</p>
  <p>Nonetheless, even though the facility must interact with other pieces of 
  the standard, the proposal takes the form of a pure extension. There are only 
  additions. </p>
  <h1><b><i>Design Decisions</i></b></h1>
  <h2>Features:</h2>
  <p>The fundamental need that this proposal aims to satisfy is providing 
  range-checked <i>standard</i> conversions because range checking is a general 
  need in a wide range of application domains. But there are other needs: for 
  example, in converting a floating-point type to an integer type it might be 
  critical to be able to control how the fractional part is handled (instead of 
  simply discarding it as a standard conversion does), or maybe an application 
  needs to trap <i>inexact</i> (but in-range) conversions (when the source value is 
  represented as one of the two adjacent values in the destination type); or 
  &quot;fix&quot; out of range conversions by choosing the closest boundary value in the 
  destination type. Yet from all this features, range checking is the only one 
  that doesn't need to redefine the conversion itself because it can be provided as 
  a <i>precondition</i> to a standard conversion.</p>
  <p>It is certainly possible to design a facility to give users further control 
  over the conversion process. To some extent, C99 and the 
  <a href="http://www.boost.org/libs/numeric/conversion/doc/index.html">Boost Numeric Conversion Library</a> 
  do that. However, the pieces that would be directly involved and affected are 
  yet to be standardized (additions from C99, additional numeric types, like 
  decimal, integer, rational, etc..) so is more convenient to take it one step 
  at a time and standardize at this point only the simplest solution to the more 
  general problem: range checking.</p>
  <h2>Interface:</h2>
  <p>A policy-based design like that used in the Boost Numeric Conversion 
  library is certainly a reasonable way to give users the extra latitude, but 
  such designs has as a drawback that the resulting behavior is on the hands of 
  the users. For such a fundamental part of a language as its standard library, 
  just carefully specifying the requirements and expected behavior for the 
  policies is simply not enough. There is no discussion about the potential and 
  usefulness of policies, but the actual instrumentation of such designs needs 
  tools from the language, like concepts and design-by-contract forms, which are 
  not yet available (but these have been already formally proposed). Thus, the 
  policy-based design of the Boost version has been dropped in favor of a 
  simpler but better defined facility.</p>
  <h2>Out of range response:</h2>
  <p>The canonical way to treat exceptional errors in C++ is by throwing an 
  exception. However, numeric conversions are specially important in numeric 
  applications and numeric applications are particularly common in restricted 
  platforms like embedded systems. In consequence, always throwing an exception in 
  the presence of an out-of-range conversion is unlikely to be welcome by the 
  numerical community which is intended to be a primary target. Thus, the 
  proposed solution uses an <i>installable handler</i> (like the new handler) so 
  that implementations and programs can customize the out-of-range response to 
  suit the target platform.</p>
  <h2>Types supported:</h2>
  <p>At this point in the C++ standard life-cycle, a number of numeric types are 
  being proposed. This proposal assumes that at least some of these types will 
  be accepted so it tries to cover the conversions involving not only <i>
  arithmetic types</i> but these eventual <i>standard numeric types</i> as well. 
  Since the proposed <code>numeric_cast&lt;&gt;()</code> only adds range checking but doesn't 
  define the conversion itself, the proposal only has to properly cover the 
  range checking logic for any type it intends to specify behavior. To achieve 
  that, the specification of the range checking logic that implementations must 
  follow is formulated with the assumption that the implementation has complete 
  access to the details of these <i>standard numeric types</i>. In particular, 
  the implementation is required to be able to test whether a boundary value of 
  any given <i>standard numeric type</i> is representable in any other given <i>standard numeric type</i>.</p>
  <p>Furthermore, the proposal adds a simple provision to allow C++ programs to 
  make their user-defined-types be usable with <code>numeric_cast&lt;&gt;</code>: they are allowed to 
  provide additional specializations, even partial (assuming the language eventually allows that), of the template function.</p>
  <h1><b><i>Proposed Text for the Standard</i></b></h1>
  <p><i>A</i>.&nbsp;&nbsp;&nbsp; Add the following to 17.4.3.5 [lib.handler.functions]</p>
  <ol>
    <li><code>out_of_range_handler</code></li>
    <li><code>set_of_out_range_handler</code></li>
  </ol>
  <p><i>B</i>. Add the following to the synopsis for &lt;numeric&gt; at 26.4, 
  [lib.numeric.ops]</p>
  <pre>template&lt;class T, class S&gt; bool is_out_of_range ( S s ) throw() ;</pre>
  <pre>template&lt;class T, class S&gt; T numeric_cast ( S s ) <code>throw ( range_error ) </code>;</pre>
  <p><i>C</i>. Add the following subclauses:</p>
  <h4>17.1.21 Numeric type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.numeric.type]</h4>
  <p>any type which satisfies the <i>numeric type requirements</i> (26.1)</p>
  <p>&nbsp;[<i>Note:</i> a user defined type can fit this definition <i>-end 
  note</i>]</p>
  <h4>17.1.22 Standard numeric type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.numeric.type.std]</h4>
  <p>any <i>numeric type</i> (17.1.21) defined in this standard, including 
  library provided types such as complex&lt;&gt;</p>
  <h4>17.1.23 Numeric conversion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.numeric.conversion]</h4>
  <p>any conversion, standard or user defined, involving <i>numeric types</i> 
  (17.1.21) </p>
  <h4>17.1.24 Standard numeric conversion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.numeric.conversion.std]</h4>
  <p>any <i>numeric conversion</i> (17.1.23) involving <i>standard numeric types</i> 
  (17.1.22)</p>
  <h4>17.1.25 Super-ranged conversions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.numeric.conversion.superranged]</h4>
  <p><i>standard numeric conversions</i> from any value of a<i> standard numeric type</i> (17.1.2) S to a 
  value of a&nbsp; <i>standard numeric 
  type</i> T such that either numeric_limits&lt;T&gt;::is_bounded==false, or both <code>numeric_limits&lt;S&gt;::lowest()</code><sup><a href="#footnote1" style="text-decoration: none">1</a></sup><code> and   numeric_limits&lt;S&gt;::max()</code> 
  can be represented in the type T, either exactly or between two adjacent T 
  values. That is, conversions for which any value of the source type can be 
  represented in the destination type.</p>
  <h4>17.1.26 Sub-ranged conversion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [defs.subranged]</h4>
  <p><i>standard numeric conversions</i> from any value of a<i> standard numeric type</i> (17.1.2) S to a 
  value of a&nbsp; <i>standard numeric 
  type</i> T such that mumeric_limits&lt;T&gt;::is_bounded==true and&nbsp; <code>numeric_limits&lt;S&gt;::lowest()</code><sup><a href="#footnote1" style="text-decoration: none">1</a></sup><code> 
  or   numeric_limits&lt;S&gt;::max()</code> 
  cannot be represented in the type T, neither exactly nor between two adjacent T 
  values. That is, conversions for which some values of the source type cannot 
  be represented in the destination type.<br>
  If conversions from S to T are <i>sub-ranged</i>, then necessarily, 
  conversions in the opposite direction, T-&gt;S, are <i>super-ranged</i>. The 
  converse is not necessarily true (for example, a conversion from N-&gt;N is 
  super-ranged in both directions)</p>
  <h4>18.7.1 Type out_of_range_handler&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [lib.support.runtime.outofrange]</h4>
  <pre>typedef void (*out_of_range_handler)();</pre>
  <p>1.&nbsp;&nbsp;&nbsp; The type of the <i>handler function</i> called by 
  numeric_cast&lt;&gt; (26.4.5) when an out of range is detected</p>
  <p>2.&nbsp;&nbsp;&nbsp; Required behavior: an <i>out_of_range_handler</i> 
  shall perform one of the following::</p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - throw an exception of type <i>
  range_error</i> (19.1.7) or a class derived from <i>
  range_error</i></p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - call either abort() or exit()</p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - return</p>
  <p>3.&nbsp;&nbsp;&nbsp; An out of range handler installed by a program or the implementation is allowed to 
  perform additional operations, with side effects, prior to the required 
  operation, provided they do not incur undefined behavior.</p>
  <p>&nbsp;&nbsp;&nbsp; [<i>Note:</i> allowing additional operations is intended 
  to let a C++ program properly register and report the incident; not to attempt to 
  recover from the error <i>-endnote</i>] </p>
  <h4>18.7.2 set_out_of_range_handler&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [lib.support.runtime.set.outofrange]</h4>
  <pre>out_of_range_handler set_out_of_range_handler( out_of_range_handler new_h ) throw() ;</pre>
  <p>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;	<i>Effects:</i> Establishes the function designated by <i>new_h</i> as the current <i>out_of_range_handler</i>.</p>
  <p>2.	<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Returns:</i> 0 on first call, the previous out_of_range_handler on subsequent calls.</p>
  <h4>26.4.5 Out of range check&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [lib.numeric.outofrangecheck]</h4>
  <pre>template&lt;class T, class S&gt; bool is_out_of_range ( Source s ) throw() ;</pre>
  <p>1.&nbsp;&nbsp;&nbsp; Returns:  </p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A. If conversions from S 
  to T are <i>super-ranged</i> (17.1.22), false for any value of s [<i>Note</i>: 
  this case can only be applied if both T and S are <i>standard 
  numeric types </i>(17.1.22), per definition of <i>super-ranged</i>&nbsp; <i>
  -end note</i>]</p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B. If conversions from S 
  to T are <i>sub-ranged</i>&nbsp; (17.1.23); the result of evaluating this 
  expression:</p>
  <p>
  <code>   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;   (s &gt;= static_cast&lt;S&gt;(numeric_limits&lt;T&gt;::lowest())</code><sup><a href="#footnote1" style="text-decoration: none">1</a></sup><code><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &amp;&amp;  (s &lt;= static_cast&lt;S&gt;(numeric_limits&lt;T&gt;::max&nbsp;&nbsp; ()).</code></p>
  <p>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<i>Note</i>: 
  this case can only be applied if both S and T are <i>standard numeric types
  </i>(17.1.22), per definition of <i>sub-ranged</i>&nbsp; <i>-end note</i>]</p>
  <p>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<i>Note</i>: 
  when S-&gt;T are <i>sub-ranged</i>; T-&gt;S are <i>super-ranged</i> so the expression can be 
  evaluated without incurring undefined behavior]</p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C.If either S or t are not <i>
  standard numeric types </i>(17.1.22), an unspecified 
  result.</p>
  <p>2.&nbsp;&nbsp;&nbsp; A C++ program is allowed to defined specializations of 
  this template function provided that S or T or both are<i> 
  user-defined-types. </i>If both S and T are <i>standard 
  numeric type </i>(17.1.22)<i> </i>the specializations ill-formed and the implementation is 
  required to issue diagnostic.</p>
  <h4>26.4.6 Numeric_cast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  [lib.numeric_cast]</h4>
  <p>
  <code>   template&lt;class T, class S&gt; T numeric_cast( S s ) throw ( 
  range_error );</code></p>
  <p>1.&nbsp;&nbsp;&nbsp;&nbsp; The result of the expression <code>numeric_cast&lt;T&gt;(s)</code> 
  is the same as the result of the expression <code>static_cast&lt;T&gt;(s)</code> with the 
  following added restrictions and side-effects:</p>
  <p>2.&nbsp;&nbsp;&nbsp; If either S or T are not <i>standard numeric types </i>(17.1.22), the 
  behavior is unspecified 
  if there exist in the program a user-provided specialization of the function 
  for&nbsp; these types and undefined if such a user-provided specialization 
  does not exist.</p>
  <p>4.&nbsp;&nbsp;&nbsp; If 
  conversions from S to T are <i>sub-ranged</i> (17.1.23), is_out_of_range&lt;T&gt;(s) shall be 
  called and if the result of that is true, the installed out_of_range-handler 
  shall be invoked, if any. </p>
  <p>5.&nbsp;&nbsp;&nbsp; If  
  conversions from S to T are <i>super-ranged</i> (17.1.22), is_out_of_range&lt;T&gt;(s) shall 
  <i>not</i> be called and numeric_cast&lt;T&gt;(s) shall be distinguishable from static_cast&lt;T&gt;(s) only in the additional type requirements. That is, 
  implementations are required to skip the overhead of range checking for 
  super-ranged conversions.</p>
  <p>6.&nbsp;&nbsp;&nbsp; A C++ program is allowed to defined specializations of 
  this template function provided that S or T or both are<i> 
  user-defined-types. </i>If both S and T are <i>standard 
  numeric type </i>(17.1.22)<i> </i>the specialization is ill-formed and the implementation is 
  required to issue a diagnostic.</p>
  <p>7.&nbsp;&nbsp;&nbsp; The implementation is allowed to implement 
  <code>numeric_cast&lt;&gt;</code> as an internal operator and not as a explicit library function 
  provided it can diagnose a violation to subclause 6 in case a C++ programs 
  adds specializations.</p>
  <p><u>Footnotes: </u></p>
  <ol>
    <a name="footnote1"></a><li><i>lowest() is the addition to numeric_limits&lt;&gt; 
    proposed in N1881</i></li> (which accompanies this proposal)<a name="footnote2"></a></ol>
  <h1><b><i>Acknowledgements</i></b></h1>
  <p>All the people in the boost community, particularly those involved in the 
  development of the Boost.NumericConversion library.</p>
  <p>Thorsten Ottosen for his help preparing this proposal.</p>
  <h1><b><i>References</i></b></h1>

  <ol>
    <li>Boost.Numeric Conversion Library, 
  <a href="http://www.boost.org/libs/numeric/conversion/doc/index.html">http://www.boost.org/libs/numeric/conversion/doc/index.html</a>, Fernando Cacciola</li>
    <li>Standard Documents:
    <ol>
      <li>ISO/IEC 9899:1999 (C99 Standard) </li>
      <li>ISO/IEC 10967-1 (Language Independent Arithmetic (LIA), Part I, 1994)
      </li>
      <li>ISO/IEC 2382-1:1993 (Information Technology - Vocabulary - Part I: 
      Fundamental Terms) </li>
      <li>ANSI/IEEE 754-1985 [and IEC 60559:1989] (Binary floating-point) </li>
      <li>ANSI/IEEE 854-1988 (Radix Independent floating-point) </li>
      <li>ANSI X3/TR-1-82 (Dictionary for Information Processing Systems) </li>
      <li><a href="http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n753.htm">
      ISO/IEC JTC1/SC22/WG14/N753</a> C9X Revision Proposal: LIA-1 Binding: 
      Rationale </li>
    </ol>
    </li>
    <li>Papers:
    <ol>
      <li>David Goldberg
      <a href="http://citeseer.nj.nec.com/goldberg91what.html">What Every 
      Computer Scientist Should Know About Floating-Point Arithmetic</a> </li>
      <li><a href="http://www.cs.berkeley.edu/~wkahan/">Prof. William Kahan</a> 
      papers on floating-point. </li>
    </ol>
    </li>
  </ol>

</body>

</html>