Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/atomic/atomic ref"

From cppreference.com
< cpp‎ | atomic
(char8_t)
(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.)
 
(15 intermediate revisions by 12 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 [[cpp/language/memory_model|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 {{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}} instances referencing an object exists, the object must be exclusively accessed through these {{tt|atomic_ref}} instances. No subobject of an object referenced by an {{tt|atomic_ref}} object may be concurrently referenced by any other {{tt|atomic_ref}} object.
+
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|atomic_ref}} - it is possible to modify the referenced value through a {{tt|const}} {{tt|atomic_ref}} object.
+
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 ===
+
  
 +
===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; } counter; // user-defined trivially-copyable type
+
struct Counters { int a; int b; }; // user-defined trivially-copyable type
std::atomic_ref<Counters> cnt(counter);   // specialization for the user-defined type
+
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 for 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}}.
+
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 ====
+
  
 +
====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}}{{rev inl|since=c++20|, {{c|char8_t}}}}, {{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}}, and {{c|long double}}, {{tt|std::atomic_ref}} provides additional atomic operations appropriate to floating-point types such as {{rlt|fetch_add}} and {{rlt|fetch_sub}}.
+
  
 
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 53: 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/> {{lc|std::ptrdiff_t}} {{mark|only for {{tt|atomic_ref<T*>}} specializations}}}}
+
{{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 64: 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 fetch_and}}
+
{{dsc inc|cpp/atomic/atomic_ref/dsc fetch_sub}}
{{dsc inc | cpp/atomic/atomic_ref/dsc fetch_or}}
+
{{dsc inc|cpp/atomic/atomic_ref/dsc operator arith2}}
{{dsc inc | cpp/atomic/atomic_ref/dsc fetch_xor}}
+
{{dsc h2|Specialized for integral and pointer types only}}
{{dsc inc | cpp/atomic/atomic_ref/dsc operator_arith}}
+
{{dsc inc|cpp/atomic/atomic_ref/dsc fetch_max}}
{{dsc inc | cpp/atomic/atomic_ref/dsc operator_arith2}}
+
{{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|ja|zh}}
+
{{langlinks|es|ja|ru|zh}}

Latest revision as of 22:31, 29 April 2024

 
 
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
(C++11)
Generic lock management
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
(C++11)
Safe Reclamation
(C++26)
Hazard Pointers
Atomic types
(C++11)
atomic_ref
(C++20)
Initialization of atomic types
(C++11)(deprecated in C++20)
(C++11)(deprecated in C++20)
Memory ordering
Free functions for atomic operations
Free functions for atomic flags
 
 
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_refs 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) [edit]
stores a value into the object referenced by an atomic_ref object
(public member function) [edit]
checks if the atomic_ref object is lock-free
(public member function) [edit]
atomically replaces the value of the referenced object with a non-atomic argument
(public member function) [edit]
atomically obtains the value of the referenced object
(public member function) [edit]
loads a value from the referenced object
(public member function) [edit]
atomically replaces the value of the referenced object and obtains the value held previously
(public member function) [edit]
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) [edit]
blocks the thread until notified and the atomic value changes
(public member function) [edit]
notifies at least one thread waiting on the atomic object
(public member function) [edit]
notifies all threads blocked waiting on the atomic object
(public member function) [edit]

Constants

indicates that the type is always lock-free
(public static member constant) [edit]
indicates the required alignment of an object to be referenced by atomic_ref
(public static member constant) [edit]

[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) [edit]
atomically subtracts the argument from the value stored in the referenced object and obtains the value held previously
(public member function) [edit]
atomically adds to or subtracts from the referenced value
(public member function) [edit]
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) [edit]
(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) [edit]
atomically increments or decrements the referenced object by one
(public member function) [edit]
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) [edit]
atomically performs bitwise OR between the argument and the value of the referenced object and obtains the value held previously
(public member function) [edit]
atomically performs bitwise XOR between the argument and the value of the referenced object and obtains the value held previously
(public member function) [edit]
atomically performs bitwise AND, OR, XOR with the referenced value
(public member function) [edit]

[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) [edit]