From Jason Turner

[atomics.ref.pointer]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3_w7s7yh/{from.md → to.md} +96 -29
tmp/tmp3_w7s7yh/{from.md → to.md} RENAMED
@@ -1,53 +1,78 @@
1
- #### Partial specialization for pointers <a id="atomics.ref.pointer">[[atomics.ref.pointer]]</a>
 
 
 
 
 
 
 
 
2
 
3
  ``` cpp
4
  namespace std {
5
- template<class T> struct atomic_ref<T*> {
6
  private:
7
- T** ptr; // exposition only
8
 
9
  public:
10
- using value_type = T*;
11
  using difference_type = ptrdiff_t;
12
  static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
13
 
14
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
15
  bool is_lock_free() const noexcept;
16
 
17
- explicit atomic_ref(T*&);
18
- atomic_ref(const atomic_ref&) noexcept;
19
  atomic_ref& operator=(const atomic_ref&) = delete;
20
 
21
- void store(T*, memory_order = memory_order::seq_cst) const noexcept;
22
- T* operator=(T*) const noexcept;
23
- T* load(memory_order = memory_order::seq_cst) const noexcept;
24
- operator T*() const noexcept;
25
 
26
- T* exchange(T*, memory_order = memory_order::seq_cst) const noexcept;
27
- bool compare_exchange_weak(T*&, T*,
 
28
  memory_order, memory_order) const noexcept;
29
- bool compare_exchange_strong(T*&, T*,
30
  memory_order, memory_order) const noexcept;
31
- bool compare_exchange_weak(T*&, T*,
 
 
 
 
 
 
 
32
  memory_order = memory_order::seq_cst) const noexcept;
33
- bool compare_exchange_strong(T*&, T*,
 
 
34
  memory_order = memory_order::seq_cst) const noexcept;
35
 
36
- T* fetch_add(difference_type, memory_order = memory_order::seq_cst) const noexcept;
37
- T* fetch_sub(difference_type, memory_order = memory_order::seq_cst) const noexcept;
 
 
 
 
 
 
38
 
39
- T* operator++(int) const noexcept;
40
- T* operator--(int) const noexcept;
41
- T* operator++() const noexcept;
42
- T* operator--() const noexcept;
43
- T* operator+=(difference_type) const noexcept;
44
- T* operator-=(difference_type) const noexcept;
45
 
46
- void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
47
- void notify_one() const noexcept;
48
- void notify_all() const noexcept;
 
49
  };
50
  }
51
  ```
52
 
53
  Descriptions are provided below only for members that differ from the
@@ -56,14 +81,18 @@ primary template.
56
  The following operations perform arithmetic computations. The
57
  correspondence among key, operator, and computation is specified in
58
  [[atomic.types.pointer.comp]].
59
 
60
  ``` cpp
61
- T* fetch_key(difference_type operand, memory_order order = memory_order::seq_cst) const noexcept;
 
62
  ```
63
 
64
- *Mandates:* `T` is a complete object type.
 
 
 
65
 
66
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
67
  result of the computation applied to the value referenced by `*ptr` and
68
  the given operand. Memory is affected according to the value of `order`.
69
  These operations are atomic read-modify-write
@@ -73,12 +102,50 @@ operations [[intro.races]].
73
  the effects.
74
 
75
  *Remarks:* The result may be an undefined address, but the operations
76
  otherwise have no undefined behavior.
77
 
 
 
 
 
 
 
 
 
 
78
  ``` cpp
79
- T* operator op=(difference_type operand) const noexcept;
 
80
  ```
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  *Effects:* Equivalent to:
83
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
84
 
 
1
+ #### Specialization for pointers <a id="atomics.ref.pointer">[[atomics.ref.pointer]]</a>
2
+
3
+ There are specializations of the `atomic_ref` class template for all
4
+ pointer-to-object types. For each such type `pointer-type`, the
5
+ specialization `atomic_ref<pointer-type>` provides additional atomic
6
+ operations appropriate to pointer types.
7
+
8
+ The program is ill-formed if `is_always_lock_free` is `false` and
9
+ `is_volatile_v<pointer-type>` is `true`.
10
 
