Travis Gockel
Travis Gockel

Reputation: 27673

Does C++11 have an std::atomic<T>::add_and_fetch method?

The C++11 standard includes the wonderful std::atomic<T>, which has member functions like this one:

integral fetch_add(integral, memory_order = memory_order_seq_cst);

However, it seems to be lacking in an add_fetch method. tbb::atomic<T> overloads the += operator to behave like add_and_fetch:

 value_type operator+=( D addend ) {
     return fetch_and_add(addend)+addend;
 }

Through empirical observation, std::atomic<T> behaves the same way, but I cannot find where it says so in the standard or if that is just my STL implementation. Is this behavior guaranteed by the standard?

Upvotes: 5

Views: 3836

Answers (3)

Cubbi
Cubbi

Reputation: 47448

std::atomic<T> if T is an integral type, has a member operator+= which does the same thing. It is described, along with all other atomic compound assignment operators in §29.6.5/30-32

C A::operator op=(M operand) volatile noexcept;

C A::operator op=(M operand) noexcept;

Effects: fetch_key(operand)

Returns: fetch_key(operand) op operand

Upvotes: 4

paxdiablo
paxdiablo

Reputation: 882028

You're right that it doesn't actually provide that functionality but that's because it isn't needed. It can be emulated with the operations already there.

atomic_fetch_add is an atomic operation that fetches the current value then adds something. That "something" is totally under your control and is not changed by atomic_fetch_add.

The standard guarantees that:

  1. The old value is returned; and
  2. The value is added.

You can then simply add the value yourself to what was returned, and you have the current value as of the time the atomic operation was done. So basically:

def atomic_add_fetch (item, addendum):
    return atomic_fetch_add (item, addendum) + addendum

is the pseudo-code for an atomic_add_fetch operation.

Upvotes: 6

Nicol Bolas
Nicol Bolas

Reputation: 473926

However, it seems to be lacking in an add_fetch method.

Why would it need one? add_fetch would be this:

return atomic_value.fetch_add(number) + number;

Yes, it technically requires an extra addition. But that's pretty minor.

In any case, there is no add_fetch in the standard. There's just fetch_add, which returns the original value.

Upvotes: 3

Related Questions