Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -37,6 +37,9 @@ #ifndef __has_builtin #define __has_builtin(__x) 0 #endif +#ifndef __has_extension +#define __has_extension(__x) 0 +#endif #ifndef __has_feature #define __has_feature(__x) 0 #endif @@ -767,4 +770,15 @@ #define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #endif -#endif // _LIBCPP_CONFIG +#if __has_extension(c_atomic) +#define _LIBCPP_HAS_C_ATOMIC_IMP +#elif _GNUC_VER > 407 +#define _LIBCPP_HAS_GCC_ATOMIC_IMP +#endif + +#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \ + || defined(_LIBCPP_HAS_NO_THREADS) +#define _LIBCPP_HAS_NO_ATOMIC_HEADER +#endif + +#endif // _LIBCPP_CONFIG Index: include/atomic =================================================================== --- include/atomic +++ include/atomic @@ -535,21 +535,20 @@ #ifdef _LIBCPP_HAS_NO_THREADS #error is not supported on this single threaded system -#else // !_LIBCPP_HAS_NO_THREADS +#endif +#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) +#error is not implemented +#endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !__has_feature(cxx_atomic) && _GNUC_VER < 407 -#error is not implemented -#else - typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order; -#if _GNUC_VER >= 407 +#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) namespace __gcc_atomic { template struct __gcc_atomic_t { @@ -805,7 +804,7 @@ return __atomic_fetch_xor(&__a->__a_value, __pattern, __gcc_atomic::__to_gcc_order(__order)); } -#endif // _GNUC_VER >= 407 +#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP template inline _LIBCPP_INLINE_VISIBILITY @@ -825,7 +824,7 @@ _LIBCPP_INLINE_VISIBILITY bool is_lock_free() const volatile _NOEXCEPT { -#if __has_feature(cxx_atomic) +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) return __c11_atomic_is_lock_free(sizeof(_Tp)); #else return __atomic_is_lock_free(sizeof(_Tp), 0); @@ -1779,8 +1778,6 @@ #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} -// lock-free property - #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE @@ -1792,10 +1789,6 @@ #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE -#endif // !__has_feature(cxx_atomic) - _LIBCPP_END_NAMESPACE_STD -#endif // !_LIBCPP_HAS_NO_THREADS - #endif // _LIBCPP_ATOMIC Index: include/ios =================================================================== --- include/ios +++ include/ios @@ -216,7 +216,7 @@ #include <__locale> #include -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) #include // for __xindex_ #endif @@ -367,7 +367,9 @@ int* __index_; size_t __event_size_; size_t __event_cap_; -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only +// enabled with clang. +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) static atomic __xindex_; #else static int __xindex_; Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -612,7 +612,7 @@ #include #endif -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include #endif @@ -5381,7 +5381,9 @@ basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only +// enabled with clang. +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) class _LIBCPP_TYPE_VIS __sp_mut { @@ -5507,7 +5509,7 @@ return atomic_compare_exchange_weak(__p, __v, __w); } -#endif // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) //enum class struct _LIBCPP_TYPE_VIS pointer_safety Index: src/ios.cpp =================================================================== --- src/ios.cpp +++ src/ios.cpp @@ -152,7 +152,7 @@ } // xalloc -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) atomic ios_base::__xindex_ = ATOMIC_VAR_INIT(0); #else int ios_base::__xindex_ = 0; Index: src/memory.cpp =================================================================== --- src/memory.cpp +++ src/memory.cpp @@ -124,7 +124,7 @@ #endif // _LIBCPP_NO_RTTI -#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) static const std::size_t __sp_mut_count = 16; static pthread_mutex_t mut_back_imp[__sp_mut_count] = @@ -177,7 +177,7 @@ return muts[hash()(p) & (__sp_mut_count-1)]; } -#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS +#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) void declare_reachable(void*) Index: test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp =================================================================== --- test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp +++ test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp @@ -22,13 +22,13 @@ int main() { { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear(&f); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear(&f); assert(f.test_and_set() == 0); Index: test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp +++ test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp @@ -22,37 +22,37 @@ int main() { { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_release); assert(f.test_and_set() == 0); } { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_release); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); assert(f.test_and_set() == 0); Index: test/std/atomics/atomics.flag/clear.pass.cpp =================================================================== --- test/std/atomics/atomics.flag/clear.pass.cpp +++ test/std/atomics/atomics.flag/clear.pass.cpp @@ -22,49 +22,49 @@ int main() { { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); f.clear(); assert(f.test_and_set() == 0); } { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_release); assert(f.test_and_set() == 0); } { - std::atomic_flag f = ATOMIC_FLAG_INIT; + std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_seq_cst); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); f.clear(); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_release); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + volatile std::atomic_flag f(false); f.test_and_set(); f.clear(std::memory_order_seq_cst); assert(f.test_and_set() == 0); Index: test/std/atomics/atomics.flag/init.pass.cpp =================================================================== --- test/std/atomics/atomics.flag/init.pass.cpp +++ test/std/atomics/atomics.flag/init.pass.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads +// XFAIL: c++98, c++03 // Index: test/std/atomics/atomics.flag/init03.pass.cpp =================================================================== --- /dev/null +++ test/std/atomics/atomics.flag/init03.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// + +// struct atomic_flag + +// TESTING EXTENSION atomic_flag(bool) + +#include +#include + +int main() +{ + std::atomic_flag f(false); + assert(f.test_and_set() == 0); +} Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp @@ -24,9 +24,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -54,35 +55,7 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp @@ -27,9 +27,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -61,35 +62,7 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp @@ -25,10 +25,10 @@ #include #include +#include "atomic_helpers.h" template -void -test() +void test() { { typedef std::atomic A; @@ -56,35 +56,7 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp @@ -29,9 +29,10 @@ #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -63,35 +64,7 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp @@ -24,9 +24,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -39,35 +40,8 @@ assert(vt == T(4)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp @@ -24,9 +24,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -41,35 +42,8 @@ assert(vt == T(4)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp @@ -32,9 +32,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -53,8 +54,7 @@ } template -void -testp() +void testp() { { typedef std::atomic A; @@ -74,38 +74,9 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - A(const A& a) : i(a.i) {} - A(const volatile A& a) : i(a.i) {} - - void operator=(const volatile A& a) volatile {i = a.i;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); testp(); testp(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp @@ -32,9 +32,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -78,38 +79,9 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - A(const A& a) : i(a.i) {} - A(const volatile A& a) : i(a.i) {} - - void operator=(const volatile A& a) volatile {i = a.i;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); testp(); testp(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp @@ -23,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -45,20 +46,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp @@ -23,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -47,20 +48,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp @@ -23,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -45,20 +46,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp @@ -23,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -47,20 +48,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp @@ -32,9 +32,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -53,8 +54,7 @@ } template -void -testp() +void testp() { { typedef std::atomic A; @@ -74,38 +74,9 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - A(const A& a) : i(a.i) {} - A(const volatile A& a) : i(a.i) {} - - void operator=(const volatile A& a) volatile {i = a.i;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); testp(); testp(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp @@ -33,9 +33,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -56,8 +57,7 @@ } template -void -testp() +void testp() { { typedef std::atomic A; @@ -79,38 +79,9 @@ } } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - A(const A& a) : i(a.i) {} - A(const volatile A& a) : i(a.i) {} - - void operator=(const volatile A& a) volatile {i = a.i;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); testp(); testp(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp @@ -23,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { { typedef std::atomic A; @@ -45,20 +46,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp @@ -23,6 +23,8 @@ #include #include +#include "atomic_helpers.h" + template void test() @@ -47,20 +49,5 @@ int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h =================================================================== --- /dev/null +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h @@ -0,0 +1,49 @@ +#ifndef ATOMIC_HELPERS_H +#define ATOMIC_HELPERS_H + +#include + +#include "test_macros.h" + +struct UserAtomicType +{ + int i; + + explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} + + friend bool operator==(const UserAtomicType& x, const UserAtomicType& y) + { return x.i == y.i; } +}; + +#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS +#define TEST_UNICODE_CHAR_TYPES_IMP() +#else +#define TEST_UNICODE_CHAR_TYPES_IMP() \ + test(); \ + test(); +# +#endif + +#define TEST_EACH_ATOMIC_INTEGRAL() \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + TEST_UNICODE_CHAR_TYPES_IMP() \ + test() + +#define TEST_EACH_ATOMIC_TYPE() \ + TEST_EACH_ATOMIC_INTEGRAL(); \ + test(); \ + test(); \ + test() + + +#endif // ATOMIC_HELPER_H Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// ... assertion fails line 34 +// ... assertion fails line 36 // @@ -24,6 +24,8 @@ #include #include +#include "atomic_helpers.h" + template void test() @@ -37,35 +39,7 @@ assert(vt == T(2)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp @@ -22,9 +22,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -42,22 +43,5 @@ int main() { test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// ... assertion fails line 34 +// ... assertion fails line 35 // @@ -24,9 +24,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -37,35 +38,7 @@ assert(std::atomic_load(&vt) == T(2)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp @@ -24,9 +24,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -37,35 +38,7 @@ assert(std::atomic_load_explicit(&vt, std::memory_order_seq_cst) == T(2)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; - int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// ... assertion fails line 31 // @@ -24,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -37,35 +37,8 @@ assert(vt == T(2)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// ... assertion fails line 31 // @@ -24,9 +23,10 @@ #include #include +#include "atomic_helpers.h" + template -void -test() +void test() { typedef std::atomic A; A t; @@ -37,35 +37,8 @@ assert(vt == T(2)); } -struct A -{ - int i; - - explicit A(int d = 0) noexcept {i=d;} - - friend bool operator==(const A& x, const A& y) - {return x.i == y.i;} -}; int main() { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + TEST_EACH_ATOMIC_TYPE(); } Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads +// XFAIL: c++98, c++03 // Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp =================================================================== --- test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp +++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp @@ -22,6 +22,8 @@ #include #include +#include "atomic_helpers.h" + struct UserType { int i; @@ -55,6 +57,6 @@ int main() { - test(); test(); + TEST_EACH_ATOMIC_INTEGRAL(); } Index: test/support/test_macros.h =================================================================== --- test/support/test_macros.h +++ test/support/test_macros.h @@ -56,8 +56,10 @@ #endif #if TEST_STD_VER >= 11 +#define TEST_CONSTEXPR constexpr #define TEST_NOEXCEPT noexcept #else +#define TEST_CONSTEXPR #define TEST_NOEXCEPT #endif