std::atomic::exchange(3)

NAME
std::atomic::exchange - std::atomic::exchange

Synopsis
   T exchange( T desired, std::memory_order order = (1)
   std::memory_order_seq_cst ) noexcept; (since C++11)
   T exchange( T desired, std::memory_order order = (2)
   std::memory_order_seq_cst ) volatile noexcept;
   Atomically replaces the underlying value with desired. The operation is
   read-modify-write operation. Memory is affected according to the value of order.
   The volatile-qualified version (2) is deprecated if (since C++20)
   std::atomic<T>::is_always_lock_free is false.

Parameters
   desired - value to assign
   order - memory order constraints to enforce

Return value
   The value of the atomic variable before the call.

Example
// Run this code
 #include <algorithm>
 #include <atomic>
 #include <cstddef>
 #include <iostream>
 #include <syncstream>
 #include <thread>
 #include <vector>
 int main(){
     const std::size_t ThreadNumber = 5;
     const int Sum = 5;
     std::atomic<int> atom{0};
     std::atomic<int> counter{0};
     // lambda as thread proc
     auto lambda = [&](const int id){
         for (int next = 0; next < Sum;){
             // each thread is writing a value from its own knowledge
             const int current = atom.exchange(next);
             counter++;
             // sync writing to prevent from interrupting by other threads
             std::osyncstream(std::cout)
                 << '#' << id << " (" << std::this_thread::get_id()
                 << ") wrote " << next << " replacing the old value "
                 << current << '\n';
             next = std::max(current, next) + 1;
         }
     };
     std::vector<std::thread> v;
     for (std::size_t i = 0; i < ThreadNumber; ++i){
         v.emplace_back(lambda, i);
     }
     for (auto& tr : v){
         tr.join();
     }
     std::cout << ThreadNumber << " threads adding 0 to "
               << Sum << " takes total "
               << counter << " times\n";
 }

Possible output:
 #1 (140552371918592) wrote 0 replacing the old value 0
 #2 (140552363525888) wrote 0 replacing the old value 0
 #1 (140552371918592) wrote 1 replacing the old value 0
 #1 (140552371918592) wrote 2 replacing the old value 1
 #2 (140552363525888) wrote 1 replacing the old value 1
 #1 (140552371918592) wrote 3 replacing the old value 2
 #1 (140552371918592) wrote 4 replacing the old value 2
 #2 (140552363525888) wrote 2 replacing the old value 3
 #2 (140552363525888) wrote 4 replacing the old value 0
 #3 (140552355133184) wrote 0 replacing the old value 4
 #0 (140552380311296) wrote 0 replacing the old value 0
 #0 (140552380311296) wrote 1 replacing the old value 4
 #4 (140552346740480) wrote 0 replacing the old value 1
 #4 (140552346740480) wrote 2 replacing the old value 0
 #4 (140552346740480) wrote 3 replacing the old value 2
 #4 (140552346740480) wrote 4 replacing the old value 3
 5 threads adding 0 to 5 takes total 16 times

See also
   atomic_exchange atomically replaces the value of the atomic object with
   atomic_exchange_explicit non-atomic argument and returns the old value of the atomic
   (C++11) (function template)
   (C++11)
   exchange replaces the argument with a new value and returns its
   (C++14) previous value
                        (function template)