﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>N3252 - A review of noexcept in the threads library</title>

  <style type="text/css">
    p {text-align:justify}
    li {text-align:justify}
    ins {background-color:#A0FFA0}
    del {background-color:#FF6666}
    
    tr.TITLE_ROW {text-align: center; font-weight: bold}
    tr.DELETED {background: #FF6666; text-decoration: line-through}
    tr.INSERTED {background: #FFFF99}
  </style>

  </head>

  <body>
<address>Document number: N3252=11-0022<br/>
  Date: 2011-02-26<br/>
  J. Daniel Garcia, Michael Wong<br/>
  Project: Programming Language C++, Library Working Group<br />
  Reply To: <a href="mailto:josedaniel.garcia@uc3m.es">josedaniel.garcia@uc3m.es</a>
</address>
 
<hr/>

<h1>N3252 - A review of noexcept in the threads library</h1>

<p>This paper studies possible changes to the Threads Library to make broad use of noexcept. The paper 
addresses National Body comments CH 16 and GB 60.</p>

<p>
Changes in this paper are <b>restricted to chapter 30</b> (threads library).
</p>

<p>
All changes in this paper are relative to N3225.
</p>

<h2>Discussion</h2>

<p>Several <tt>swap()</tt> functions have been made <tt>noexcept</tt> as the are defined in terms of the corresponding <tt>noexcept</tt> member function.</p>

<p>In 30.4.1 <tt>mutex</tt>, <tt>recursive_mutex</tt>, <tt>timed_mutex</tt> and <tt>recursive_timed_mutex</tt> constructors have been made <tt>noexcept</tt>

In section 30.6.1 some operations have been made <tt>noexcept</tt> to be consistent with the disgnostics library.

In section 30.6.10 member function <tt>valid</tt> is not consistent with its definition in 30.6.10.1. It has been updated.


<h1>Proposed Wording</h1>

<h2>30.3 Threads [thread.threads]</h2>

After p. 1

<pre>
namespace std {
  #define __STDCPP_THREADS__ __cplusplus

  class thread;

  void swap(thread&amp; x, thread&amp; y)<ins> noexcept</ins>;

  namespace this_thread {
    thread::id get_id()<ins> noexcept</ins>;
    void yield()<ins> noexcept</ins>;
    template &lt;class Clock, class Duration&gt;
      void sleep_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time)<ins> noexcept</ins>;
  template &lt;class Rep, class Period&gt;
    void sleep_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time)<ins> noexcept</ins>;
  }
}
</pre>

<h2>30.3.1.7 thread specialized algorithms [thread.thread.algorithm]</h2>

Before p.1

<pre>void swap(thread&amp; x, thread&amp; y)<ins> noexcept</ins>;</pre>

<h2>30.4.1.2.1 Class mutex [thread.mutex.class]</h2>

Before p. 1
<pre>
namespace std {
  class mutex {
  public:
    constexpr mutex()<ins> noexcept</ins>;
    ~mutex();

    mutex(const mutex&amp;) = delete;
    mutex&amp; operator=(const mutex&amp;) = delete;

    void lock();
    bool try_lock() noexcept;
    void unlock() noexcept;

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}
</pre>

<h2>30.4.1.2.2 Class recursive_mutex [thread.mutex.recursive]</h2>

Before p.1
<pre>
namespace std {
  class recursive_mutex {
  public:
    recursive_mutex()<ins> noexcept</ins>;
    ~recursive_mutex();

    recursive_mutex(const recursive_mutex&amp;) = delete;
    recursive_mutex&amp; operator=(const recursive_mutex&amp;) = delete;

    void lock();
    bool try_lock() noexcept;
    void unlock() noexcept;

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}
</pre>

<h2>30.4.1.3.1 Class timed_mutex [thread.timedmutex.class]</h2>

Before p. 1
<pre>
namespace std {
  class timed_mutex {
  public:
    timed_mutex()<ins> noexcept</ins>;
    ~timed_mutex();

    timed_mutex(const timed_mutex&amp;) = delete;
    timed_mutex&amp; operator=(const timed_mutex&amp;) = delete;

    void lock();
    bool try_lock();
    template &lt;class Rep, class Period&gt;
      bool try_lock_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) noexcept;
    template &lt;class Clock, class Duration&gt;
      bool try_lock_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) noexcept;
    void unlock();

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}
</pre>

<h2>30.4.1.3.2 Class recursive_timed_mutex [thread.timedmutex.recursive]</h2>

Before p. 1
<pre>
namespace std {
  class recursive_timed_mutex {
  public:
    recursive_timed_mutex()<ins> noexcept</ins>;
    ~recursive_timed_mutex();

    recursive_timed_mutex(const recursive_timed_mutex&amp;) = delete;
    recursive_timed_mutex&amp; operator=(const recursive_timed_mutex&amp;) = delete;

    void lock();
    bool try_lock();
    template &lt;class Rep, class Period&gt;
      bool try_lock_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) noexcept;
    template &lt;class Clock, class Duration&gt;
      bool try_lock_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) noexcept;
    void unlock();

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}
</pre>
<h2>30.6.2 Error handling</h2>

Before p.1
<pre>const error_category&amp; future_category()<ins> noexcept</ins>;</pre>

After p. 2
<pre>error_code make_error_code(future_errc e)<ins> noexcept</ins>;</pre>

After p. 3
<pre>error_condition make_error_condition(future_errc e)<ins> noexcept</ins>;</pre>

<h2>30.6.5 Class template promise [futures.promise]</h2>

After p. 27
<pre>
template &lt;class R&gt;
  void swap(promise&lt;R&gt;&amp; x, promise&lt;R&gt;&amp; y)<ins> noexcept</ins>;
</pre>

<h2>30.6.10 Class template packaged_task [futures.task]</h2>

After p.2
<pre>
namespace std {
template&lt;class R, class... ArgTypes&gt;
class packaged_task&lt;R(ArgTypes...)&gt; {
public:
...
  bool valid() const<ins> noexcept</ins>;
...
</pre>

</body>
</html>
