33 Concurrency support library [thread]

33.11 Safe reclamation [saferecl]

33.11.3 Hazard pointers [saferecl.hp]

33.11.3.4 Class hazard_pointer [saferecl.hp.holder]

33.11.3.4.3 Member functions [saferecl.hp.holder.mem]

[[nodiscard]] bool empty() const noexcept;
Returns: true if and only if *this is empty.
template<class T> T* protect(const atomic<T*>& src) noexcept;
Effects: Equivalent to: T* ptr = src.load(memory_order::relaxed); while (!try_protect(ptr, src)) {} return ptr;
template<class T> bool try_protect(T*& ptr, const atomic<T*>& src) noexcept;
Mandates: T is a hazard-protectable type.
Preconditions: *this is not empty.
Effects: Performs the following steps in order:
  • Initializes a variable old of type T* with the value of ptr.
  • Evaluates reset_protection(old).
  • Assigns the value of src.load(memory_order​::​acquire) to ptr.
  • If old == ptr is false, evaluates reset_protection().
Returns: old == ptr.
template<class T> void reset_protection(const T* ptr) noexcept;
Mandates: T is a hazard-protectable type.
Preconditions: *this is not empty.
Effects: If ptr is a null pointer value, invokes reset_protection().
Otherwise, associates the hazard pointer owned by *this with *ptr, thereby ending the current protection epoch.
Complexity: Constant.
void reset_protection(nullptr_t = nullptr) noexcept;
Preconditions: *this is not empty.
Postconditions: The hazard pointer owned by *this is unassociated.
Complexity: Constant.
void swap(hazard_pointer& other) noexcept;
Effects: Swaps the hazard pointer ownership of this object with that of other.
[Note 1: 
The owned hazard pointers, if any, remain unchanged during the swap and continue to be associated with the respective objects that they were protecting before the swap, if any.
No protection epochs are ended or initiated.
— end note]
Complexity: Constant.