<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>N2779 Concepts for Clause 18: Part 2</title>
  <base href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/" />
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <style type="text/css">
    /* <![CDATA[*/
      address {text-align: right}
      p {text-align:justify}
      li {text-align:justify}
      ins {background-color:#FFFF99}
      del {background-color:#FF9999}
    /* ]]> */
  </style>
</head>
<body>
  <address>
    Document number: N2779=08-0289<br />
    <br />
    <a href="mailto:alisdair.meredith@codegear.com">Alisdair Meredith</a><br />
    2008-09-17
  </address>
  <hr />
    
<h1>Concepts for Clause 18: Part 2</h1>
<p>
The original paper reviewing the language support library for application of 
concepts was <a href="2008/n2619.pdf">N2619</a>.  At the time the feature
was not understood well enough (by the author) to support the 
<code>numeric_limits</code> class template.  In addition, the class template
<code>initializer_list</code> has been added.  This paper suggests constraints
for both templates.
</p>

<h2>Basic Analysis</h2>

<h3>Numeric limits</h3>
<p>
There is a clear desire to use <code>numeric_limits</code> from generic code,
as its key reason to exist is for code dealing with an arbitrary type to
probe for information.
</p>
<p>
An early mis-understanding in trying to understand this template is that there
are really no constaints on the member functions themselves.  While it is
difficult to work out the necessary operations to compute the limitting values
for arbitrary types, that is not how this template works.  Instead, the
basic implementation returns default values regardless of type, and an explicit
specialization is expected for any type that is to be fully supported. Said
specializations are not constrained to list the operations used in their
implementations, as the specialization is effectively a regular class - there
are no dependant names to look up.
</p>
<p>
There was some thought about defining a <code>NumericLimitType</code> concept
so that default implementation could be supplied for the new members added to
the <code>numeric_limits</code> template that could be found for valid
specializations according to the 03 specification.  However, this seems a lot
of work for a look-up that will only occur in constrained contexts, for the
benefit of a couple of functions.  A better approach would be to properly
decompose the numeric limits notion into a family of concepts that would
solve a more complete set of problems.  That analysis is beyond this paper.
</p>
<p>
Finally, in order to constrain the <code>numeric_limits</code> template a
reasonable requirement has to be chosen.  The author has selected
<code>RegularType</code> as possessing the right set of value-like
properties to represent an object that might be useful in a context
that we would want to query its numerical properties.  This is also
a minimal set, to make implementation of the base template reasonable
without further constraints.
</p>

<h3>Initializer lists</h3>
<p>
Initializer lists were added to support a unified syntax for initialization
at the Sophia-Antipolis meeting, 2008.  In order to support this syntax
in constrained contexts, a minimal useful requirement is placed upon the
template.
</p>
<p>
A further language feature targetting adoption in the CD to be issued from
the San Francisco meeting, 2008 is an enhanced for-loop syntax.  This syntax
will be supported for <code>initializer_list</code>s by providing a
concept_map for the <code>Range</code> concept.
</p>
<p>
Finally, the <code>Container</code> concept can also be supported by
<code>initializer_list</code> with the addition of a few simple typedefs,
at least one of which is also needed to support the <code>Range</code>
concept.
</p>

<h2>Proposed Wording</h2>

<p>
Update 18.2.1.1 Class template numeric_limits [numeric.limits]
</p>
<pre>
namespace std {
  template&lt;<del>class</del><ins>Regular</ins> T> class numeric_limits {
  public:
    static constexpr bool is_specialized = false;
    static constexpr T min() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T max() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T lowest() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr int digits = 0;
    static constexpr int digits10 = 0;
    static constexpr int max_digits10 = 0;
    static constexpr bool is_signed = false;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact = false;
    static constexpr int radix = 0;
    static constexpr T epsilon() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T round_error() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr int min_exponent = 0;
    static constexpr int min_exponent10 = 0;
    static constexpr int max_exponent = 0;
    static constexpr int max_exponent10 = 0;
    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss = false;
    static constexpr T infinity() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T quiet_NaN() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T signaling_NaN() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr T denorm_min() throw()<del>;</del><ins> { return T(); }</ins>
    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = false;
    static constexpr bool is_modulo = false;
    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };
...
}
</pre>

<p>
Update 18.8 Initializer lists [support.initlist]p1
</p>
<h3>Header &lt;initializer_list> synopsis</h3>
<pre>
namespace std {
  template&lt;<del>class</del><ins>ObjectType</ins> E> class initializer_list {
  public:
    <ins>typedef E value_type;</ins>
    <ins>typedef const E& reference;</ins>
    <ins>typedef const E& const_reference;</ins>
    <ins>typedef size_t size_type;</ins>

    <ins>typedef const E * iterator;</ins>
    <ins>typedef const E * const_iterator;</ins>

    initializer_list();
    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
  };

  template&lt;ObjectType T> concept_map Range&lt;initializer_list&lt;T>> {
    const T * begin( initializer_list&lt;T> c ) { return c.begin(); }
    const T * end( initializer_list&lt;T> c ) { return c.end(); }
  };
}
</pre>
</body>
</html>
