11 #include <boost/predef.h>
18 # pragma push_macro("NOMINMAX")
19 # pragma push_macro("WIN32_LEAN_AND_MEAN")
22 # define NOMINMAX // Deactivates min/max macros from windows.h
25 # ifndef WIN32_LEAN_AND_MEAN
26 # define WIN32_LEAN_AND_MEAN // Deactivates unnecessary parts of windows.h
32 # pragma pop_macro("WIN32_LEAN_AND_MEAN")
33 # pragma pop_macro("NOMINMAX")
38 #include <qi/config.hpp>
51 return __sync_bool_compare_and_swap(cond, 0, 1);
52 #elif defined _MSC_VER
53 return 1 - InterlockedCompareExchange(cond, 1, 0);
55 #error "Unknown platform, testAndSet not implemented"
81 inline int swap(
int value);
101 return __sync_add_and_fetch(&
_value, 1);
105 return __sync_sub_and_fetch(&
_value, 1);
109 __sync_lock_test_and_set(&
_value, value);
114 return __sync_lock_test_and_set(&
_value, value);
118 return __sync_bool_compare_and_swap(&
_value, testValue, setValue);
120 #elif defined(_MSC_VER)
123 return _InterlockedIncrement(&
_value);
127 return _InterlockedDecrement(&
_value);
131 InterlockedExchange(&
_value, value);
136 return InterlockedExchange(&
_value, value);
140 return _InterlockedCompareExchange(&
_value, setValue, testValue) == testValue;
155 template <
typename T>
169 :
_value(std::move(value))
197 {
_value = std::move(value);
return *
this; }
205 {
return _value.compare_exchange_strong(testValue, setValue); }
211 {
return _value.exchange(value); }
240 bool expected =
false;
241 const bool desired =
true;
242 return b.compare_exchange_strong(expected, desired);
253 bool expected =
true;
254 const bool desired =
false;
255 return b.compare_exchange_strong(expected, desired);
260 std::atomic_flag* _flag =
nullptr;
261 bool _locked =
false;
265 if (_flag && _locked)
275 , _locked{ !f.test_and_set() }
283 , _locked{ o._locked }
305 explicit operator bool()
const
318 T
src(
const std::atomic<T>& x)
325 #define _QI_INSTANCIATE(_, a, elem) ::qi::detail::newAndAssign(&elem);
374 #define QI_THREADSAFE_NEW(...) \
375 QI_ONCE(QI_VAARGS_APPLY(_QI_INSTANCIATE, _, __VA_ARGS__);)
420 #define QI_ONCE(code) \
421 static qi::detail::StaticAtomicInt QI_UNIQ_DEF(atomic_guard_a) = {0}; \
422 static qi::detail::StaticAtomicInt QI_UNIQ_DEF(atomic_guard_b) = {0}; \
423 while (!QI_UNIQ_DEF(atomic_guard_a).setIfEquals(1, 1)) \
425 bool tok = QI_UNIQ_DEF(atomic_guard_b).setIfEquals(0, 1); \
434 QI_UNIQ_DEF(atomic_guard_b) = 0; \
437 ++QI_UNIQ_DEF(atomic_guard_a); \
441 #endif // QI_ATOMIC_HPP_
void setValue(qi::Promise< R > &p, const boost::function< R()> &f)
T operator--()
Atomic pre-decrement of the value.
bool setIfEquals(T testValue, T setValue)
bool setIfEquals(int testValue, int setValue)
Atomic< T > & operator=(T value)
StaticAtomicInt & operator=(int value)
bool tryLowerAtomicFlag(std::atomic< bool > &b)
AtomicFlagLock(std::atomic_flag &f)
long testAndSet(long *cond)
bool tryRaiseAtomicFlag(std::atomic< bool > &b)
#define QI_NOEXCEPT(cond)
Specify that a function may throw or not. Do nothing if noexcept is not available.
Atomic(const Atomic &other)
void newAndAssign(T **ptr)
T operator++()
Atomic pre-increment of the value.
T operator++(int)
Atomic post-increment of the value.
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Atomic< T > & operator=(const Atomic< T > &value)
T operator--(int)
Atomic post-decrement of the value.
AtomicFlagLock(AtomicFlagLock &&o)
Various macros for qi. (deprecated, export API, disallow copy, ..) <includename>qi/macro.hpp</includename> .
AtomicFlagLock & operator=(AtomicFlagLock &&o)
AtomicFlagLock & operator=(const AtomicFlagLock &)=delete
T src(const std::atomic< T > &x)
AtomicFlagLock scopelock(std::atomic_flag &f)
model ScopeLockable std::atomic_flag: