<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>N3251- noexcept for the Atomics 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: N3251=11-0021<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:michaelw@ca.ibm.com">michaelw@ca.ibm.com</a>
</address>

<h1>noexcept for the Atomics Library</h1>

<p>This paper suggest changes to the Atomics operations
Library to make broad use of <tt>noexcept</tt>. The paper
addresses National Body comments CH 16 and GB 60.</p>

<p>Changes in this paper are <b>restricted to chapter 29</b> (Atomic operations
library). </p>

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

<h2>Discussion</h2>

<p>All atomic operations should be amended with <tt>noexcept</tt> with the exception of deleted operations. We have
enumerated the changes but we could also just advise the editor to append <tt>noexcept</tt> to all operations except deleted operations.

<h2>Acknowledgments</h2>

<p>We wish to thank Lawrence Crowl and Paul Mckenney for their comments.</p>

<h1>Proposed Wording</h1>

<p>1. Modify as follows:</p>

<h2>29.2 Header <atomic> synopsis [atomics.syn]</h2>

Modifiy synopsis as follows

<pre>
namespace std {
  // 29.3, order and consistency
  enum memory_order;
  template &lt;class T&gt;
    T kill_dependency(T y)<ins> noexcept</ins>;

  ...

  // 29.6.1, general operations on atomic types
  template &lt;class T&gt;
    bool atomic_is_lock_free(const volatile atomic_type*)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_is_lock_free(const atomic_type*)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_init(volatile atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_init(atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_store(volatile atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_store(atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_store_explicit(volatile atomic_type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    void atomic_store_explicit(atomic_type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_load(const volatile atomic_type*)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_load(const atomic_type*)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_load_explicit(const volatile atomic_type*, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_load_explicit(const atomic_type*, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_exchange(volatile atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_exchange(atomic_type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_exchange_explicit(volatile atomic_type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_exchange_explicit(atomic_type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_weak(volatile atomic_type*, T*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_weak(atomic_type*, T*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_strong(volatile atomic_type*, T*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_strong(atomic_type*, T*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_weak_explicit(volatile atomic_type*, T*, T,
      memory_order, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_weak_explicit(atomic_type*, T*, T.
      memory_order, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare)exchange_strong_explicit(volatile atomic_type*, T*, T,
      memory_order, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    bool atomic_compare_exchange_strong_explicit(atomic_type*, T*, T,
      memory_order, memory_order)<ins> noexcept</ins>;

  // 29.6.2, templated operations on atomic types
  template &lt;class T&gt;
    T atomic_fetch_add(volatile atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_add(atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_add_explicit(volatile atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_add_explicit(atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_sub(volatile atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_sub(atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_sub_explicit(volatile atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_sub_explicit(atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_and(volatile atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_and(atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_and_explicit(volatile atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_and_explicit(atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_or(volatile atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_or(atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_or_explicit(volatile atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_or_explicit(atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_xor(volatile atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_xor(atomic-type*, T)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_xor_explicit(volatile atomic-type*, T, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T atomic_fetch_xor_explicit(atomic-type*, T, memory_order)<ins> noexcept</ins>;

  // 29.6.3, arithmetic operations on atomic types
  template &lt;&gt;
    integral atomic_fetch_add(volatile atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_add(atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_add_explicit(volatile atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_add_explicit(atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_sub(volatile atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_sub(atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_sub_explicit(volatile atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_sub_explicit(atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_and(volatile atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_and(atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_and_explicit(volatile atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_and_explicit(atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_or(volatile atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_or(atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_or_explicit(volatile atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_or_explicit(atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_xor(volatile atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_xor(atomic-integral*, integral)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_xor_explicit(volatile atomic-integral*, integral, memory_order)<ins> noexcept</ins>;
  template &lt;&gt;
    integral atomic_fetch_xor_explicit(atomic-integral*, integral, memory_order)<ins> noexcept</ins>;

  // 29.6.4, partial specializations for pointers
  template &lt;class T&gt;
    T* atomic_fetch_add(volatile atomic&lt;T*&gt;*, ptrdiff_t)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_add(atomic&lt;T*&gt;*, ptrdiff_t)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_add_explicit(volatile atomic&lt;T*&gt;*, ptrdiff_t, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_add_explicit(atomic&lt;T*&gt;*, ptrdiff_t, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_sub(volatile atomic&lt;T*&gt;*, ptrdiff_t)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_sub(atomic&lt;T*&gt;*, ptrdiff_t)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_sub_explicit(volatile atomic&lt;T*&gt;*, ptrdiff_t, memory_order)<ins> noexcept</ins>;
  template &lt;class T&gt;
    T* atomic_fetch_sub_explicit(atomic&lt;T*&gt;*, ptrdiff_t, memory_order)<ins> noexcept</ins>;

  // 29.6.5, initialization
  #define ATOMIC_VAR_INIT(value) see below

  // 29.7, flag type and operations
  struct atomic_flag;
  bool atomic_flag_test_and_set(volatile atomic_flag*)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set(atomic_flag*)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order)<ins> noexcept</ins>;
  void atomic_flag_clear(volatile atomic_flag*)<ins> noexcept</ins>;
  void atomic_flag_clear(atomic_flag*)<ins> noexcept</ins>;
  void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order)<ins> noexcept</ins>;
  void atomic_flag_clear_explicit(atomic_flag*, memory_order)<ins> noexcept</ins>;

  // 29.8, fences
  void atomic_thread_fence(memory_order)<ins> noexcept</ins>;
  void atomic_signal_fence(memory_order)<ins> noexcept</ins>;
}
</pre>

<h2>29.3 Order and Consistency [atomics.order]</h2>

After p. 3, modify as follows:

<pre>
template &lt;class T&gt;
  T kill_dependency(T y)<ins> noexcept</ins>;
</pre>

<h2>29.5 Atomic Types [atomics.types.generic]</h2>

Before p.1, modify as follows:

<pre>
namespace std {
  template &lt;class T&gt; struct atomic {
    bool is_lock_free() const volatile<ins> noexcept</ins>;
    bool is_lock_free() const<ins> noexcept</ins>;
    void store(T, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    void store(T, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    T load(memory_order = memory_order_seq_cst) const volatile<ins> noexcept</ins>;
    T load(memory_order = memory_order_seq_cst) const<ins> noexcept</ins>;
    operator T() const volatile<ins> noexcept</ins>;
    operator T() const<ins> noexcept</ins>;
    T exchange(T, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    T exchange(T, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_weak(T&amp;, T, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(T&amp;, T, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_strong(T&amp;, T, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(T&amp;, T, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_weak(T&amp;, T, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(T&amp;, T, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_strong(T&amp;, T, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(T&amp;, T, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;

    atomic()<ins> noexcept</ins> = default;
    constexpr atomic(T)<ins> noexcept</ins>;
    atomic(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) volatile = delete;
    T operator=(T) volatile<ins> noexcept</ins>;
    T operator=(T)<ins> noexcept</ins>;
  };

  template &lt;&gt; struct atomic&lt;integral&gt; {
    bool is_lock_free() const volatile<ins> noexcept</ins>;
    bool is_lock_free() const<ins> noexcept</ins>;
    void store(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    void store(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral load(memory_order = memory_order_seq_cst) const volatile<ins> noexcept</ins>;
    integral load(memory_order = memory_order_seq_cst) const<ins> noexcept</ins>;
    operator integral() const volatile<ins> noexcept</ins>;
    operator integral() const<ins> noexcept</ins>;
    integral exchange(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral exchange(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_weak(integral&amp;, integral, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(integral&amp;, integral, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_strong(integral&amp;, integral, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(integral&amp;, integral, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_weak(integral&amp;, integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(integral&amp;, integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_strong(integral&amp;, integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(integral&amp;, integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral fetch_add(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral fetch_and(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral fetch_or(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;

    atomic()<ins> noexcept</ins> = default;
    constexpr atomic(integral)<ins> noexcept</ins>;
    atomic(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) volatile = delete;
    integral operator=(integral) volatile<ins> noexcept</ins>;
    integral operator=(integral)<ins> noexcept</ins>;

    integral operator++(int) volatile<ins> noexcept</ins>;
    integral operator++(int)<ins> noexcept</ins>;
    integral operator--(int) volatile<ins> noexcept</ins>;
    integral operator--(int)<ins> noexcept</ins>;
    integral operator++() volatile<ins> noexcept</ins>;
    integral operator++()<ins> noexcept</ins>;
    integral operator--() volatile<ins> noexcept</ins>;
    integral operator--()<ins> noexcept</ins>;
    integral operator+=(integral) volatile<ins> noexcept</ins>;
    integral operator+=(integral)<ins> noexcept</ins>;
    integral operator-=(integral) volatile<ins> noexcept</ins>;
    integral operator-=(integral)<ins> noexcept</ins>;
    integral operator&amp;=(integral) volatile<ins> noexcept</ins>;
    integral operator&amp;=(integral)<ins> noexcept</ins>;
    integral operator|=(integral) volatile<ins> noexcept</ins>;
    integral operator|=(integral)<ins> noexcept</ins>;
    integral operator^=(integral) volatile<ins> noexcept</ins>;
    integral operator^=(integral)<ins> noexcept</ins>;
  };

  template &lt;class T&gt; struct atomic&lt;T*&gt; {
    bool is_lock_free() const volatile<ins> noexcept</ins>;
    bool is_lock_free() const<ins> noexcept</ins>;
    void store(T*, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    void store(T*, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    T* load(memory_order = memory_order_seq_cst) const volatile<ins> noexcept</ins>;
    T* load(memory_order = memory_order_seq_cst) const<ins> noexcept</ins>;
    operator T*() const volatile<ins> noexcept</ins>;
    operator T*() const<ins> noexcept</ins>;
    T* exchange(T*, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    T* exchange(T*, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_weak(T*&amp;, T*, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(T*&amp;, T*, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_strong(T*&amp;, T*, memory_order, memory_order) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(T*&amp;, T*, memory_order, memory_order)<ins> noexcept</ins>;
    bool compare_exchange_weak(T*&amp;, T*, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_weak(T*&amp;, T*, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    bool compare_exchange_strong(T*&amp;, T*, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool compare_exchange_strong(T*&amp;, T*, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst)<ins> noexcept</ins>;

    atomic()<ins> noexcept</ins> = default;
    constexpr atomic(T*)<ins> noexcept</ins>;
    atomic(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) volatile = delete;
    T* operator=(T*) volatile<ins> noexcept</ins>;
    T* operator=(T*)<ins> noexcept</ins>;

    T* operator++(int) volatile<ins> noexcept</ins>;
    T* operator++(int)<ins> noexcept</ins>;
    T* operator--(int) volatile<ins> noexcept</ins>;
    T* operator--(int)<ins> noexcept</ins>;
    T* operator++() volatile<ins> noexcept</ins>;
    T* operator++()<ins> noexcept</ins>;
    T* operator--() volatile<ins> noexcept</ins>;
    T* operator--()<ins> noexcept</ins>;
    T* operator+=(ptrdiff_t) volatile<ins> noexcept</ins>;
    T* operator+=(ptrdiff_t)<ins> noexcept</ins>;
    T* operator-=(ptrdiff_t) volatile<ins> noexcept</ins>;
    T* operator-=(ptrdiff_t)<ins> noexcept</ins>;
  };
}
</pre>

<h2>29.6.5 Requirements for operations on atomic types [atomics.types.operations.req]</h2>

After p. 3, modify as follows:

<pre>
A::A()<ins> noexcept</ins> = default;
</pre>

After p. 4, modify as follows
<pre>
constexpr A::A(C desired)<ins> noexcept</ins>;
</pre>

After p. 6, modify as follows
<pre>
bool atomic_is_lock_free(const volatile A *object)<ins> noexcept</ins>;
bool atomic_is_lock_free(const A *object)<ins> noexcept</ins>;
bool A::is_lock_free() const volatile<ins> noexcept</ins>;
bool A::is_lock_free() const<ins> noexcept</ins>;
</pre>

After p. 7, modify as follows:
<pre>
void atomic_init(volatile A *object, C desired)<ins> noexcept</ins>;
void atomic_init(A *object, C desired)<ins> noexcept</ins>;
</pre>

After p. 8, modify as follows:
<pre>
void atomic_store(volatile A* object, C desired)<ins> noexcept</ins>;
void atomic_store(A* object, C desired)<ins> noexcept</ins>;
void atomic_store_explicit(volatile A *object, C desired, memory_order order)<ins> noexcept</ins>;
void atomic_store_explicit(A* object, C desired, memory_order order)<ins> noexcept</ins>;
void A::store(C desired, memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
void A::store(C desired, memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

After p. 10, modify as follows:
<pre>
C A::operator=(C desired) volatile<ins> noexcept</ins>;
C A::operator=(C desired)<ins> noexcept</ins>;
</pre>

After p. 12, modify as follows:
<pre>
C atomic_load(const volatile A* object)<ins> noexcept</ins>;
C atomic_load(const A* object)<ins> noexcept</ins>;
C atomic_load_explicit(const volatile A* object, memory_order)<ins> noexcept</ins>;
C atomic_load_explicit(const A* object, memory_order)<ins> noexcept</ins>;
C A::load(memory_order order = memory_order_seq_cst) const volatile<ins> noexcept</ins>;
C A::load(memory_order order = memory_order_seq_cst) const<ins> noexcept</ins>;
</pre>

After p. 15, modify as follows:
<pre>
A::operator C () const volatile<ins> noexcept</ins>;
A::operator C () const<ins> noexcept</ins>;
</pre>

After p. 17, modify as follows:
<pre>
C atomic_exchange(volatile A* object, C desired)<ins> noexcept</ins>;
C atomic_exchange(A* object, C desired)<ins> noexcept</ins>;
C atomic_exchange_explicit(volatile A* object, C desired, memory_order)<ins> noexcept</ins>;
C atomic_exchange_explicit(A* object, C desired, memory_order)<ins> noexcept</ins>;
C A::exchange(C desired, memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
C A::exchange(C desired, memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

After p. 19, modify as follows:
<pre>
bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired)<ins> noexcept</ins>;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired)<ins> noexcept</ins>;
bool atomic_compare_exchange_strong(volatile A* object, C * expected, C desired)<ins> noexcept</ins>;
bool atomic_compare_exchange_strong(A* object, C * expected, C desired)<ins> noexcept</ins>;
bool atomic_compare_exchange_weak_explicit(volatile A* object, C * expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool atomic_compare_exchange_weak_explicit(A* object, C * expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool atomic_compare_exchange_strong_explicit(volatile A* object, C * expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool atomic_compare_exchange_strong_explicit(A* object, C * expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool A::compare_exchange_weak(C &amp; expected, C desired,
  memory_order success, memory_order failure) volatile<ins> noexcept</ins>;
bool A::compare_exchange_weak(C &amp; expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool A::compare_exchange_strong(C &amp; expected, C desired,
  memory_order success, memory_order failure) volatile<ins> noexcept</ins>;
bool A::compare_exchange_strong(C &amp; expected, C desired,
  memory_order success, memory_order failure)<ins> noexcept</ins>;
bool A::compare_exchange_weak(C &amp; expected, C desired,
  memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
bool A::compare_exchange_weak(C &amp; expected, C desired,
  memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
bool A::compare_exchange_strong(C &amp; expected, C desired,
  memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
bool A::compare_exchange_strong(C &amp; expected, C desired,
  memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

Before p. 28, modify as follows:
<pre>
C atomic_fetch_key(volatile A *object, M operand)<ins> noexcept</ins>;
C atomic_fetch_key(A* object, M operand)<ins> noexcept</ins>;
C atomic_fetch_key_explicit(volatile A *object, M operand, memory_order order)<ins> noexcept</ins>;
C atomic_fetch_key_explicit(A* object, M operand, memory_order order)<ins> noexcept</ins>;
C A::fetch_key(M operand, memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
C A::fetch_key(M operand, memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

After p. 30, modify as follows:
<pre>
C A::operator op=(M operand) volatile<ins> noexcept</ins>;
C A::operator op=(M operand)<ins> noexcept</ins>;
</pre>

After p. 32, modify as follows:
<pre>
C A::operator++(int) volatile<ins> noexcept</ins>;
C A::operator++(int)<ins> noexcept</ins>;
</pre>

After p. 33, modify as follows:
<pre>
C A::operator--(int) volatile<ins> noexcept</ins>;
C A::operator--(int)<ins> noexcept</ins>;
</pre>

After p. 34, modify as follows:
<pre>
C A::operator++() volatile<ins> noexcept</ins>;
C A::operator++()<ins> noexcept</ins>;
</pre>

After p. 36, modify as follows:
<pre>
C A::operator--() volatile<ins> noexcept</ins>;
C A::operator--()<ins> noexcept</ins>;
</pre>

<h2>29.7 Flag Type and Operations [atomics.flag]</h2>

Before p.1, modify as follows:

<pre>
namespace std {
  typedef struct atomic_flag {
    bool test_and_set(memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    bool test_and_set(memory_order = memory_order_seq_cst)<ins> noexcept</ins>;
    void clear(memory_order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
    void clear(memory_order = memory_order_seq_cst)<ins> noexcept</ins>;

    atomic_flag()<ins> noexcept</ins> = default;
    atomic_flag(const atomic_flag&amp;) = delete;
    atomic_flag&amp; operator=(const atomic_flag&amp;) = delete;
    atomic_flag&amp; operator=(const atomic_flag&amp;) volatile = delete;
  } atomic_flag;

  bool atomic_flag_test_and_set(volatile atomic_flag*)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set(atomic_flag*)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order)<ins> noexcept</ins>;
  bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order)<ins> noexcept</ins>;
  void atomic_flag_clear(volatile atomic_flag*)<ins> noexcept</ins>;
  void atomic_flag_clear(atomic_flag*)<ins> noexcept</ins>;
  void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order)<ins> noexcept</ins>;
  void atomic_flag_clear_explicit(atomic_flag*, memory_order)<ins> noexcept</ins>;

  #define ATOMIC_FLAG_INIT see below
}
</pre>

After p. 4, modify as follows:
<pre>
bool atomic_flag_test_and_set(volatile atomic_flag *object)<ins> noexcept</ins>;
bool atomic_flag_test_and_set(atomic_flag *object)<ins> noexcept</ins>;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order)<ins> noexcept</ins>;
bool atomic_flag_test_and_set_explicit(atomic_flag *object, memory_order order)<ins> noexcept</ins>;
bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

After p. 6, modify as follows:
<pre>
void atomic_flag_clear(volatile atomic_flag *object)<ins> noexcept</ins>;
void atomic_flag_clear(atomic_flag *object)<ins> noexcept</ins>;
void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order)<ins> noexcept</ins>;
void atomic_flag_clear_explicit(atomic_flag *object, memory_order order)<ins> noexcept</ins>;
void atomic_flag::clear(memory_order order = memory_order_seq_cst) volatile<ins> noexcept</ins>;
void atomic_flag::clear(memory_order order = memory_order_seq_cst)<ins> noexcept</ins>;
</pre>

<h2>29.8 Fences [atomics.fences]</h2>

After p. 4, modify as follows:
<pre>
void atomic_thread_fence(memory_order order)<ins> noexcept</ins>;
</pre>

After p. 5, modify as follows:
<pre>
void atomic_signal_fence(memory_order order)<ins> noexcept</ins>;
</pre>

</body>

</html>
