From 749adeba3d655f27abec2a3589a612a15d8be21c Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 19 Aug 2015 17:21:46 +0000 Subject: [PATCH] [libcxx] Allow use of in C++03. Try 3. Summary: After putting this question up on cfe-dev I have decided that it would be best to allow the use of `` in C++03. Although static initialization is a concern the syntax required to get it is C++11 only. Meaning that C++11 constant static initialization cannot silently break in C++03, it will always cause a syntax error. Furthermore `ATOMIC_VAR_INIT` and `ATOMIC_FLAG_INIT` remain defined in C++03 even though they cannot be used because C++03 usages will cause better error messages. The main change in this patch is to replace `__has_feature(cxx_atomic)`, which only returns true when C++ >= 11, to `__has_extension(c_atomic)` which returns true whenever clang supports the required atomic builtins. This patch adds the following macros: * `_LIBCPP_HAS_C_ATOMIC_IMP` - Defined on clang versions which provide the C `_Atomic` keyword. * `_LIBCPP_HAS_GCC_ATOMIC_IMP` - Defined on GCC > 4.7. We must use the fallback atomic implementation. * `_LIBCPP_HAS_NO_ATOMIC_HEADER` - Defined when it is not safe to include ``. `_LIBCPP_HAS_C_ATOMIC_IMP` and `_LIBCPP_HAS_GCC_ATOMIC_IMP` are mutually exclusive, only one should be defined. If neither is defined then `` is not implemented and including `` will issue an error. Reviewers: chandlerc, jroelofs, mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D11555 llvm-svn: 245463 --- libcxx/include/__config | 16 +++- libcxx/include/atomic | 21 ++--- libcxx/include/ios | 6 +- libcxx/include/memory | 8 +- libcxx/src/ios.cpp | 2 +- libcxx/src/memory.cpp | 4 +- .../atomics.flag/atomic_flag_clear.pass.cpp | 4 +- .../atomic_flag_clear_explicit.pass.cpp | 12 +-- .../std/atomics/atomics.flag/clear.pass.cpp | 16 ++-- .../std/atomics/atomics.flag/init.pass.cpp | 1 + .../std/atomics/atomics.flag/init03.pass.cpp | 25 ++++++ .../atomic_compare_exchange_strong.pass.cpp | 38 ++------ ..._compare_exchange_strong_explicit.pass.cpp | 38 ++------ .../atomic_compare_exchange_weak.pass.cpp | 37 ++------ ...ic_compare_exchange_weak_explicit.pass.cpp | 38 ++------ .../atomic_exchange.pass.cpp | 39 ++------- .../atomic_exchange_explicit.pass.cpp | 39 ++------- .../atomic_fetch_add.pass.cpp | 82 ++++++------------ .../atomic_fetch_add_explicit.pass.cpp | 41 ++------- .../atomic_fetch_and.pass.cpp | 27 ++---- .../atomic_fetch_and_explicit.pass.cpp | 27 ++---- .../atomic_fetch_or.pass.cpp | 27 ++---- .../atomic_fetch_or_explicit.pass.cpp | 27 ++---- .../atomic_fetch_sub.pass.cpp | 82 ++++++------------ .../atomic_fetch_sub_explicit.pass.cpp | 86 +++++++------------ .../atomic_fetch_xor.pass.cpp | 27 ++---- .../atomic_fetch_xor_explicit.pass.cpp | 27 ++---- .../atomic_helpers.h | 51 +++++++++++ .../atomic_init.pass.cpp | 40 ++------- .../atomic_is_lock_free.pass.cpp | 31 ++----- .../atomic_load.pass.cpp | 40 ++------- .../atomic_load_explicit.pass.cpp | 38 ++------ .../atomic_store.pass.cpp | 40 ++------- .../atomic_store_explicit.pass.cpp | 40 ++------- .../atomic_var_init.pass.cpp | 1 + .../ctor.pass.cpp | 40 +++++---- libcxx/test/support/test_macros.h | 2 + 37 files changed, 363 insertions(+), 757 deletions(-) create mode 100644 libcxx/test/std/atomics/atomics.flag/init03.pass.cpp create mode 100644 libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h diff --git a/libcxx/include/__config b/libcxx/include/__config index 5c15156e9ae7..76675008605f 100644 --- a/libcxx/include/__config +++ b/libcxx/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 @@ -773,4 +776,15 @@ extern "C" void __sanitizer_annotate_contiguous_container( #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 diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 97a998d33633..13965fbdd2c1 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -535,21 +535,20 @@ void atomic_signal_fence(memory_order m) noexcept; #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 @@ static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern, 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 @@ struct __atomic_base // false _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 @@ typedef atomic atomic_uintmax_t; #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 @@ typedef atomic atomic_uintmax_t; #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 diff --git a/libcxx/include/ios b/libcxx/include/ios index ff79998b0bbf..8843ed4ca858 100644 --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -216,7 +216,7 @@ storage-class-specifier const error_category& iostream_category() noexcept; #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 @@ private: 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_; diff --git a/libcxx/include/memory b/libcxx/include/memory index 750034b3cbd3..38ce433b2f2a 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -612,7 +612,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #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 @@ inline _LIBCPP_INLINE_VISIBILITY 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 @@ atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v 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 diff --git a/libcxx/src/ios.cpp b/libcxx/src/ios.cpp index 9d9daa99adc1..23e3ee0ca044 100644 --- a/libcxx/src/ios.cpp +++ b/libcxx/src/ios.cpp @@ -152,7 +152,7 @@ ios_base::getloc() const } // 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; diff --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp index 369f97ffbb58..5b81f26e3dc0 100644 --- a/libcxx/src/memory.cpp +++ b/libcxx/src/memory.cpp @@ -124,7 +124,7 @@ __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT #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 @@ __get_sp_mut(const void* p) 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*) diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp index 8a60f8196dab..3a74e13faf19 100644 --- a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp +++ b/libcxx/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); diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp index 92e57ecc03f8..0467384455cc 100644 --- a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp +++ b/libcxx/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); diff --git a/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp b/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp index 7c9362680bba..ea5ae45ae99a 100644 --- a/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp +++ b/libcxx/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); diff --git a/libcxx/test/std/atomics/atomics.flag/init.pass.cpp b/libcxx/test/std/atomics/atomics.flag/init.pass.cpp index c90509d8fbb5..c4a121b094a4 100644 --- a/libcxx/test/std/atomics/atomics.flag/init.pass.cpp +++ b/libcxx/test/std/atomics/atomics.flag/init.pass.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads +// XFAIL: c++98, c++03 // diff --git a/libcxx/test/std/atomics/atomics.flag/init03.pass.cpp b/libcxx/test/std/atomics/atomics.flag/init03.pass.cpp new file mode 100644 index 000000000000..0910bc5ceccb --- /dev/null +++ b/libcxx/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); +} diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp index f1cc993ed33e..7b221dc6eff8 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp @@ -24,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A a; @@ -52,37 +53,10 @@ test() assert(a == T(2)); assert(t == 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp index f667ab7f139b..27de5bec4928 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp @@ -27,10 +27,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A a; @@ -59,37 +60,10 @@ test() assert(a == T(2)); assert(t == 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp index 175c445d4560..8c12715647e8 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp @@ -25,11 +25,11 @@ #include #include +#include "atomic_helpers.h" template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A a; @@ -54,37 +54,10 @@ test() assert(a == T(2)); assert(t == 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp index 46f80bfbcb7b..90a93f02b978 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp @@ -29,10 +29,11 @@ #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A a; @@ -61,37 +62,10 @@ test() assert(a == T(2)); assert(t == 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp index 525e74aa6374..035d974427a4 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp @@ -24,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_init(&t, T(1)); @@ -37,37 +38,11 @@ test() std::atomic_init(&vt, T(3)); assert(std::atomic_exchange(&vt, T(4)) == T(3)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp index 9fe4ac816448..4d66bb5f3b81 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp @@ -24,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_init(&t, T(1)); @@ -39,37 +40,11 @@ test() assert(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst) == T(3)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp index 3408def9058a..48ff601539cf 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp @@ -32,10 +32,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -50,62 +51,33 @@ test() assert(std::atomic_fetch_add(&t, T(2)) == T(1)); assert(t == T(3)); } -} - -template -void -testp() -{ - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - A t; - std::atomic_init(&t, T(1*sizeof(X))); - assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); - assert(t == T(3*sizeof(X))); - } - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - volatile A t; - std::atomic_init(&t, T(1*sizeof(X))); - assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); - assert(t == T(3*sizeof(X))); - } -} - -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;} + } }; +template +void testp() +{ + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + volatile A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } +} + 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 + TestEachIntegralType()(); testp(); testp(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp index 9977bd491e7a..2dc90c9aca68 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp @@ -32,10 +32,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -52,7 +53,8 @@ test() std::memory_order_seq_cst) == T(1)); assert(t == T(3)); } -} + } +}; template void @@ -78,38 +80,9 @@ testp() } } -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 + TestEachIntegralType()(); testp(); testp(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp index 4c7c0432efc9..57355d30411e 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -41,24 +42,10 @@ test() assert(std::atomic_fetch_and(&t, T(2)) == T(3)); assert(t == T(2)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp index d83bbf264de5..26ff5f65e7db 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -43,24 +44,10 @@ test() std::memory_order_seq_cst) == T(3)); assert(t == T(2)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp index acf6d439de43..ca44fdc3217d 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -41,24 +42,10 @@ test() assert(std::atomic_fetch_or(&t, T(2)) == T(3)); assert(t == T(3)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp index 72685e4d9408..72bbde798cb9 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -43,24 +44,10 @@ test() std::memory_order_seq_cst) == T(3)); assert(t == T(3)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp index ed8b541291af..2743040428c5 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp @@ -32,10 +32,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -50,62 +51,33 @@ test() assert(std::atomic_fetch_sub(&t, T(2)) == T(3)); assert(t == T(1)); } -} - -template -void -testp() -{ - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - A t; - std::atomic_init(&t, T(3*sizeof(X))); - assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); - assert(t == T(1*sizeof(X))); - } - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - volatile A t; - std::atomic_init(&t, T(3*sizeof(X))); - assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); - assert(t == T(1*sizeof(X))); - } -} - -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;} + } }; +template +void testp() +{ + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + volatile A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } +} + 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 + TestEachIntegralType()(); testp(); testp(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp index e6c92eada6df..6e94c505fd8c 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp @@ -33,10 +33,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -53,64 +54,35 @@ test() std::memory_order_seq_cst) == T(3)); assert(t == T(1)); } -} - -template -void -testp() -{ - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - A t; - std::atomic_init(&t, T(3*sizeof(X))); - assert(std::atomic_fetch_sub_explicit(&t, 2, - std::memory_order_seq_cst) == T(3*sizeof(X))); - assert(t == T(1*sizeof(X))); - } - { - typedef std::atomic A; - typedef typename std::remove_pointer::type X; - volatile A t; - std::atomic_init(&t, T(3*sizeof(X))); - assert(std::atomic_fetch_sub_explicit(&t, 2, - std::memory_order_seq_cst) == T(3*sizeof(X))); - assert(t == T(1*sizeof(X))); - } -} - -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;} + } }; +template +void testp() +{ + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub_explicit(&t, 2, + std::memory_order_seq_cst) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } + { + typedef std::atomic A; + typedef typename std::remove_pointer::type X; + volatile A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub_explicit(&t, 2, + std::memory_order_seq_cst) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } +} + 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 + TestEachIntegralType()(); testp(); testp(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp index fc6b97b7db45..42d57dedbd11 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -41,24 +42,10 @@ test() assert(std::atomic_fetch_xor(&t, T(2)) == T(3)); assert(t == T(1)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp index 58772aa4d152..8f388fee6325 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp @@ -23,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -43,24 +44,10 @@ test() std::memory_order_seq_cst) == T(3)); assert(t == T(1)); } -} + } +}; 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 + TestEachIntegralType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h new file mode 100644 index 000000000000..e31420b156c6 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h @@ -0,0 +1,51 @@ +#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; } +}; + +template < template class TestFunctor > +struct TestEachIntegralType { + void operator()() const { + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + TestFunctor()(); + TestFunctor()(); +#endif + } +}; + +template < template class TestFunctor > +struct TestEachAtomicType { + void operator()() const { + TestEachIntegralType()(); + TestFunctor()(); + TestFunctor()(); + TestFunctor()(); + } +}; + + +#endif // ATOMIC_HELPER_H diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp index 137b6f60f746..884c02dfe7ea 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp +++ b/libcxx/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,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_init(&t, T(1)); @@ -35,37 +36,10 @@ test() volatile A vt; std::atomic_init(&vt, T(2)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp index ee229120a62a..5d50016ed32c 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp @@ -22,17 +22,19 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; bool b1 = std::atomic_is_lock_free(static_cast(&t)); volatile A vt; bool b2 = std::atomic_is_lock_free(static_cast(&vt)); assert(b1 == b2); -} + } +}; struct A { @@ -41,23 +43,6 @@ struct A 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(); + TestFn()(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp index 66918c71f1f6..e7b8e64b434f 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp +++ b/libcxx/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,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_init(&t, T(1)); @@ -35,37 +36,10 @@ test() volatile A vt; std::atomic_init(&vt, T(2)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp index 5f402a9f139f..56533fa871e5 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp @@ -24,10 +24,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_init(&t, T(1)); @@ -35,37 +36,10 @@ test() volatile A vt; std::atomic_init(&vt, T(2)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp index 2b9582b3c522..e61dae904116 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp +++ b/libcxx/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,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_store(&t, T(1)); @@ -35,37 +35,11 @@ test() volatile A vt; std::atomic_store(&vt, T(2)); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp index 8fe0c7d88421..e57cf8b1b323 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp +++ b/libcxx/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,10 +23,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { typedef std::atomic A; A t; std::atomic_store_explicit(&t, T(1), std::memory_order_seq_cst); @@ -35,37 +35,11 @@ test() volatile A vt; std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst); 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(); + TestEachAtomicType()(); } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp index 5fed691da268..9f25807fbcde 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp +++ b/libcxx/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 // diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp index f85172a0149c..f6944c7255bc 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp +++ b/libcxx/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; @@ -34,27 +36,29 @@ struct UserType { }; template -void test() { - typedef std::atomic Atomic; - static_assert(std::is_literal_type::value, ""); - constexpr Tp t(42); - { - constexpr Atomic a(t); - assert(a == t); +struct TestFunc { + void operator()() const { + typedef std::atomic Atomic; + static_assert(std::is_literal_type::value, ""); + constexpr Tp t(42); + { + constexpr Atomic a(t); + assert(a == t); + } + { + constexpr Atomic a{t}; + assert(a == t); + } + { + constexpr Atomic a = ATOMIC_VAR_INIT(t); + assert(a == t); + } } - { - constexpr Atomic a{t}; - assert(a == t); - } - { - constexpr Atomic a = ATOMIC_VAR_INIT(t); - assert(a == t); - } -} +}; int main() { - test(); - test(); + TestFunc()(); + TestEachIntegralType()(); } diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h index 08ec28f7c7b6..8602f5286ef9 100644 --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -62,8 +62,10 @@ #endif #if TEST_STD_VER >= 11 +#define TEST_CONSTEXPR constexpr #define TEST_NOEXCEPT noexcept #else +#define TEST_CONSTEXPR #define TEST_NOEXCEPT #endif