32 Atomic operations library [atomics]

32.6 Class template atomic [atomics.types.generic]

32.6.3 Partial specialization for pointers [atomics.types.pointer]

namespace std {
  template <class T> struct atomic<T*> {
    using value_type = T*;
    using difference_type = ptrdiff_t;
    static constexpr bool is_always_lock_free = implementation-defined;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(T*, memory_order = memory_order_seq_cst) noexcept;
    T* load(memory_order = memory_order_seq_cst) const volatile noexcept;
    T* load(memory_order = memory_order_seq_cst) const noexcept;
    operator T*() const volatile noexcept;
    operator T*() const noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(T*) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    T* operator=(T*) volatile noexcept;
    T* operator=(T*) noexcept;

    T* operator++(int) volatile noexcept;
    T* operator++(int) noexcept;
    T* operator--(int) volatile noexcept;
    T* operator--(int) noexcept;
    T* operator++() volatile noexcept;
    T* operator++() noexcept;
    T* operator--() volatile noexcept;
    T* operator--() noexcept;
    T* operator+=(ptrdiff_t) volatile noexcept;
    T* operator+=(ptrdiff_t) noexcept;
    T* operator-=(ptrdiff_t) volatile noexcept;
    T* operator-=(ptrdiff_t) noexcept;
  };
}

Имеется частичная специализация atomic шаблона класса для указателей. Специализации этой частичной специализации - это структуры стандартного макета. У каждого из них есть тривиальный конструктор по умолчанию и тривиальный деструктор.

Ниже приведены описания только для членов, которые отличаются от основного шаблона.

Следующие операции выполняют арифметические действия с указателями. Соответствие ключа, оператора и вычислений:

Таблица 139 - Вычисления атомарных указателей
Key Op Вычисление Key Op Вычисление
add + добавление sub - вычитание

T* fetch_key(ptrdiff_t operand, memory_order order = memory_order_seq_cst) volatile noexcept; T* fetch_key(ptrdiff_t operand, memory_order order = memory_order_seq_cst) noexcept;

Requires: T должен быть типом объекта, иначе программа будет некорректной. [ Note: Арифметика указателей на void* указатели функций неправильно сформирована. ] end note

Effects: Атомно заменяет значение, на которое указывает, this результатом вычисления, примененного к значению, на которое указывает this и данное operand. На память влияет значение order. Эти операции являются атомарными операциями чтения-изменения-записи ([intro.multithread]).

Returns: Атомарно, значение, на которое указывает this непосредственно перед эффектами.

Remarks: Результатом может быть неопределенный адрес, но в противном случае операции не имеют неопределенного поведения.

T* operator op=(ptrdiff_t operand) volatile noexcept; T* operator op=(ptrdiff_t operand) noexcept;

Effects: Эквивалентен: return fetch_­key(operand) op operand;