<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Standard exception information types for std::exception</title>
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"></meta>
    <meta http-equiv="Content-Language" content="en-us"></meta>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
  </head>
  <body>
    <address>
      Document number: N3758
    </address>
    <address>
      Programming Language C++, Library Subgroup
    </address>
    <address>
      &nbsp;
    </address>
    <address>
      Emil Dotchevski, <a href="mailto:emil@revergestudios.com">emil@revergestudios.com</a>
    </address>
    <address>
      &nbsp;
    </address>
    <address>
      2013-08-30
    </address>
    <h1>
      Standard exception information types for <code>std::exception</code>
    </h1>
    <ul>
      <li>
        <a href="#overview">Overview</a>
      </li>
      <li>
        <a href="#motivation">Motivation</a>
      </li>
      <li>
        <a href="#impact">Impact</a>
      </li>
      <li>
        <a href="#text">Proposed text</a>
      </li>
      <li>
        <a href="#implementability">Implementability</a>
      </li>
    </ul>
    <h2>
      <a name="overview">I. Overview</a>
    </h2>
    <p>
      This proposal defines standard exception information types compatible with N3757.
    </p>
    <h2>
      <a name="motivation">II. Motivation</a>
    </h2>
    <p>
      Defining standard exception information types improves compatibility between programs and libraries that throw and/or handle exceptions.
    </p>
    <h2>
      <a name="impact">III. Impact</a>
    </h2>
    <p>
      Defining standard exception information types as proposed supplements N3757 and does not affect any other parts of the standard library.
    </p>
    <h2>
      <a name="text">IV. Proposed Text</a>
    </h2>
    <p>
        In the standard header <code>&lt;exception&gt;</code> add the following type definitions in namespace <code>std</code> (refer to
        N3757 for the definition of <code>set&lt;&gt;</code>):
    </p>
    <table border="1" cellpadding="10px" cellspacing="0">
        <tr>
            <th>Type</th>
            <th>Description</th>
        </tr>
        <tr>
            <td><pre>struct errinfo_throw_function
{
  typedef char const * type;
};

struct errinfo_throw_file
{
  typedef char const * type;
};

struct errinfo_throw_line
{
  typedef int type;
};</pre></td>
            <td>
                <p>These types specify the name of the function, the source file name and line number containing the <code>throw</code> statement
                that emitted the exception, as if <code>__PRETTY_FUNCTION__</code>, <code>__FILE__</code> and <code>__LINE__</code> are
                passed separately to <code>std::exception::set&lt;&gt;</code> at the point of the <code>throw</code>. Implementations are encouraged,
                but not required, to include this information automatically in all exceptions of types that derive from <code>std::exception</code>.</p>
              </td>
        </tr>
        <tr>
            <td><pre>struct errinfo_api_function
{
  typedef char const * type;
};</pre></td>
            <td>
                <p>Used when throwing exceptions in case a call to a no-throw API function fails, to indicate the name of that function. For example:</p>
                <pre>fread(ptr,size,count,f);
if( ferror(f) )
{
  file_error e; //derives from std::exception
  e.set&lt;errinfo_api_function&gt;("fread");
  throw e;
}
                </pre>
            </td>
        </tr>
        <tr>
            <td><pre>struct errinfo_file_name
{
  typedef std::string type;
};</pre></td>
            <td><p>Specifies a relevant file name for exceptions used to report file errors, using UTF-8 encoding. Example:</p>
            <pre>try
{
  FILE * f=fopen("name","rb");
  if( !f )
    throw file_open_error(); //derives from std::exception
  .....
}
catch( std::exception &amp; e )
{
  e.set&lt;errinfo_file_name&gt;("name");
  throw;
}</pre>
            </td>
        </tr>
        <tr>
            <td><pre>struct errinfo_fileno
{
  typedef int type;
};

struct errinfo_file
{
  typedef FILE * type;
};</pre></td>
            <td><p>These types can be used to specify a relevant file descriptor or <code>FILE</code> pointer in exceptions used to report file errors.
                One possible use case is in contexts that operate on more than one file, to determine the correct file name to pass to <code>set&lt;errinfo_file_name&gt;</code>
                depending on the file information reported by a lower level function.
                </p></td>
        </tr>
        <tr>
            <td><pre>struct errinfo_errno
{
  typedef errno_code type;
};</pre>
                <p>where <code>errno_code</code> is defined as:</p>
                <pre>struct errno_code
{
  int value;
  errno_code(int value):
    value(value)
  {
  }
};</pre></td>
            <td>
                <p>
                    Specifies a relevant <code>errno</code> code (note the implicit conversion from <code>int</code>.) The <code>errno_code</code> type
                    is a wrapper needed to convert the <code>errno</code> code to string for the purposes of <code>std::exception::diagnostic_information</code>
                    (see N3757), for example by the following accessible <code>operator&lt;&lt;</code> overload (or equivalent):
                </p>
                <pre>ostream &amp; operator&lt;&lt;( ostream &amp; _S, errno_code const &amp; _X )
{
  return _S &lt;&lt; _X.value &lt;&lt; '(' &lt;&lt; strerror(_X.value) &lt;&lt; ')';
}</pre>
            </td>
        </tr>
    </table>
    <h2>
      <a name="implementability">V. Implementability</a>
    </h2>
    <p>
        A proof of concept implementation for N3757 is available in Boost. See boost/exception/N3757.hpp and libs/exception/test/N3757_test.cpp
        in <a href="http://svn.boost.org/svn/boost/trunk">http://svn.boost.org/svn/boost/trunk</a>.
    </p>
  </body>
</html>