From Jason Turner

[atomics.ref.float]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp92jvejyo/{from.md → to.md} +134 -28
tmp/tmp92jvejyo/{from.md → to.md} RENAMED
@@ -1,74 +1,109 @@
1
  #### Specializations for floating-point types <a id="atomics.ref.float">[[atomics.ref.float]]</a>
2
 
3
  There are specializations of the `atomic_ref` class template for all
4
- cv-unqualified floating-point types. For each such type
5
- `floating-point-type`, the specialization `atomic_ref<floating-point>`
6
- provides additional atomic operations appropriate to floating-point
7
- types.
 
 
8
 
9
  ``` cpp
10
  namespace std {
11
  template<> struct atomic_ref<floating-point-type> {
12
  private:
13
  floating-point-type* ptr; // exposition only
14
 
15
  public:
16
- using value_type = floating-point-type;
17
  using difference_type = value_type;
18
  static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
19
 
20
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
21
  bool is_lock_free() const noexcept;
22
 
23
- explicit atomic_ref(floating-point-type&);
24
- atomic_ref(const atomic_ref&) noexcept;
25
  atomic_ref& operator=(const atomic_ref&) = delete;
26
 
27
- void store(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
28
- floating-point-type operator=(floating-point-type) const noexcept;
29
- floating-point-type load(memory_order = memory_order::seq_cst) const noexcept;
30
- operator floating-point-type() const noexcept;
 
31
 
32
- floating-point-type exchange(floating-point-type,
33
  memory_order = memory_order::seq_cst) const noexcept;
34
- bool compare_exchange_weak(floating-point-type&, floating-point-type,
35
  memory_order, memory_order) const noexcept;
36
- bool compare_exchange_strong(floating-point-type&, floating-point-type,
37
  memory_order, memory_order) const noexcept;
38
- bool compare_exchange_weak(floating-point-type&, floating-point-type,
 
 
 
 
 
 
 
 
 
 
39
  memory_order = memory_order::seq_cst) const noexcept;
40
- bool compare_exchange_strong(floating-point-type&, floating-point-type,
 
 
 
 
 
 
 
 
41
  memory_order = memory_order::seq_cst) const noexcept;
42
 
43
- floating-point-type fetch_add(floating-point-type,
 
 
 
 
44
  memory_order = memory_order::seq_cst) const noexcept;
45
- floating-point-type fetch_sub(floating-point-type,
 
 
 
 
46
  memory_order = memory_order::seq_cst) const noexcept;
47
 
48
- floating-point-type operator+=(floating-point-type) const noexcept;
49
- floating-point-type operator-=(floating-point-type) const noexcept;
50
 
51
- void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
52
- void notify_one() const noexcept;
53
- void notify_all() const noexcept;
 
 
54
  };
55
  }
56
  ```
57
 
58
  Descriptions are provided below only for members that differ from the
59
  primary template.
60
 
61
  The following operations perform arithmetic computations. The
62
  correspondence among key, operator, and computation is specified in
63
- [[atomic.types.int.comp]].
 
 
64
 
65
  ``` cpp
66
- floating-point-type fetch_key(floating-point-type operand,
67
  memory_order order = memory_order::seq_cst) const noexcept;
68
  ```
69
 
 
 
70
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
71
  result of the computation applied to the value referenced by `*ptr` and
72
  the given operand. Memory is affected according to the value of `order`.
73
  These operations are atomic read-modify-write
74
  operations [[intro.races]].
@@ -78,18 +113,89 @@ the effects.
78
 
79
  *Remarks:* If the result is not a representable value for its
80
  type [[expr.pre]], the result is unspecified, but the operations
81
  otherwise have no undefined behavior. Atomic arithmetic operations on
82
  *`floating-point-type`* should conform to the
83
- `std::numeric_limits<`*`floating-point-type`*`>` traits associated with
84
- the floating-point type [[limits.syn]]. The floating-point
85
  environment [[cfenv]] for atomic arithmetic operations on
86
  *`floating-point-type`* may be different than the calling thread’s
87
  floating-point environment.
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  ``` cpp
90
- floating-point-type operator op=(floating-point-type operand) const noexcept;
 
91
  ```
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  *Effects:* Equivalent to:
94
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
95
 
 
1
  #### Specializations for floating-point types <a id="atomics.ref.float">[[atomics.ref.float]]</a>
2
 
3
  There are specializations of the `atomic_ref` class template for all
4
+ floating-point types. For each such type `floating-point-type`, the
5
+ specialization `atomic_ref<floating-point-type>` provides additional
6
+ atomic operations appropriate to floating-point types.
7
+
8
+ The program is ill-formed if `is_always_lock_free` is `false` and
9
+ `is_volatile_v<floating-point-type>` is `true`.
10
 
