std::atomic...::atomic_ref(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸŽ€ NAME πŸŽ€

std::atomic_ref::atomic_ref β€” literally std::atomic_ref::atomic_ref, the constructor bestie. The NAME line is giving std::atomic_ref::atomic_ref - std::atomic_ref::atomic_ref, and we are obsessed. πŸ’…

okay so this is std::atomic...::atomic_ref(3) from the C++ Standard Libary zone, and it's all about making an atomic_ref πŸ’–


✨ Synopsis ✨

Both of these are tagged (since C++20), no cap:

          explicit atomic_ref( T& obj );                (1) (since C++20)
          atomic_ref( const atomic_ref& ref ) noexcept; (2) (since C++20)

Constructs a new atomic_ref object. ✨

  1. Constructs an atomic_ref object referencing the object obj. The behavior is undefined if obj is not aligned to required_alignment. 😭 This is not a vibe-check you want to fail, bestie.
  2. Constructs an atomic_ref object referencing the object referenced by ref.

🌸 Parameters 🌸

  • obj β€” object to reference
  • ref β€” another atomic_ref object to copy from

πŸ¦‹ Example πŸ¦‹

The program increments the values in a container using several threads. Then the final sum is printed. Non-atomic access may "loss" the results of some operations due to data-races. πŸ™ˆ

Non-atomic access may "loss" the results of some operations due to data-races.
       // Run this code

        #include <atomic>
        #include <iostream>
        #include <numeric>
        #include <thread>
        #include <vector>

        int main()
        {
            using Data = std::vector<char>;

            auto inc_atomically = [](Data& data)
            {
                for (Data::value_type& x : data)
                {
                    auto xx = std::atomic_ref<Data::value_type>(x);
                    ++xx; // atomic read-modify-write
                }
            };

            auto inc_directly = [](Data& data)
            {
                for (Data::value_type& x : data)
                    ++x;
            };

            auto test_run = [](const auto Fun)
            {
                Data data(10'000'000);
                {
                    std::jthread j1{Fun, std::ref(data)};
                    std::jthread j2{Fun, std::ref(data)};
                    std::jthread j3{Fun, std::ref(data)};
                    std::jthread j4{Fun, std::ref(data)};
                }
                std::cout << "sum = " << std::accumulate(cbegin(data),
       cend(data), 0) << '\n';
            };

            test_run(inc_atomically);
            test_run(inc_directly);
        }

🌈 Possible output: 🌈

        sum = 40000000
        sum = 39994973

source/version check, bestie: http://cppreference.com Β· 2024.06.10 Β· std::atomic...::atomic_ref(3) β€” that's the whole tea πŸ«ΆπŸ’…πŸ”₯

πŸ“¦ where this page comes from