11
  ``` cpp
12
  namespace std {
13
+ template<> struct atomic_ref<pointer-type> {
14
  private:
15
+ pointer-type* ptr; // exposition only
16
 
17
  public:
18
+ using value_type = remove_cv_t<pointer-type>;
19
  using difference_type = ptrdiff_t;
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(pointer-type&);
26
+ constexpr atomic_ref(const atomic_ref&) noexcept;
27
  atomic_ref& operator=(const atomic_ref&) = delete;
28
 
29
+ constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept;
30
+ constexpr value_type operator=(value_type) const noexcept;
31
+ constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
32
+ constexpr operator value_type() const noexcept;
33
 
34
+ constexpr value_type exchange(value_type,
35
+ memory_order = memory_order::seq_cst) const noexcept;
36
+ constexpr bool compare_exchange_weak(value_type&, value_type,
37
  memory_order, memory_order) const noexcept;
38
+ constexpr bool compare_exchange_strong(value_type&, value_type,
39
  memory_order, memory_order) const noexcept;
40
+ constexpr bool compare_exchange_weak(value_type&, value_type,
41
+ memory_order = memory_order::seq_cst) const noexcept;
42
+ constexpr bool compare_exchange_strong(value_type&, value_type,
43
+ memory_order = memory_order::seq_cst) const noexcept;
44
+
45
+ constexpr value_type fetch_add(difference_type,
46
+ memory_order = memory_order::seq_cst) const noexcept;
47
+ constexpr value_type fetch_sub(difference_type,
48
  memory_order = memory_order::seq_cst) const noexcept;
49
+ constexpr value_type fetch_max(value_type,
50
+ memory_order = memory_order::seq_cst) const noexcept;
51
+ constexpr value_type fetch_min(value_type,
52
  memory_order = memory_order::seq_cst) const noexcept;
53
 
54
+ constexpr void store_add(difference_type,
55
+ memory_order = memory_order::seq_cst) const noexcept;
56
+ constexpr void store_sub(difference_type,
57
+ memory_order = memory_order::seq_cst) const noexcept;
58
+ constexpr void store_max(value_type,
59
+ memory_order = memory_order::seq_cst) const noexcept;
60
+ constexpr void store_min(value_type,
61
+ memory_order = memory_order::seq_cst) const noexcept;
62
 
63
+ constexpr value_type operator++(int) const noexcept;
64
+ constexpr value_type operator--(int) const noexcept;
65
+ constexpr value_type operator++() const noexcept;
66
+ constexpr value_type operator--() const noexcept;
67
+ constexpr value_type operator+=(difference_type) const noexcept;
68
+ constexpr value_type operator-=(difference_type) const noexcept;
69
 
70
+ constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept;
71
+ constexpr void notify_one() const noexcept;
72
+ constexpr void notify_all() const noexcept;
73
+ constexpr pointer-type* address() const noexcept;
74
  };
75
  }
76
  ```
77
 
78
  Descriptions are provided below only for members that differ from the
 
81
  The following operations perform arithmetic computations. The
82
  correspondence among key, operator, and computation is specified in
83
  [[atomic.types.pointer.comp]].
84
 
85
  ``` cpp
86
+ constexpr value_type fetch_key(\seeabovenc operand,
87
+ memory_order order = memory_order::seq_cst) const noexcept;
88
  ```
89
 
90
+ *Constraints:* `is_const_v<`*`pointer-type`*`>` is `false`.
91
+
92
+ *Mandates:* `remove_pointer_t<`*`pointer-type`*`>` is a complete object
93
+ type.
94
 
95
  *Effects:* Atomically replaces the value referenced by `*ptr` with the
96
  result of the computation applied to the value referenced by `*ptr` and
97
  the given operand. Memory is affected according to the value of `order`.
98
  These operations are atomic read-modify-write
 
102
  the effects.
103
 
104
  *Remarks:* The result may be an undefined address, but the operations
105
  otherwise have no undefined behavior.
106
 
107
+ For `fetch_max` and `fetch_min`, the maximum and minimum computation is
108
+ performed as if by `max` and `min` algorithms [[alg.min.max]],
109
+ respectively, with the object value and the first parameter as the
110
+ arguments.
111
+
112
+ [*Note 1*: If the pointers point to different complete objects (or
113
+ subobjects thereof), the `<` operator does not establish a strict weak
114
+ ordering ([[cpp17.lessthancomparable]], [[expr.rel]]). — *end note*]
115
+
116
  ``` cpp
117
+ constexpr void store_key(\seeabovenc operand,
118
+ memory_order order = memory_order::seq_cst) const noexcept;
119
  ```
120
 
121
+ *Mandates:* `remove_pointer_t<`*`pointer-type`*`>` is a complete object
122
+ type.
123
+
124
+ *Preconditions:* `order` is `memory_order::relaxed`,
125
+ `memory_order::release`, or `memory_order::seq_cst`.
126
+
127
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
128
+ result of the computation applied to the value referenced by `*ptr` and
129
+ the given `operand`. Memory is affected according to the value of
130
+ `order`. These operations are atomic modify-write
131
+ operations [[atomics.order]].
132
+
133
+ *Remarks:* The result may be an undefined address, but the operations
134
+ otherwise have no undefined behavior. For `store_max` and `store_min`,
135
+ the `maximum` and `minimum` computation is performed as if by `max` and
136
+ `min` algorithms [[alg.min.max]], respectively, with `*ptr` and the
137
+ first parameter as the arguments.
138
+
139
+ [*Note 2*: If the pointers point to different complete objects (or
140
+ subobjects thereof), the `<` operator does not establish a strict weak
141
+ ordering ([[cpp17.lessthancomparable]], [[expr.rel]]). — *end note*]
142
+
143
+ ``` cpp
144
+ constexpr value_type operator op=(difference_type operand) const noexcept;
145
+ ```
146
+
147
+ *Constraints:* `is_const_v<`*`pointer-type`*`>` is `false`.
148
+
149
  *Effects:* Equivalent to:
150
  `return fetch_`*`key`*`(operand) `*`op`*` operand;`
151