11
  ``` cpp
12
  namespace std {
13
  template<> struct atomic_ref<floating-point-type> {
14
  private:
15
  floating-point-type* ptr; // exposition only
16
 
17
  public:
18
+ using value_type = remove_cv_t<floating-point-type>;
19
  using difference_type = value_type;
20
  static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
21
 
22
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
23
  bool is_lock_free() const noexcept;
24
 
25
+ constexpr explicit atomic_ref(floating-point-type&);
26
+ constexpr atomic_ref(const atomic_ref&) noexcept;
27
  atomic_ref& operator=(const atomic_ref&) = delete;
28
 
29
+ constexpr void store(value_type,
30
+ memory_order = memory_order::seq_cst) const noexcept;
31
+ constexpr value_type operator=(value_type) const noexcept;
32
+ constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
33
+ constexpr operator value_type() const noexcept;
34
 
35
+ constexpr value_type exchange(value_type,
36
  memory_order = memory_order::seq_cst) const noexcept;
37
+ constexpr bool compare_exchange_weak(value_type&, value_type,
38
  memory_order, memory_order) const noexcept;
39
+ constexpr bool compare_exchange_strong(value_type&, value_type,
40
  memory_order, memory_order) const noexcept;
41
+ constexpr bool compare_exchange_weak(value_type&, value_type,
42
+ memory_order = memory_order::seq_cst) const noexcept;
43
+ constexpr bool compare_exchange_strong(value_type&, value_type,
44
+ memory_order = memory_order::seq_cst) const noexcept;
45
+
46
+ constexpr value_type fetch_add(value_type,
47
+ memory_order = memory_order::seq_cst) const noexcept;
48
+ constexpr value_type fetch_sub(value_type,
49
+ memory_order = memory_order::seq_cst) const noexcept;
50
+
51
+ constexpr value_type fetch_max(value_type,
52
  memory_order = memory_order::seq_cst) const noexcept;
53
+ constexpr value_type fetch_min(value_type,
54
+ memory_order = memory_order::seq_cst) const noexcept;
55
+ constexpr value_type fetch_fmaximum(value_type,
56
+ memory_order = memory_order::seq_cst) const noexcept;
57
+ constexpr value_type fetch_fminimum(value_type,
58
+ memory_order = memory_order::seq_cst) const noexcept;
59
+ constexpr value_type fetch_fmaximum_num(value_type,
60
+ memory_order = memory_order::seq_cst) const noexcept;
61
+ constexpr value_type fetch_fminimum_num(value_type,
62
  memory_order = memory_order::seq_cst) const noexcept;
63
 
64
+ constexpr void store_add(value_type, memory_order = memory_order::seq_cst) const noexcept;
65
+ constexpr void store_sub(value_type, memory_order = memory_order::seq_cst) const noexcept;
66
+ constexpr void store_max(value_type, memory_order = memory_order::seq_cst) const noexcept;
67
+ constexpr void store_min(value_type, memory_order = memory_order::seq_cst) const noexcept;
68
+ constexpr void store_fmaximum(value_type,
69
  memory_order = memory_order::seq_cst) const noexcept;
70
+ constexpr void store_fminimum(value_type,
71
+ memory_order = memory_order::seq_cst) const noexcept;
72
+ constexpr void store_fmaximum_num(value_type,
73
+ memory_order = memory_order::seq_cst) const noexcept;
74
+ constexpr void store_fminimum_num(value_type,
75
  memory_order = memory_order::seq_cst) const noexcept;
76
 
77
+ constexpr value_type operator+=(value_type) const noexcept;
78
+ constexpr value_type operator-=(value_type) const noexcept;
79
 
80
+ constexpr void wait(value_type,
81
+ memory_order = memory_order::seq_cst) const noexcept;
82
+ constexpr void notify_one() const noexcept;
83
+ constexpr void notify_all() const noexcept;
84
+ constexpr floating-point-type* address() const noexcept;
85
  };
86
  }
87
  ```
88
 
89
  Descriptions are provided below only for members that differ from the
90
  primary template.
91
 
92
  The following operations perform arithmetic computations. The
93
  correspondence among key, operator, and computation is specified in
94
+ [[atomic.types.int.comp]], except for the keys `max`, `min`, `fmaximum`,
95
+ `fminimum`, `fmaximum_num`, and `fminimum_num`, which are specified
96
+ below.
97
 
98
  ``` cpp
99
+ constexpr value_type fetch_key(value_type operand,
100
  memory_order order = memory_order::seq_cst) const noexcept;
101
  ```
102
 
103
+ *Constraints:* `is_const_v<`*`floating-point-type`*`>` is `false`.
104
+
105
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
106
  result of the computation applied to the value referenced by `*ptr` and
107
  the given operand. Memory is affected according to the value of `order`.
