OpenShot Library | libopenshot-audio  0.2.0
juce_Atomic.h
1 
2 /** @weakgroup juce_core-memory
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 #ifndef DOXYGEN
31  namespace AtomicHelpers
32  {
33  template <typename T> struct DiffTypeHelper { using Type = T; };
34  template <typename T> struct DiffTypeHelper<T*> { using Type = std::ptrdiff_t; };
35  }
36 #endif
37 
38 //==============================================================================
39 /**
40  A simple wrapper around std::atomic.
41 
42  @tags{Core}
43 */
44 template <typename Type>
45 struct Atomic final
46 {
47  using DiffType = typename AtomicHelpers::DiffTypeHelper<Type>::Type;
48 
49  /** Creates a new value, initialised to zero. */
50  Atomic() noexcept : value (Type()) {}
51 
52  /** Creates a new value, with a given initial value. */
53  Atomic (Type initialValue) noexcept : value (initialValue) {}
54 
55  /** Copies another value (atomically). */
56  Atomic (const Atomic& other) noexcept : value (other.get()) {}
57 
58  /** Destructor. */
59  ~Atomic() noexcept
60  {
61  #if __cpp_lib_atomic_is_always_lock_free
62  static_assert (std::atomic<Type>::is_always_lock_free,
63  "This class can only be used for lock-free types");
64  #endif
65  }
66 
67  /** Atomically reads and returns the current value. */
68  Type get() const noexcept { return value.load(); }
69 
70  /** Atomically sets the current value. */
71  void set (Type newValue) noexcept { value = newValue; }
72 
73  /** Atomically sets the current value, returning the value that was replaced. */
74  Type exchange (Type newValue) noexcept { return value.exchange (newValue); }
75 
76  /** Atomically compares this value with a target value, and if it is equal, sets
77  this to be equal to a new value.
78 
79  This operation is the atomic equivalent of doing this:
80  @code
81  bool compareAndSetBool (Type newValue, Type valueToCompare)
82  {
83  if (get() == valueToCompare)
84  {
85  set (newValue);
86  return true;
87  }
88 
89  return false;
90  }
91  @endcode
92 
93  Internally, this method calls std::atomic::compare_exchange_strong with
94  memory_order_seq_cst (the strictest std::memory_order).
95 
96  @returns true if the comparison was true and the value was replaced; false if
97  the comparison failed and the value was left unchanged.
98  @see compareAndSetValue
99  */
100  bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept
101  {
102  return value.compare_exchange_strong (valueToCompare, newValue);
103  }
104 
105  /** Copies another value into this one (atomically). */
106  Atomic<Type>& operator= (const Atomic& other) noexcept
107  {
108  value = other.value.load();
109  return *this;
110  }
111 
112  /** Copies another value into this one (atomically). */
113  Atomic<Type>& operator= (Type newValue) noexcept
114  {
115  value = newValue;
116  return *this;
117  }
118 
119  /** Atomically adds a number to this value, returning the new value. */
120  Type operator+= (DiffType amountToAdd) noexcept { return value += amountToAdd; }
121 
122  /** Atomically subtracts a number from this value, returning the new value. */
123  Type operator-= (DiffType amountToSubtract) noexcept { return value -= amountToSubtract; }
124 
125  /** Atomically increments this value, returning the new value. */
126  Type operator++() noexcept { return ++value; }
127 
128  /** Atomically decrements this value, returning the new value. */
129  Type operator--() noexcept { return --value; }
130 
131  /** Implements a memory read/write barrier.
132 
133  Internally this calls std::atomic_thread_fence with
134  memory_order_seq_cst (the strictest std::memory_order).
135  */
136  void memoryBarrier() noexcept { atomic_thread_fence (std::memory_order_seq_cst); }
137 
138  /** The std::atomic object that this class operates on. */
139  std::atomic<Type> value;
140 
141  //==============================================================================
142  #ifndef DOXYGEN
143  /* This method has been deprecated as there is no equivalent method in
144  std::atomic. Use compareAndSetBool instead.
145  */
146  JUCE_DEPRECATED (Type compareAndSetValue (Type, Type) noexcept);
147  #endif
148 };
149 
150 } // namespace juce
151 
152 /** @}*/
A simple wrapper around std::atomic.
Definition: juce_Atomic.h:45
Atomic(Type initialValue) noexcept
Creates a new value, with a given initial value.
Definition: juce_Atomic.h:53
Type operator--() noexcept
Atomically decrements this value, returning the new value.
Definition: juce_Atomic.h:129
Atomic(const Atomic &other) noexcept
Copies another value (atomically).
Definition: juce_Atomic.h:56
std::atomic< Type > value
The std::atomic object that this class operates on.
Definition: juce_Atomic.h:139
Type exchange(Type newValue) noexcept
Atomically sets the current value, returning the value that was replaced.
Definition: juce_Atomic.h:74
void memoryBarrier() noexcept
Implements a memory read/write barrier.
Definition: juce_Atomic.h:136
Atomic() noexcept
Creates a new value, initialised to zero.
Definition: juce_Atomic.h:50
bool compareAndSetBool(Type newValue, Type valueToCompare) noexcept
Atomically compares this value with a target value, and if it is equal, sets this to be equal to a ne...
Definition: juce_Atomic.h:100
~Atomic() noexcept
Destructor.
Definition: juce_Atomic.h:59
Type operator++() noexcept
Atomically increments this value, returning the new value.
Definition: juce_Atomic.h:126