1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <atomic> 10 11 // Test nested types 12 13 // template <class T> 14 // class atomic 15 // { 16 // public: 17 // typedef T value_type; 18 // }; 19 20 #include <atomic> 21 #include <chrono> 22 #include <cstdint> 23 #include <memory> 24 #include <type_traits> 25 26 #include "test_macros.h" 27 28 #ifndef TEST_HAS_NO_THREADS 29 # include <thread> 30 #endif 31 32 template <class A, bool Integral> 33 struct test_atomic 34 { 35 test_atomic() 36 { 37 A a; (void)a; 38 #if TEST_STD_VER >= 17 39 static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), ""); 40 #endif 41 } 42 }; 43 44 template <class A> 45 struct test_atomic<A, true> 46 { 47 test_atomic() 48 { 49 A a; (void)a; 50 #if TEST_STD_VER >= 17 51 static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), ""); 52 static_assert((std::is_same_v<typename A::value_type, typename A::difference_type>), ""); 53 #endif 54 } 55 }; 56 57 template <class A> 58 struct test_atomic<A*, false> 59 { 60 test_atomic() 61 { 62 A a; (void)a; 63 #if TEST_STD_VER >= 17 64 static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), ""); 65 static_assert((std::is_same_v<typename A::difference_type, std::ptrdiff_t>), ""); 66 #endif 67 } 68 }; 69 70 template <class T> 71 void 72 test() 73 { 74 using A = std::atomic<T>; 75 #if TEST_STD_VER >= 17 76 static_assert((std::is_same_v<typename A::value_type, T>), ""); 77 #endif 78 test_atomic<A, std::is_integral<T>::value && !std::is_same<T, bool>::value>(); 79 } 80 81 struct TriviallyCopyable { 82 int i_; 83 }; 84 85 struct WeirdTriviallyCopyable 86 { 87 char i, j, k; /* the 3 chars of doom */ 88 }; 89 90 struct PaddedTriviallyCopyable 91 { 92 char i; int j; /* probably lock-free? */ 93 }; 94 95 struct LargeTriviallyCopyable 96 { 97 int i, j[127]; /* decidedly not lock-free */ 98 }; 99 100 int main(int, char**) 101 { 102 test<bool> (); 103 test<char> (); 104 test<signed char> (); 105 test<unsigned char> (); 106 test<short> (); 107 test<unsigned short> (); 108 test<int> (); 109 test<unsigned int> (); 110 test<long> (); 111 test<unsigned long> (); 112 test<long long> (); 113 test<unsigned long long> (); 114 #if TEST_STD_VER > 17 && defined(__cpp_char8_t) 115 test<char8_t> (); 116 #endif 117 test<char16_t> (); 118 test<char32_t> (); 119 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 120 test<wchar_t> (); 121 #endif 122 123 test<std::int_least8_t> (); 124 test<std::uint_least8_t> (); 125 test<std::int_least16_t> (); 126 test<std::uint_least16_t> (); 127 test<std::int_least32_t> (); 128 test<std::uint_least32_t> (); 129 test<std::int_least64_t> (); 130 test<std::uint_least64_t> (); 131 132 test<std::int_fast8_t> (); 133 test<std::uint_fast8_t> (); 134 test<std::int_fast16_t> (); 135 test<std::uint_fast16_t> (); 136 test<std::int_fast32_t> (); 137 test<std::uint_fast32_t> (); 138 test<std::int_fast64_t> (); 139 test<std::uint_fast64_t> (); 140 141 test< std::int8_t> (); 142 test<std::uint8_t> (); 143 test< std::int16_t> (); 144 test<std::uint16_t> (); 145 test< std::int32_t> (); 146 test<std::uint32_t> (); 147 test< std::int64_t> (); 148 test<std::uint64_t> (); 149 150 test<std::intptr_t> (); 151 test<std::uintptr_t> (); 152 test<std::size_t> (); 153 test<std::ptrdiff_t> (); 154 test<std::intmax_t> (); 155 test<std::uintmax_t> (); 156 157 test<std::uintmax_t> (); 158 test<std::uintmax_t> (); 159 160 test<TriviallyCopyable>(); 161 test<PaddedTriviallyCopyable>(); 162 #ifndef __APPLE__ // Apple doesn't ship libatomic 163 /* 164 These aren't going to be lock-free, 165 so some libatomic.a is necessary. 166 */ 167 test<WeirdTriviallyCopyable>(); 168 test<LargeTriviallyCopyable>(); 169 #endif 170 171 #ifndef TEST_HAS_NO_THREADS 172 test<std::thread::id>(); 173 #endif 174 test<std::chrono::nanoseconds>(); 175 test<float>(); 176 177 #if TEST_STD_VER >= 20 178 test<std::atomic_signed_lock_free::value_type>(); 179 static_assert(std::is_signed_v<std::atomic_signed_lock_free::value_type>); 180 static_assert(std::is_integral_v<std::atomic_signed_lock_free::value_type>); 181 182 test<std::atomic_unsigned_lock_free::value_type>(); 183 static_assert(std::is_unsigned_v<std::atomic_unsigned_lock_free::value_type>); 184 static_assert(std::is_integral_v<std::atomic_unsigned_lock_free::value_type>); 185 /* 186 test<std::shared_ptr<int>>(); 187 */ 188 #endif 189 190 return 0; 191 } 192