# std::atomic_fetch_or, std::atomic_fetch_or_explicit

From cppreference.com
< cpp‎ | atomic

Defined in header `<atomic>` |  |
| (1) | (since C++11)
template< class T > T atomic_fetch_or( std::atomic<T>* obj, typename std::atomic<T>::value_type arg ) noexcept; |  |
template< class T > T atomic_fetch_or( volatile std::atomic<T>* obj, typename std::atomic<T>::value_type arg ) noexcept; |  |
| (2) | (since C++11)
template< class T > T atomic_fetch_or_explicit( std::atomic<T>* obj, typename std::atomic<T>::value_type arg, std::memory_order order) noexcept; |  |
template< class T > T atomic_fetch_or_explicit( volatile std::atomic<T>* obj, typename std::atomic<T>::value_type arg, std::memory_order order) noexcept; |  |

Atomically replaces the value pointed by `obj` with the result of bitwise OR between the old value of `obj` and `arg`. Returns the value `obj` held previously.

The operation is performed as if the following is executed:

1) obj->fetch_or(arg)
2) obj->fetch_or(arg, order)

If `std::atomic<T>` has no `fetch_xor` member (this member is only provided for integral types), the program is ill-formed.

### Parameters

obj | - | pointer to the atomic object to modify
arg | - | the value to bitwise OR to the value stored in the atomic object
order | - | the memory synchronization ordering for this operation: all values are permitted.

### Return value

The value immediately preceding the effects of this function in the modification order of `*obj`.

### Possible implementation

    template< class T >
    T atomic_fetch_or( std::atomic<T>* obj, typename std::atomic<T>::value_type  arg )
    {
        return obj->fetch_or(arg);
    }

### Example

Run this code

    #include <iostream>
    #include <atomic>
    #include <thread>
    #include <chrono>
    #include <functional>

    // Binary semaphore for demonstrative purposes only
    // This is a simple yet meaningful example: atomic operations
    // are unnecessary without threads.
    class Semaphore {
        std::atomic_char m_signaled;
      public:
        Semaphore(bool initial = false)
        {
            m_signaled = initial;
        }
        // Block until semaphore is signaled
        void take()
        {
            while (!std::atomic_fetch_and(&m_signaled, false)) {
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
            }
        }

        void put()
        {
            std::atomic_fetch_or(&m_signaled, true);
        }
    };

    class ThreadedCounter {
        static const int N = 100;
        static const int REPORT_INTERVAL = 10;
        int m_count;
        bool m_done;
        Semaphore m_count_sem;
        Semaphore m_print_sem;

        void count_up()
        {
            for (m_count = 1; m_count <= N; m_count++) {
                if (m_count % REPORT_INTERVAL == 0) {
                    if (m_count == N) m_done = true;
                    m_print_sem.put(); // signal printing to occur
                    m_count_sem.take(); // wait until printing is complete proceeding
                }
            }
            std::cout << "count_up() done\n";
            m_done = true;
            m_print_sem.put();
        }

        void print_count()
        {
            do {
                m_print_sem.take();
                std::cout << m_count << '\n';
                m_count_sem.put();
            } while (!m_done);
            std::cout << "print_count() done\n";
        }

      public:
        ThreadedCounter() : m_done(false) {}
        void run()
        {
            auto print_thread = std::thread(&ThreadedCounter::print_count, this);
            auto count_thread = std::thread(&ThreadedCounter::count_up, this);
            print_thread.join();
            count_thread.join();
        }
    };

    int main()
    {
        ThreadedCounter m_counter;
        m_counter.run();
    }

Output:

    10
    20
    30
    40
    50
    60
    70
    80
    90
    100
    print_count() done
    count_up() done

### Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
P0558R1 | C++11 | exact type match required because `T` is deduced from multiple arguments | `T` is deduced from the `atomic` argument only

### See also

fetch_or | atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously (public member function of `std::atomic<T>`)
atomic_fetch_and atomic_fetch_and_explicit (C++11)(C++11) | replaces the atomic object with the result of bitwise AND with a non-atomic argument and obtains the previous value of the atomic (function template)
atomic_fetch_xor atomic_fetch_xor_explicit (C++11)(C++11) | replaces the atomic object with the result of bitwise XOR with a non-atomic argument and obtains the previous value of the atomic (function template)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/atomic/atomic_fetch_or&oldid=99107"