From Jason Turner

[atomics.ref.int]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpjw6txpxj/{from.md → to.md} +97 -43
tmp/tmpjw6txpxj/{from.md → to.md} RENAMED
@@ -1,77 +1,96 @@
1
  #### Specializations for integral types <a id="atomics.ref.int">[[atomics.ref.int]]</a>
2
 
3
- There are specializations of the `atomic_ref` class template for the
4
- integral types `char`, `signed char`, `unsigned char`, `short`,
5
- `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long`,
6
- `long long`, `unsigned long long`, `char8_t`, `char16_t`, `char32_t`,
7
- `wchar_t`, and any other types needed by the typedefs in the header
8
- `<cstdint>`. For each such type `integral-type`, the specialization
9
- `atomic_ref<integral-type>` provides additional atomic operations
10
- appropriate to integral types.
11
 
12
  [*Note 1*: The specialization `atomic_ref<bool>` uses the primary
13
  template [[atomics.ref.generic]]. — *end note*]
14
 
 
 
 
15
  ``` cpp
16
  namespace std {
17
  template<> struct atomic_ref<integral-type> {
18
  private:
19
  integral-type* ptr; // exposition only
20
 
21
  public:
22
- using value_type = integral-type;
23
  using difference_type = value_type;
24
  static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
25
 
26
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
27
  bool is_lock_free() const noexcept;
28
 
29
- explicit atomic_ref(integral-type&);
30
- atomic_ref(const atomic_ref&) noexcept;
31
  atomic_ref& operator=(const atomic_ref&) = delete;
32
 
33
- void store(integral-type, memory_order = memory_order::seq_cst) const noexcept;
34
- integral-type operator=(integral-type) const noexcept;
35
- integral-type load(memory_order = memory_order::seq_cst) const noexcept;
36
- operator integral-type() const noexcept;
37
 
38
- integral-type exchange(integral-type,
39
  memory_order = memory_order::seq_cst) const noexcept;
40
- bool compare_exchange_weak(integral-type&, integral-type,
41
  memory_order, memory_order) const noexcept;
42
- bool compare_exchange_strong(integral-type&, integral-type,
43
  memory_order, memory_order) const noexcept;
44
- bool compare_exchange_weak(integral-type&, integral-type,
45
  memory_order = memory_order::seq_cst) const noexcept;
46
- bool compare_exchange_strong(integral-type&, integral-type,
47
  memory_order = memory_order::seq_cst) const noexcept;
48
 
49
- integral-type fetch_add(integral-type,
50
  memory_order = memory_order::seq_cst) const noexcept;
51
- integral-type fetch_sub(integral-type,
52
  memory_order = memory_order::seq_cst) const noexcept;
53
- integral-type fetch_and(integral-type,
54
  memory_order = memory_order::seq_cst) const noexcept;
55
- integral-type fetch_or(integral-type,
56
  memory_order = memory_order::seq_cst) const noexcept;
57
- integral-type fetch_xor(integral-type,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  memory_order = memory_order::seq_cst) const noexcept;
59
 
60
- integral-type operator++(int) const noexcept;
61
- integral-type operator--(int) const noexcept;
62
- integral-type operator++() const noexcept;
63
- integral-type operator--() const noexcept;
64
- integral-type operator+=(integral-type) const noexcept;
65
- integral-type operator-=(integral-type) const noexcept;
66
- integral-type operator&=(integral-type) const noexcept;
67
- integral-type operator|=(integral-type) const noexcept;
68
- integral-type operator^=(integral-type) const noexcept;
69
 
70
- void wait(integral-type, memory_order = memory_order::seq_cst) const noexcept;
71
- void notify_one() const noexcept;
72
- void notify_all() const noexcept;
 
73
  };
74
  }
75
  ```
76
 
77
  Descriptions are provided below only for members that differ from the
@@ -80,33 +99,68 @@ primary template.
80
  The following operations perform arithmetic computations. The
81
  correspondence among key, operator, and computation is specified in
82
  [[atomic.types.int.comp]].
83
 
84
  ``` cpp
85
- integral-type fetch_key(integral-type operand,
86
  memory_order order = memory_order::seq_cst) const noexcept;
87
  ```
