get_index.pass.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // UNSUPPORTED: c++98, c++03, c++11, c++14
  10. // XFAIL: dylib-has-no-bad_variant_access
  11. // <variant>
  12. // template <size_t I, class... Types>
  13. // constexpr variant_alternative_t<I, variant<Types...>>&
  14. // get(variant<Types...>& v);
  15. // template <size_t I, class... Types>
  16. // constexpr variant_alternative_t<I, variant<Types...>>&&
  17. // get(variant<Types...>&& v);
  18. // template <size_t I, class... Types>
  19. // constexpr variant_alternative_t<I, variant<Types...>> const& get(const
  20. // variant<Types...>& v);
  21. // template <size_t I, class... Types>
  22. // constexpr variant_alternative_t<I, variant<Types...>> const&& get(const
  23. // variant<Types...>&& v);
  24. #include "test_macros.h"
  25. #include "variant_test_helpers.hpp"
  26. #include <cassert>
  27. #include <type_traits>
  28. #include <utility>
  29. #include <variant>
  30. void test_const_lvalue_get() {
  31. {
  32. using V = std::variant<int, const long>;
  33. constexpr V v(42);
  34. #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
  35. ASSERT_NOEXCEPT(std::get<0>(v));
  36. #endif
  37. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
  38. static_assert(std::get<0>(v) == 42, "");
  39. }
  40. {
  41. using V = std::variant<int, const long>;
  42. const V v(42);
  43. ASSERT_NOT_NOEXCEPT(std::get<0>(v));
  44. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
  45. assert(std::get<0>(v) == 42);
  46. }
  47. {
  48. using V = std::variant<int, const long>;
  49. constexpr V v(42l);
  50. #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
  51. ASSERT_NOEXCEPT(std::get<1>(v));
  52. #endif
  53. ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
  54. static_assert(std::get<1>(v) == 42, "");
  55. }
  56. {
  57. using V = std::variant<int, const long>;
  58. const V v(42l);
  59. ASSERT_NOT_NOEXCEPT(std::get<1>(v));
  60. ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
  61. assert(std::get<1>(v) == 42);
  62. }
  63. // FIXME: Remove these once reference support is reinstated
  64. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  65. {
  66. using V = std::variant<int &>;
  67. int x = 42;
  68. const V v(x);
  69. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
  70. assert(&std::get<0>(v) == &x);
  71. }
  72. {
  73. using V = std::variant<int &&>;
  74. int x = 42;
  75. const V v(std::move(x));
  76. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
  77. assert(&std::get<0>(v) == &x);
  78. }
  79. {
  80. using V = std::variant<const int &&>;
  81. int x = 42;
  82. const V v(std::move(x));
  83. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
  84. assert(&std::get<0>(v) == &x);
  85. }
  86. #endif
  87. }
  88. void test_lvalue_get() {
  89. {
  90. using V = std::variant<int, const long>;
  91. V v(42);
  92. ASSERT_NOT_NOEXCEPT(std::get<0>(v));
  93. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
  94. assert(std::get<0>(v) == 42);
  95. }
  96. {
  97. using V = std::variant<int, const long>;
  98. V v(42l);
  99. ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
  100. assert(std::get<1>(v) == 42);
  101. }
  102. // FIXME: Remove these once reference support is reinstated
  103. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  104. {
  105. using V = std::variant<int &>;
  106. int x = 42;
  107. V v(x);
  108. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
  109. assert(&std::get<0>(v) == &x);
  110. }
  111. {
  112. using V = std::variant<const int &>;
  113. int x = 42;
  114. V v(x);
  115. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
  116. assert(&std::get<0>(v) == &x);
  117. }
  118. {
  119. using V = std::variant<int &&>;
  120. int x = 42;
  121. V v(std::move(x));
  122. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
  123. assert(&std::get<0>(v) == &x);
  124. }
  125. {
  126. using V = std::variant<const int &&>;
  127. int x = 42;
  128. V v(std::move(x));
  129. ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
  130. assert(&std::get<0>(v) == &x);
  131. }
  132. #endif
  133. }
  134. void test_rvalue_get() {
  135. {
  136. using V = std::variant<int, const long>;
  137. V v(42);
  138. ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
  139. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
  140. assert(std::get<0>(std::move(v)) == 42);
  141. }
  142. {
  143. using V = std::variant<int, const long>;
  144. V v(42l);
  145. ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
  146. assert(std::get<1>(std::move(v)) == 42);
  147. }
  148. // FIXME: Remove these once reference support is reinstated
  149. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  150. {
  151. using V = std::variant<int &>;
  152. int x = 42;
  153. V v(x);
  154. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
  155. assert(&std::get<0>(std::move(v)) == &x);
  156. }
  157. {
  158. using V = std::variant<const int &>;
  159. int x = 42;
  160. V v(x);
  161. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
  162. assert(&std::get<0>(std::move(v)) == &x);
  163. }
  164. {
  165. using V = std::variant<int &&>;
  166. int x = 42;
  167. V v(std::move(x));
  168. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
  169. int &&xref = std::get<0>(std::move(v));
  170. assert(&xref == &x);
  171. }
  172. {
  173. using V = std::variant<const int &&>;
  174. int x = 42;
  175. V v(std::move(x));
  176. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
  177. const int &&xref = std::get<0>(std::move(v));
  178. assert(&xref == &x);
  179. }
  180. #endif
  181. }
  182. void test_const_rvalue_get() {
  183. {
  184. using V = std::variant<int, const long>;
  185. const V v(42);
  186. ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
  187. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
  188. assert(std::get<0>(std::move(v)) == 42);
  189. }
  190. {
  191. using V = std::variant<int, const long>;
  192. const V v(42l);
  193. ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
  194. assert(std::get<1>(std::move(v)) == 42);
  195. }
  196. // FIXME: Remove these once reference support is reinstated
  197. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  198. {
  199. using V = std::variant<int &>;
  200. int x = 42;
  201. const V v(x);
  202. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
  203. assert(&std::get<0>(std::move(v)) == &x);
  204. }
  205. {
  206. using V = std::variant<const int &>;
  207. int x = 42;
  208. const V v(x);
  209. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
  210. assert(&std::get<0>(std::move(v)) == &x);
  211. }
  212. {
  213. using V = std::variant<int &&>;
  214. int x = 42;
  215. const V v(std::move(x));
  216. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
  217. int &&xref = std::get<0>(std::move(v));
  218. assert(&xref == &x);
  219. }
  220. {
  221. using V = std::variant<const int &&>;
  222. int x = 42;
  223. const V v(std::move(x));
  224. ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
  225. const int &&xref = std::get<0>(std::move(v));
  226. assert(&xref == &x);
  227. }
  228. #endif
  229. }
  230. template <std::size_t I> using Idx = std::integral_constant<size_t, I>;
  231. void test_throws_for_all_value_categories() {
  232. #ifndef TEST_HAS_NO_EXCEPTIONS
  233. using V = std::variant<int, long>;
  234. V v0(42);
  235. const V &cv0 = v0;
  236. assert(v0.index() == 0);
  237. V v1(42l);
  238. const V &cv1 = v1;
  239. assert(v1.index() == 1);
  240. std::integral_constant<size_t, 0> zero;
  241. std::integral_constant<size_t, 1> one;
  242. auto test = [](auto idx, auto &&v) {
  243. using Idx = decltype(idx);
  244. try {
  245. TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v));
  246. } catch (const std::bad_variant_access &) {
  247. return true;
  248. } catch (...) { /* ... */
  249. }
  250. return false;
  251. };
  252. { // lvalue test cases
  253. assert(test(one, v0));
  254. assert(test(zero, v1));
  255. }
  256. { // const lvalue test cases
  257. assert(test(one, cv0));
  258. assert(test(zero, cv1));
  259. }
  260. { // rvalue test cases
  261. assert(test(one, std::move(v0)));
  262. assert(test(zero, std::move(v1)));
  263. }
  264. { // const rvalue test cases
  265. assert(test(one, std::move(cv0)));
  266. assert(test(zero, std::move(cv1)));
  267. }
  268. #endif
  269. }
  270. int main(int, char**) {
  271. test_const_lvalue_get();
  272. test_lvalue_get();
  273. test_rvalue_get();
  274. test_const_rvalue_get();
  275. test_throws_for_all_value_categories();
  276. return 0;
  277. }