108
  These operations are atomic read-modify-write
109
  operations [[intro.races]].
 
113
 
114
  *Remarks:* If the result is not a representable value for its
115
  type [[expr.pre]], the result is unspecified, but the operations
116
  otherwise have no undefined behavior. Atomic arithmetic operations on
117
  *`floating-point-type`* should conform to the
118
+ `std::numeric_limits<value_type>` traits associated with the
119
+ floating-point type [[limits.syn]]. The floating-point
120
  environment [[cfenv]] for atomic arithmetic operations on
121
  *`floating-point-type`* may be different than the calling thread’s
122
  floating-point environment.
123
 
124
+ - For `fetch_fmaximum` and `fetch_fminimum`, the maximum and minimum
125
+ computation is performed as if by `fmaximum` and `fminimum`,
126
+ respectively, with `*ptr` and the first parameter as the arguments.
127
+ - For `fetch_fmaximum_num` and `fetch_fminimum_num`, the maximum and
128
+ minimum computation is performed as if by `fmaximum_num` and
129
+ `fminimum_num`, respectively, with `*ptr` and the first parameter as
130
+ the arguments.
131
+ - For `fetch_max` and `fetch_min`, the maximum and minimum computation
132
+ is performed as if by `fmaximum_num` and `fminimum_num`, respectively,
133
+ with `*ptr` and the first parameter as the arguments, except that:
134
+ - If both arguments are NaN, an unspecified NaN value is stored at
135
+ `*ptr`.
136
+ - If exactly one argument is a NaN, either the other argument or an
137
+ unspecified NaN value is stored at `*ptr`; it is unspecified which.
138
+ - If the arguments are differently signed zeros, which of these values
139
+ is stored at `*ptr` is unspecified.
140
+
141
+ *Recommended practice:* The implementation of `fetch_max` and
142
+ `fetch_min` should treat negative zero as smaller than positive zero.
143
+
144
  ``` cpp
145
+ constexpr void store_key(value_type operand,
146
+ memory_order order = memory_order::seq_cst) const noexcept;
147
  ```
148
 
149
+ *Preconditions:* `order` is `memory_order::relaxed`,
150
+ `memory_order::release`, or `memory_order::seq_cst`.
151
+
152
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
153
+ result of the computation applied to the value referenced by `*ptr` and
154
+ the given `operand`. Memory is affected according to the value of
155
+ `order`. These operations are atomic modify-write
156
+ operations [[atomics.order]].
157
+
158
+ *Remarks:* If the result is not a representable value for its
159
+ type [[expr.pre]], the result is unspecified, but the operations
160
+ otherwise have no undefined behavior. Atomic arithmetic operations on
161
+ *`floating-point-type`* should conform to the
162
+ `numeric_limits<`*`floating-point-type`*`>` traits associated with the
163
+ floating-point type [[limits.syn]]. The floating-point
164
+ environment [[cfenv]] for atomic arithmetic operations on
165
+ *`floating-point-type`* may be different than the calling thread’s
166
+ floating-point environment. The arithmetic rules of floating-point
167
+ atomic modify-write operations may be different from operations on
168
+ floating-point types or atomic floating-point types.
169
+
170
+ [*Note 1*: Tree reductions are permitted for atomic modify-write
171
+ operations. — *end note*]
172
+
173
+ - For `store_fmaximum` and `store_fminimum`, the maximum and minimum
174
+ computation is performed as if by `fmaximum` and `fminimum`,
175
+ respectively, with `*ptr` and the first parameter as the arguments.
176
+ - For `store_fmaximum_num` and `store_fminimum_num`, the maximum and
177
+ minimum computation is performed as if by `fmaximum_num `and
178
+ `fminimum_num`, respectively, with `*ptr` and the first parameter as
179
+ the arguments.
180
+ - For `store_max` and `store_min`, the maximum and minimum computation
181
+ is performed as if by `fmaximum_num` and `fminimum_num`, respectively,
182
+ with `*ptr` and the first parameter as the arguments, except that:
183
+ - If both arguments are NaN, an unspecified NaN value is stored at
184
+ `*ptr`.
185
+ - If exactly one argument is a NaN, either the other argument or an
186
+ unspecified NaN value is stored at `*ptr`, it is unspecified which.
187
+ - If the arguments are differently signed zeros, which of these values
188
+ is stored at `*ptr` is unspecified.
189
+
190
+ *Recommended practice:* The implementation of `store_max` and
191
+ `store_min` should treat negative zero as smaller than positive zero.
192
+
193
+ ``` cpp
194
+ constexpr value_type operator op=(value_type operand) const noexcept;
195
+ ```
196
+
197
+ *Constraints:* `is_const_v<`*`floating-point-type`*`>` is `false`.
198
+
199
  *Effects:* Equivalent to:
200
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
201