88
 
 
 
89
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
90
  result of the computation applied to the value referenced by `*ptr` and
91
  the given operand. Memory is affected according to the value of `order`.
92
  These operations are atomic read-modify-write
93
  operations [[intro.races]].
94
 
95
  *Returns:* Atomically, the value referenced by `*ptr` immediately before
96
  the effects.
97
 
98
- *Remarks:* For signed integer types, the result is as if the object
99
- value and parameters were converted to their corresponding unsigned
100
- types, the computation performed on those types, and the result
101
- converted back to the signed type.
102
 
103
  [*Note 1*: There are no undefined results arising from the
104
  computation. — *end note*]
105
 
 
 
 
 
 
106
  ``` cpp
107
- integral-type operator op=(integral-type operand) const noexcept;
 
108
  ```
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  *Effects:* Equivalent to:
111
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
112
 
 
1
  #### Specializations for integral types <a id="atomics.ref.int">[[atomics.ref.int]]</a>
2
 
3
+ There are specializations of the `atomic_ref` class template for all
4
+ integral types except cv `bool`. For each such type `integral-type`, the
5
+ specialization `atomic_ref<integral-type>` provides additional atomic
6
+ operations appropriate to integral types.
 
 
 
 
7
 
8
  [*Note 1*: The specialization `atomic_ref<bool>` uses the primary
9
  template [[atomics.ref.generic]]. — *end note*]
10
 
11
+ The program is ill-formed if `is_always_lock_free` is `false` and
12
+ `is_volatile_v<integral-type>` is `true`.
13
+
14
  ``` cpp
15
  namespace std {
16
  template<> struct atomic_ref<integral-type> {
17
  private:
18
  integral-type* ptr; // exposition only
19
 
20
  public:
21
+ using value_type = remove_cv_t<integral-type>;
22
  using difference_type = value_type;
23
  static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
24
 
25
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
26
  bool is_lock_free() const noexcept;
27
 
28
+ constexpr explicit atomic_ref(integral-type&);
29
+ constexpr atomic_ref(const atomic_ref&) noexcept;
30
  atomic_ref& operator=(const atomic_ref&) = delete;
31
 
32
+ constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept;
33
+ constexpr value_type operator=(value_type) const noexcept;
34
+ constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
35
+ constexpr operator value_type() const noexcept;
36
 
37
+ constexpr value_type exchange(value_type,
38
  memory_order = memory_order::seq_cst) const noexcept;
39
+ constexpr bool compare_exchange_weak(value_type&, value_type,
40
  memory_order, memory_order) const noexcept;
41
+ constexpr bool compare_exchange_strong(value_type&, value_type,
42
  memory_order, memory_order) const noexcept;
43
+ constexpr bool compare_exchange_weak(value_type&, value_type,
44
  memory_order = memory_order::seq_cst) const noexcept;
45
+ constexpr bool compare_exchange_strong(value_type&, value_type,
46
  memory_order = memory_order::seq_cst) const noexcept;
47
 
48
+ constexpr value_type fetch_add(value_type,
49
  memory_order = memory_order::seq_cst) const noexcept;
50
+ constexpr value_type fetch_sub(value_type,
51
  memory_order = memory_order::seq_cst) const noexcept;
52
+ constexpr value_type fetch_and(value_type,
53
  memory_order = memory_order::seq_cst) const noexcept;
54
+ constexpr value_type fetch_or(value_type,
55
  memory_order = memory_order::seq_cst) const noexcept;
56
+ constexpr value_type fetch_xor(value_type,
57
+ memory_order = memory_order::seq_cst) const noexcept;
58
+ constexpr value_type fetch_max(value_type,
59
+ memory_order = memory_order::seq_cst) const noexcept;
60
+ constexpr value_type fetch_min(value_type,
61
+ memory_order = memory_order::seq_cst) const noexcept;
62
+
63
+ constexpr void store_add(value_type,
64
+ memory_order = memory_order::seq_cst) const noexcept;
65
+ constexpr void store_sub(value_type,
66
+ memory_order = memory_order::seq_cst) const noexcept;
67
+ constexpr void store_and(value_type,
68
+ memory_order = memory_order::seq_cst) const noexcept;
69
+ constexpr void store_or(value_type,
70
+ memory_order = memory_order::seq_cst) const noexcept;
71
+ constexpr void store_xor(value_type,
72
+ memory_order = memory_order::seq_cst) const noexcept;
73
+ constexpr void store_max(value_type,
74
+ memory_order = memory_order::seq_cst) const noexcept;
75
+ constexpr void store_min(value_type,
76
  memory_order = memory_order::seq_cst) const noexcept;
77
 
78
+ constexpr value_type operator++(int) const noexcept;
79
+ constexpr value_type operator--(int) const noexcept;
80
+ constexpr value_type operator++() const noexcept;
81
+ constexpr value_type operator--() const noexcept;
82
+ constexpr value_type operator+=(value_type) const noexcept;
83
+ constexpr value_type operator-=(value_type) const noexcept;
84
+ constexpr value_type operator&=(value_type) const noexcept;
85
+ constexpr value_type operator|=(value_type) const noexcept;
86
+ constexpr value_type operator^=(value_type) const noexcept;
87
 
88
+ constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept;
89
+ constexpr void notify_one() const noexcept;
90
+ constexpr void notify_all() const noexcept;
91
+ constexpr integral-type* address() const noexcept;
92
  };
93
  }
94
  ```
