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/algorithm =================================================================== --- include/algorithm +++ include/algorithm @@ -4361,6 +4361,34 @@ // inplace_merge +template +void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + _VSTD::move(__first1, __last1, __result); + return; + } + + if (__comp(*__first2, *__first1)) + { + *__result = _VSTD::move(*__first2); + ++__first2; + } + else + { + *__result = _VSTD::move(*__first1); + ++__first1; + } + } + // __first2 through __last2 are already in the right spot. +} + template void __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, @@ -4376,11 +4404,7 @@ value_type* __p = __buff; for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p) ::new(__p) value_type(_VSTD::move(*__i)); - __merge<_Compare>(move_iterator(__buff), - move_iterator(__p), - move_iterator<_BidirectionalIterator>(__middle), - move_iterator<_BidirectionalIterator>(__last), - __first, __comp); + __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp); } else { @@ -4389,9 +4413,9 @@ ::new(__p) value_type(_VSTD::move(*__i)); typedef reverse_iterator<_BidirectionalIterator> _RBi; typedef reverse_iterator _Rv; - __merge(move_iterator<_RBi>(_RBi(__middle)), move_iterator<_RBi>(_RBi(__first)), - move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)), - _RBi(__last), __negate<_Compare>(__comp)); + __half_inplace_merge(_Rv(__p), _Rv(__buff), + _RBi(__middle), _RBi(__first), + _RBi(__last), __negate<_Compare>(__comp)); } } 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: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -474,7 +474,7 @@ // template struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {}; // -template +template struct __member_pointer_traits_imp { // forward declaration; specializations later }; 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/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp =================================================================== --- test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp +++ test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp @@ -20,12 +20,35 @@ #include "test_iterators.h" +#ifndef TEST_STD_VER >= 11 +struct S { + S() : i_(0) {} + S(int i) : i_(i) {} + + S(const S& rhs) : i_(rhs.i_) {} + S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; } + + S& operator =(const S& rhs) { i_ = rhs.i_; return *this; } + S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; } + S& operator =(int i) { i_ = i; return *this; } + + bool operator <(const S& rhs) const { return i_ < rhs.i_; } + bool operator ==(const S& rhs) const { return i_ == rhs.i_; } + bool operator ==(int i) const { return i_ == i; } + + void set(int i) { i_ = i; } + + int i_; + }; +#endif + template void test_one(unsigned N, unsigned M) { + typedef typename std::iterator_traits::value_type value_type; assert(M <= N); - int* ia = new int[N]; + value_type* ia = new value_type[N]; for (unsigned i = 0; i < N; ++i) ia[i] = i; std::random_shuffle(ia, ia+N); @@ -76,4 +99,10 @@ test >(); test >(); test(); + +#ifndef TEST_STD_VER >= 11 + test >(); + test >(); + test(); +#endif // TEST_STD_VER >= 11 } Index: test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp =================================================================== --- test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp +++ test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp @@ -18,7 +18,10 @@ #include #include #include -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#include "test_macros.h" + +#ifndef TEST_STD_VER >= 11 #include struct indirect_less @@ -28,7 +31,29 @@ {return *x < *y;} }; -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +struct S { + S() : i_(0) {} + S(int i) : i_(i) {} + + S(const S& rhs) : i_(rhs.i_) {} + S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; } + + S& operator =(const S& rhs) { i_ = rhs.i_; return *this; } + S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; } + S& operator =(int i) { i_ = i; return *this; } + + bool operator <(const S& rhs) const { return i_ < rhs.i_; } + bool operator >(const S& rhs) const { return i_ > rhs.i_; } + bool operator ==(const S& rhs) const { return i_ == rhs.i_; } + bool operator ==(int i) const { return i_ == i; } + + void set(int i) { i_ = i; } + + int i_; + }; + + +#endif // TEST_STD_VER >= 11 #include "test_iterators.h" #include "counting_predicates.hpp" @@ -38,19 +63,20 @@ test_one(unsigned N, unsigned M) { assert(M <= N); - int* ia = new int[N]; + typedef typename std::iterator_traits::value_type value_type; + value_type* ia = new value_type[N]; for (unsigned i = 0; i < N; ++i) ia[i] = i; std::random_shuffle(ia, ia+N); - std::sort(ia, ia+M, std::greater()); - std::sort(ia+M, ia+N, std::greater()); - binary_counting_predicate, int, int> pred((std::greater())); + std::sort(ia, ia+M, std::greater()); + std::sort(ia+M, ia+N, std::greater()); + binary_counting_predicate, value_type, value_type> pred((std::greater())); std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::ref(pred)); if(N > 0) { assert(ia[0] == N-1); assert(ia[N-1] == 0); - assert(std::is_sorted(ia, ia+N, std::greater())); + assert(std::is_sorted(ia, ia+N, std::greater())); assert(pred.count() <= (N-1)); } delete [] ia; @@ -93,7 +119,11 @@ test >(); test(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef TEST_STD_VER >= 11 + test >(); + test >(); + test(); + { unsigned N = 100; unsigned M = 50; @@ -112,5 +142,5 @@ } delete [] ia; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // TEST_STD_VER >= 11 } 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 =================================================================== --- test/std/atomics/atomics.flag/init03.pass.cpp +++ test/std/atomics/atomics.flag/init03.pass.cpp @@ -13,13 +13,13 @@ // struct atomic_flag -// atomic_flag() = ATOMIC_FLAG_INIT; +// TESTING EXTENSION atomic_flag(bool) #include #include int main() { - std::atomic_flag f = ATOMIC_FLAG_INIT; + 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,10 +32,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -50,11 +51,11 @@ assert(std::atomic_fetch_add(&t, T(2)) == T(1)); assert(t == T(3)); } -} + } +}; template -void -testp() +void testp() { { typedef std::atomic A; @@ -74,38 +75,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 + TestEachIntegralType()(); 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,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 @@ std::memory_order_seq_cst) == T(1)); assert(t == T(3)); } -} + } +}; template void @@ -78,38 +80,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 + TestEachIntegralType()(); 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,10 +32,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -50,11 +51,11 @@ assert(std::atomic_fetch_sub(&t, T(2)) == T(3)); assert(t == T(1)); } -} + } +}; template -void -testp() +void testp() { { typedef std::atomic A; @@ -74,38 +75,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 + TestEachIntegralType()(); 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,10 +33,11 @@ #include #include +#include "atomic_helpers.h" + template -void -test() -{ +struct TestFn { + void operator()() const { { typedef std::atomic A; A t; @@ -53,11 +54,11 @@ std::memory_order_seq_cst) == T(3)); assert(t == T(1)); } -} + } +}; template -void -testp() +void testp() { { typedef std::atomic A; @@ -79,38 +80,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 + TestEachIntegralType()(); 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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,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 @@ 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()(); } 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; @@ -34,27 +36,29 @@ }; 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); - } - { - constexpr Atomic a{t}; - assert(a == t); - } - { - constexpr Atomic a = ATOMIC_VAR_INIT(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); + } } -} +}; int main() { - test(); - test(); + TestFunc()(); + TestEachIntegralType()(); } Index: test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp =================================================================== --- test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp +++ test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp @@ -10,13 +10,6 @@ // UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 -// NOTE: std::terminate is called so the destructors are not invoked and the -// memory is not freed. This will cause ASAN to fail. -// XFAIL: asan - -// NOTE: TSAN will report this test as leaking a thread. -// XFAIL: tsan - // // class thread 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