Difference between revisions of "cpp/atomic/atomic ref"
(++) |
(Added fetch_max and fetch_min, also rearranged the table of specialized member functions. Now users are able to tell which specialization provides these functions without entering these pages.) |
||
(20 intermediate revisions by 14 users not shown) | |||
Line 2: | Line 2: | ||
{{cpp/atomic/atomic_ref/navbar}} | {{cpp/atomic/atomic_ref/navbar}} | ||
{{dcl begin}} | {{dcl begin}} | ||
− | {{dcl header | atomic}} | + | {{dcl header|atomic}} |
− | {{dcl | num = 1 | since=c++20 | 1= | + | {{dcl|num=1|since=c++20|1= |
template< class T > | template< class T > | ||
struct atomic_ref; | struct atomic_ref; | ||
}} | }} | ||
− | {{dcl | num = 2 | since=c++20 | 1= | + | {{dcl|num=2|since=c++20|1= |
template< class T > | template< class T > | ||
struct atomic_ref<T*>; | struct atomic_ref<T*>; | ||
Line 13: | Line 13: | ||
{{dcl end}} | {{dcl end}} | ||
− | The {{tt|std::atomic_ref}} class template applies atomic operations to the object it references. For the lifetime of the {{tt|atomic_ref}} object, the object it references is considered an atomic object. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see | + | The {{tt|std::atomic_ref}} class template applies atomic operations to the object it references. For the lifetime of the {{tt|std::atomic_ref}} object, the object it references is considered an atomic object. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see {{lt|cpp/language/memory model}} for details on data races). In addition, accesses to atomic objects may establish inter-thread synchronization and order non-atomic memory accesses as specified by {{lc|std::memory_order}}. |
− | The lifetime of an object must exceed the lifetime of all {{tt|atomic_ref}}s that references the object. While any {{tt|atomic_ref}} | + | The lifetime of an object must exceed the lifetime of all {{tt|std::atomic_ref}}s that references the object. While any {{tt|std::atomic_ref}} instance referencing an object exists, the object must be exclusively accessed through these {{tt|std::atomic_ref}} instances. No subobject of an object referenced by an {{tt|std::atomic_ref}} object may be concurrently referenced by any other {{tt|std::atomic_ref}} object. |
− | Atomic operations applied to an object through an {{tt|atomic_ref}} are atomic with respect to atomic operations applied through any other {{tt|atomic_ref}} referencing the same object. | + | Atomic operations applied to an object through an {{tt|std::atomic_ref}} are atomic with respect to atomic operations applied through any other {{tt|std::atomic_ref}} referencing the same object. |
{{tt|std::atomic_ref}} is {{named req|CopyConstructible}}. | {{tt|std::atomic_ref}} is {{named req|CopyConstructible}}. | ||
− | + | Like language references, constness is shallow for {{tt|std::atomic_ref}} - it is possible to modify the referenced value through a {{c/core|const}} {{tt|std::atomic_ref}} object. | |
+ | ===Specializations=== | ||
====Primary template==== | ====Primary template==== | ||
− | The primary {{tt|std::atomic_ref}} template may be instantiated with any {{named req|TriviallyCopyable}} type {{tt|T}} (including {{c|bool}}): | + | The primary {{tt|std::atomic_ref}} template may be instantiated with any {{named req|TriviallyCopyable}} type {{tt|T}} (including {{c/core|bool}}): |
{{source|1= | {{source|1= | ||
− | struct Counters { int a; int b; } | + | struct Counters { int a; int b; }; // user-defined trivially-copyable type |
− | std::atomic_ref<Counters> cnt(counter); | + | alignas(std::atomic_ref<Counters>::required_alignment) Counters counter; |
+ | std::atomic_ref<Counters> cnt(counter); // specialization for the user-defined type | ||
}} | }} | ||
− | ====Partial specialization for pointer types ==== | + | ====Partial specialization for pointer types==== |
− | The standard library provides partial specializations of the {{tt|std::atomic_ref}} template | + | The standard library provides partial specializations of the {{tt|std::atomic_ref}} template for all pointer types. In addition to the operations provided for all atomic types, these specializations additionally support atomic arithmetic operations appropriate to pointer types, such as {{rlt|fetch_add}}, {{rlt|fetch_sub}}. |
− | + | ||
− | + | ||
+ | ====Specializations for integral types==== | ||
When instantiated with one of the following integral types, {{tt|std::atomic_ref}} provides additional atomic operations appropriate to integral types such as {{rlt|fetch_add}}, {{rlt|fetch_sub}}, {{rlt|fetch_and}}, {{rlt|fetch_or}}, {{rlt|fetch_xor}}: | When instantiated with one of the following integral types, {{tt|std::atomic_ref}} provides additional atomic operations appropriate to integral types such as {{rlt|fetch_add}}, {{rlt|fetch_sub}}, {{rlt|fetch_and}}, {{rlt|fetch_or}}, {{rlt|fetch_xor}}: | ||
− | :* The character types {{c|char}}, {{c|char16_t}}, {{c|char32_t}}, and {{c|wchar_t}}; | + | :* The character types {{c/core|char}}, {{c/core|char8_t}}, {{c/core|char16_t}}, {{c/core|char32_t}}, and {{c/core|wchar_t}}; |
− | :* The standard signed integer types: {{c|signed char}}, {{c|short}}, {{c|int}}, {{c|long}}, and {{c|long long}}; | + | :* The standard signed integer types: {{c/core|signed char}}, {{c/core|short}}, {{c/core|int}}, {{c/core|long}}, and {{c/core|long long}}; |
− | :* The standard unsigned integer types: {{c|unsigned char}}, {{c|unsigned short}}, {{c|unsigned int}}, {{c|unsigned long}}, and {{c|unsigned long long}}; | + | :* The standard unsigned integer types: {{c/core|unsigned char}}, {{c/core|unsigned short}}, {{c/core|unsigned int}}, {{c/core|unsigned long}}, and {{c/core|unsigned long long}}; |
:* Any additional integral types needed by the typedefs in the header {{header|cstdint}}. | :* Any additional integral types needed by the typedefs in the header {{header|cstdint}}. | ||
Signed integer arithmetic is defined to use two's complement; there are no undefined results. | Signed integer arithmetic is defined to use two's complement; there are no undefined results. | ||
− | ==== Specializations for floating-point types ==== | + | ====Specializations for floating-point types==== |
− | + | When instantiated with one of the cv-unqualified floating-point types ({{c/core|float}}, {{c/core|double}}, {{c/core|long double}}{{rev inl|since=c++23| and cv-unqualified [[cpp/language/types#Extended floating-point types|extended floating-point types]]}}), {{tt|std::atomic_ref}} provides additional atomic operations appropriate to floating-point types such as {{rlt|fetch_add}} and {{rlt|fetch_sub}}. | |
− | When instantiated with one of the floating-point types {{c|float}}, {{c|double}}, | + | |
No operations result in undefined behavior even if the result is not representable in the floating-point type. The [[cpp/numeric/fenv|floating-point environment]] in effect may be different from the calling thread's floating-point environment. | No operations result in undefined behavior even if the result is not representable in the floating-point type. The [[cpp/numeric/fenv|floating-point environment]] in effect may be different from the calling thread's floating-point environment. | ||
Line 51: | Line 51: | ||
===Member types=== | ===Member types=== | ||
{{dsc begin}}} | {{dsc begin}}} | ||
− | {{dsc hitem| Member type | Definition}} | + | {{dsc hitem| Member type|Definition}} |
− | {{dsc | {{tt|value_type}} | ''see below'' }} | + | {{dsc|{{tt|value_type}}|''see below''}} |
− | {{dsc | {{tt|difference_type}} | {{tt|value_type}} {{mark|only for {{tt|atomic_ref<''Integral''>}} and {{tt|atomic_ref<''Floating''>}} specializations}}<br | + | {{dsc|{{tt|difference_type}}|{{tt|value_type}} {{mark|only for {{tt|atomic_ref<''Integral''>}} and {{tt|atomic_ref<''Floating''>}} specializations}}<br>{{lc|std::ptrdiff_t}} {{mark|only for {{tt|std::atomic_ref<T*>}} specializations}}}} |
{{dsc end}} | {{dsc end}} | ||
Line 62: | Line 62: | ||
===Member functions=== | ===Member functions=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/atomic/atomic_ref/dsc constructor}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc constructor}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc operator{{=}}}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc operator{{=}}}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc is_lock_free}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc is_lock_free}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc store}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc store}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc load}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc load}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc operator_T}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc operator_T}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc exchange}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc exchange}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc compare_exchange}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc compare_exchange}} |
− | {{dsc h1 | Constants}} | + | {{dsc inc|cpp/atomic/atomic/dsc wait|atomic_ref}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc is_always_lock_free}} | + | {{dsc inc|cpp/atomic/atomic/dsc notify_one|atomic_ref}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc required_alignment }} | + | {{dsc inc|cpp/atomic/atomic/dsc notify_all|atomic_ref}} |
+ | {{dsc h1|Constants}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc is_always_lock_free}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc required_alignment}} | ||
{{dsc end}} | {{dsc end}} | ||
===Specialized member functions=== | ===Specialized member functions=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/atomic/atomic_ref/dsc fetch_add}} | + | {{dsc h2|Specialized for integral, floating-point and pointer types}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc fetch_sub}} | + | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_add}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc | + | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_sub}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc | + | {{dsc inc|cpp/atomic/atomic_ref/dsc operator arith2}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc | + | {{dsc h2|Specialized for integral and pointer types only}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc | + | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_max}} |
− | {{dsc inc | cpp/atomic/atomic_ref/dsc | + | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_min}} |
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc operator arith}} | ||
+ | {{dsc h2|Specialized for integral types only}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_and}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_or}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc fetch_xor}} | ||
+ | {{dsc inc|cpp/atomic/atomic_ref/dsc operator arith3}} | ||
{{dsc end}} | {{dsc end}} | ||
+ | |||
+ | ===Notes=== | ||
+ | {{feature test macro|__cpp_lib_atomic_ref|{{tt|std::atomic_ref}}|value=201806L|std=C++20}} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/atomic/dsc atomic}} | + | {{dsc inc|cpp/atomic/dsc atomic}} |
{{dsc end}} | {{dsc end}} | ||
+ | |||
+ | {{langlinks|es|ja|ru|zh}} |
Latest revision as of 22:31, 29 April 2024
Defined in header <atomic>
|
||
template< class T > struct atomic_ref; |
(1) | (since C++20) |
template< class T > struct atomic_ref<T*>; |
(2) | (since C++20) |
The std::atomic_ref
class template applies atomic operations to the object it references. For the lifetime of the std::atomic_ref
object, the object it references is considered an atomic object. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races). In addition, accesses to atomic objects may establish inter-thread synchronization and order non-atomic memory accesses as specified by std::memory_order.
The lifetime of an object must exceed the lifetime of all std::atomic_ref
s that references the object. While any std::atomic_ref
instance referencing an object exists, the object must be exclusively accessed through these std::atomic_ref
instances. No subobject of an object referenced by an std::atomic_ref
object may be concurrently referenced by any other std::atomic_ref
object.
Atomic operations applied to an object through an std::atomic_ref
are atomic with respect to atomic operations applied through any other std::atomic_ref
referencing the same object.
std::atomic_ref
is CopyConstructible.
Like language references, constness is shallow for std::atomic_ref
- it is possible to modify the referenced value through a const std::atomic_ref
object.
Contents |
[edit] Specializations
[edit] Primary template
The primary std::atomic_ref
template may be instantiated with any TriviallyCopyable type T
(including bool):
struct Counters { int a; int b; }; // user-defined trivially-copyable type alignas(std::atomic_ref<Counters>::required_alignment) Counters counter; std::atomic_ref<Counters> cnt(counter); // specialization for the user-defined type
[edit] Partial specialization for pointer types
The standard library provides partial specializations of the std::atomic_ref
template for all pointer types. In addition to the operations provided for all atomic types, these specializations additionally support atomic arithmetic operations appropriate to pointer types, such as fetch_add
, fetch_sub
.
[edit] Specializations for integral types
When instantiated with one of the following integral types, std::atomic_ref
provides additional atomic operations appropriate to integral types such as fetch_add
, fetch_sub
, fetch_and
, fetch_or
, fetch_xor
:
- The character types char, char8_t, char16_t, char32_t, and wchar_t;
- The standard signed integer types: signed char, short, int, long, and long long;
- The standard unsigned integer types: unsigned char, unsigned short, unsigned int, unsigned long, and unsigned long long;
- Any additional integral types needed by the typedefs in the header <cstdint>.
Signed integer arithmetic is defined to use two's complement; there are no undefined results.
[edit] Specializations for floating-point types
When instantiated with one of the cv-unqualified floating-point types (float, double, long double and cv-unqualified extended floating-point types(since C++23)), std::atomic_ref
provides additional atomic operations appropriate to floating-point types such as fetch_add
and fetch_sub
.
No operations result in undefined behavior even if the result is not representable in the floating-point type. The floating-point environment in effect may be different from the calling thread's floating-point environment.
[edit] Member types
Member type | Definition |
value_type
|
see below |
difference_type
|
value_type (only for atomic_ref<Integral> and atomic_ref<Floating> specializations)std::ptrdiff_t (only for std::atomic_ref<T*> specializations)
|
For every std::atomic_ref<X>
(whether or not specialized), std::atomic_ref<X>::value_type
is X
.
difference_type
is not defined in the primary atomic_ref
template.
[edit] Member functions
constructs an atomic_ref object (public member function) | |
stores a value into the object referenced by an atomic_ref object (public member function) | |
checks if the atomic_ref object is lock-free (public member function) | |
atomically replaces the value of the referenced object with a non-atomic argument (public member function) | |
atomically obtains the value of the referenced object (public member function) | |
loads a value from the referenced object (public member function) | |
atomically replaces the value of the referenced object and obtains the value held previously (public member function) | |
atomically compares the value of the referenced object with non-atomic argument and performs atomic exchange if equal or atomic load if not (public member function) | |
blocks the thread until notified and the atomic value changes (public member function) | |
notifies at least one thread waiting on the atomic object (public member function) | |
notifies all threads blocked waiting on the atomic object (public member function) | |
Constants | |
[static] |
indicates that the type is always lock-free (public static member constant) |
[static] |
indicates the required alignment of an object to be referenced by atomic_ref (public static member constant) |
[edit] Specialized member functions
Specialized for integral, floating-point and pointer types | |
atomically adds the argument to the value stored in the referenced object and obtains the value held previously (public member function) | |
atomically subtracts the argument from the value stored in the referenced object and obtains the value held previously (public member function) | |
atomically adds to or subtracts from the referenced value (public member function) | |
Specialized for integral and pointer types only | |
(C++26) |
atomically performs std::max between the argument and the value of the referenced object and obtains the value held previously (public member function) |
(C++26) |
atomically performs std::min between the argument and the value of the referenced object and obtains the value held previously (public member function) |
atomically increments or decrements the referenced object by one (public member function) | |
Specialized for integral types only | |
atomically performs bitwise AND between the argument and the value of the referenced object and obtains the value held previously (public member function) | |
atomically performs bitwise OR between the argument and the value of the referenced object and obtains the value held previously (public member function) | |
atomically performs bitwise XOR between the argument and the value of the referenced object and obtains the value held previously (public member function) | |
atomically performs bitwise AND, OR, XOR with the referenced value (public member function) |
[edit] Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_atomic_ref |
201806L | (C++20) | std::atomic_ref
|
[edit] See also
(C++11) |
atomic class template and specializations for bool, integral, floating-point,(since C++20) and pointer types (class template) |