95
 
96
  Descriptions are provided below only for members that differ from the
 
99
  The following operations perform arithmetic computations. The
100
  correspondence among key, operator, and computation is specified in
101
  [[atomic.types.int.comp]].
102
 
103
  ``` cpp
104
+ constexpr value_type fetch_key(value_type operand,
105
  memory_order order = memory_order::seq_cst) const noexcept;
106
  ```
107
 
108
+ *Constraints:* `is_const_v<`*`integral-type`*`>` is `false`.
109
+
110
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
111
  result of the computation applied to the value referenced by `*ptr` and
112
  the given operand. Memory is affected according to the value of `order`.
113
  These operations are atomic read-modify-write
114
  operations [[intro.races]].
115
 
116
  *Returns:* Atomically, the value referenced by `*ptr` immediately before
117
  the effects.
118
 
119
+ *Remarks:* Except for `fetch_max` and `fetch_min`, for signed integer
120
+ types the result is as if the object value and parameters were converted
121
+ to their corresponding unsigned types, the computation performed on
122
+ those types, and the result converted back to the signed type.
123
 
124
  [*Note 1*: There are no undefined results arising from the
125
  computation. — *end note*]
126
 
127
+ For `fetch_max` and `fetch_min`, the maximum and minimum computation is
128
+ performed as if by `max` and `min` algorithms [[alg.min.max]],
129
+ respectively, with the object value and the first parameter as the
130
+ arguments.
131
+
132
  ``` cpp
133
+ constexpr void store_key(value_type operand,
134
+ memory_order order = memory_order::seq_cst) const noexcept;
135
  ```
136
 
137
+ *Preconditions:* `order` is `memory_order::relaxed`,
138
+ `memory_order::release`, or `memory_order::seq_cst`.
139
+
140
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
141
+ result of the computation applied to the value referenced by `*ptr` and
142
+ the given `operand`. Memory is affected according to the value of
143
+ `order`. These operations are atomic modify-write
144
+ operations [[atomics.order]].
145
+
146
+ *Remarks:* Except for `store_max` and `store_min`, for signed integer
147
+ types, the result is as if `*ptr` and parameters were converted to their
148
+ corresponding unsigned types, the computation performed on those types,
149
+ and the result converted back to the signed type.
150
+
151
+ [*Note 2*: There are no undefined results arising from the
152
+ computation. — *end note*]
153
+
154
+ For `store_max` and `store_min`, the maximum and minimum computation is
155
+ performed as if by `max` and `min` algorithms [[alg.min.max]],
156
+ respectively, with `*ptr` and the first parameter as the arguments.
157
+
158
+ ``` cpp
159
+ constexpr value_type operator op=(value_type operand) const noexcept;
160
+ ```
161
+
162
+ *Constraints:* `is_const_v<`*`integral-type`*`>` is `false`.
163
+
164
  *Effects:* Equivalent to:
165
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
166