/* Copyright (C) 2015 Povilas Kanapickas This file is part of cppreference-doc This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. */ #ifndef CPPREFERENCE_ATOMIC_H #define CPPREFERENCE_ATOMIC_H #include // for ptrdiff_t #include namespace std { #if CPPREFERENCE_STDVER>= 2011 enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst }; template struct atomic { atomic() = default; constexpr atomic(T desired); atomic(const atomic&) = delete; T operator=(T desired); T operator=(T desired) volatile; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; bool is_lock_free() const; bool is_lock_free() const volatile; void store(T desired, std::memory_order order = std::memory_order_seq_cst); void store(T desired, std::memory_order order = std::memory_order_seq_cst) volatile; T load(std::memory_order order = std::memory_order_seq_cst) const; T load(std::memory_order order = std::memory_order_seq_cst) const volatile; operator T() const; operator T() const volatile; T exchange(T desired, std::memory_order order = std::memory_order_seq_cst); T exchange(T desired, std::memory_order order = std::memory_order_seq_cst) volatile; bool compare_exchange_weak(T& expected, T desired, std::memory_order success, std::memory_order failure); bool compare_exchange_weak(T& expected, T desired, std::memory_order success, std::memory_order failure) volatile; bool compare_exchange_weak(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst); bool compare_exchange_weak(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst) volatile; bool compare_exchange_strong(T& expected, T desired, std::memory_order success, std::memory_order failure); bool compare_exchange_strong(T& expected, T desired, std::memory_order success, std::memory_order failure) volatile; bool compare_exchange_strong(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst); bool compare_exchange_strong(T& expected, T desired, std::memory_order order = std::memory_order_seq_cst) volatile; // member of atomic T fetch_add(T arg, memory_order = std::memory_order_seq_cst); T fetch_add(T arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T* fetch_add(std::ptrdiff_t arg, memory_order = std::memory_order_seq_cst); T* fetch_add(std::ptrdiff_t arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T fetch_sub(T arg, memory_order = std::memory_order_seq_cst); T fetch_sub(T arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T* fetch_sub(std::ptrdiff_t arg, memory_order = std::memory_order_seq_cst); T* fetch_sub(std::ptrdiff_t arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T fetch_and(T arg, memory_order = std::memory_order_seq_cst); T fetch_and(T arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T fetch_or(T arg, memory_order = std::memory_order_seq_cst); T fetch_or(T arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T fetch_xor(T arg, memory_order = std::memory_order_seq_cst); T fetch_xor(T arg, memory_order = std::memory_order_seq_cst) volatile; // member of atomic T operator++(); T operator++() volatile; T operator++(int); T operator++(int) volatile; T operator--(); T operator--() volatile; T operator--(int); T operator--(int) volatile; T operator+=(T arg); T operator+=(T arg) volatile; T operator-=(T arg); T operator-=(T arg) volatile; T operator&=(T arg); T operator&=(T arg) volatile; T operator|=(T arg); T operator|=(T arg) volatile; T operator^=(T arg); T operator^=(T arg) volatile; // member of atomic T* operator++(); T* operator++() volatile; T* operator++(int); T* operator++(int) volatile; T* operator--(); T* operator--() volatile; T* operator--(int); T* operator--(int) volatile; T* operator+=(std::ptrdiff_t arg); T* operator+=(std::ptrdiff_t arg) volatile; T* operator-=(std::ptrdiff_t arg); T* operator-=(std::ptrdiff_t arg) volatile; }; typedef atomic atomic_bool; typedef atomic atomic_char; typedef atomic atomic_schar; typedef atomic atomic_uchar; typedef atomic atomic_short; typedef atomic atomic_ushort; typedef atomic atomic_int; typedef atomic atomic_uint; typedef atomic atomic_long; typedef atomic atomic_ulong; typedef atomic atomic_llong; typedef atomic atomic_ullong; typedef atomic atomic_char16_t; typedef atomic atomic_char32_t; typedef atomic atomic_wchar_t; typedef atomic atomic_int_least8_t; typedef atomic atomic_uint_least8_t; typedef atomic atomic_int_least16_t; typedef atomic atomic_uint_least16_t; typedef atomic atomic_int_least32_t; typedef atomic atomic_uint_least32_t; typedef atomic atomic_int_least64_t; typedef atomic atomic_uint_least64_t; typedef atomic atomic_int_fast8_t; typedef atomic atomic_uint_fast8_t; typedef atomic atomic_int_fast16_t; typedef atomic atomic_uint_fast16_t; typedef atomic atomic_int_fast32_t; typedef atomic atomic_uint_fast32_t; typedef atomic atomic_int_fast64_t; typedef atomic atomic_uint_fast64_t; typedef atomic atomic_intptr_t; typedef atomic atomic_uintptr_t; typedef atomic atomic_size_t; typedef atomic atomic_ptrdiff_t; typedef atomic atomic_intmax_t; typedef atomic atomic_uintmax_t; template bool atomic_is_lock_free(const volatile std::atomic* obj); template bool atomic_is_lock_free(const std::atomic* obj); template void atomic_store(std::atomic* obj, T desr); template void atomic_store(volatile std::atomic* obj, T desr); template void atomic_store_explicit(std::atomic* obj, T desr, std::memory_order order); template void atomic_store_explicit(volatile std::atomic* obj, T desr, std::memory_order order); template T atomic_load(const std::atomic* obj); template T atomic_load(const volatile std::atomic* obj); template T atomic_load_explicit(const std::atomic* obj, std::memory_order order); template T atomic_load_explicit(const volatile std::atomic* obj, std::memory_order order); template T atomic_exchange(std::atomic* obj, T desr); template T atomic_exchange(volatile std::atomic* obj, T desr); template T atomic_exchange_explicit(std::atomic* obj, T desr, std::memory_order order); template T atomic_exchange_explicit(volatile std::atomic* obj, T desr, std::memory_order order); template bool atomic_compare_exchange_weak(std::atomic* obj, T* expected, T desired); template bool atomic_compare_exchange_weak(volatile std::atomic* obj, T* expected, T desired); template bool atomic_compare_exchange_strong(std::atomic* obj, T* expected, T desired); template bool atomic_compare_exchange_strong(volatile std::atomic* obj, T* expected, T desired); template bool atomic_compare_exchange_weak_explicit(std::atomic* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail); template bool atomic_compare_exchange_weak_explicit(volatile std::atomic* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail); template bool atomic_compare_exchange_strong_explicit(std::atomic* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail); template bool atomic_compare_exchange_strong_explicit(volatile std::atomic* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail); template Integral atomic_fetch_add(std::atomic* obj, Integral arg); template Integral atomic_fetch_add(volatile std::atomic* obj, Integral arg); template Integral atomic_fetch_add_explicit(std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_add_explicit(volatile std::atomic* obj, Integral arg, std::memory_order order); template T* atomic_fetch_add(std::atomic* obj, std::ptrdiff_t arg); template T* atomic_fetch_add(volatile std::atomic* obj, std::ptrdiff_t arg); template T* atomic_fetch_add_explicit(std::atomic* obj, std::ptrdiff_t arg, std::memory_order order); template T* atomic_fetch_add_explicit(volatile std::atomic* obj, std::ptrdiff_t arg, std::memory_order order); template Integral atomic_fetch_sub(std::atomic* obj, Integral arg); template Integral atomic_fetch_sub(volatile std::atomic* obj, Integral arg); template Integral atomic_fetch_sub_explicit(std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_sub_explicit(volatile std::atomic* obj, Integral arg, std::memory_order order); template T* atomic_fetch_sub(std::atomic* obj, std::ptrdiff_t arg); template T* atomic_fetch_sub(volatile std::atomic* obj, std::ptrdiff_t arg); template T* atomic_fetch_sub_explicit(std::atomic* obj, std::ptrdiff_t arg, std::memory_order order); template T* atomic_fetch_sub_explicit(volatile std::atomic* obj, std::ptrdiff_t arg, std::memory_order order); template Integral atomic_fetch_and(std::atomic* obj, Integral arg); template Integral atomic_fetch_and(volatile std::atomic* obj, Integral arg); template Integral atomic_fetch_and_explicit(std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_and_explicit(volatile std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_or(std::atomic* obj, Integral arg); template Integral atomic_fetch_or(volatile std::atomic* obj, Integral arg); template Integral atomic_fetch_or_explicit(std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_or_explicit(volatile std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_xor(std::atomic* obj, Integral arg); template Integral atomic_fetch_xor(volatile std::atomic* obj, Integral arg); template Integral atomic_fetch_xor_explicit(std::atomic* obj, Integral arg, std::memory_order order); template Integral atomic_fetch_xor_explicit(volatile std::atomic* obj, Integral arg, std::memory_order order); class atomic_flag { public: atomic_flag(); atomic_flag(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) volatile = delete; void clear(std::memory_order order = std::memory_order_seq_cst) volatile; void clear(std::memory_order order = std::memory_order_seq_cst); bool test_and_set(std::memory_order order = std::memory_order_seq_cst) volatile; bool test_and_set(std::memory_order order = std::memory_order_seq_cst); }; bool atomic_flag_test_and_set(volatile std::atomic_flag* p); bool atomic_flag_test_and_set(std::atomic_flag* p); bool atomic_flag_test_and_set_explicit(volatile std::atomic_flag* p, std::memory_order order); bool atomic_flag_test_and_set_explicit(std::atomic_flag* p, std::memory_order order); void atomic_flag_clear(volatile std::atomic_flag* p); void atomic_flag_clear(std::atomic_flag* p); void atomic_flag_clear_explicit(volatile std::atomic_flag* p, std::memory_order order); void atomic_flag_clear_explicit(std::atomic_flag* p, std::memory_order order); void atomic_signal_fence(std::memory_order order); void atomic_thread_fence(std::memory_order order); template T kill_dependency(T y); template void atomic_init(std::atomic* obj, T desired); template void atomic_init(volatile std::atomic* obj, T desired); #define ATOMIC_VAR_INIT(value) // impl-defined #define ATOMIC_FLAG_INIT // impl-defined #endif // CPPREFERENCE_STDVER>= 2011 } // namespace std #endif // CPPREFERENCE_ATOMIC_H