T.pass.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 <class ...Types> class variant;
  13. // template <class T> constexpr variant(T&&) noexcept(see below);
  14. #include <cassert>
  15. #include <string>
  16. #include <type_traits>
  17. #include <variant>
  18. #include "test_convertible.hpp"
  19. #include "test_macros.h"
  20. #include "variant_test_helpers.hpp"
  21. struct Dummy {
  22. Dummy() = default;
  23. };
  24. struct ThrowsT {
  25. ThrowsT(int) noexcept(false) {}
  26. };
  27. struct NoThrowT {
  28. NoThrowT(int) noexcept(true) {}
  29. };
  30. struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
  31. struct NoConstructible { NoConstructible() = delete; };
  32. void test_T_ctor_noexcept() {
  33. {
  34. using V = std::variant<Dummy, NoThrowT>;
  35. static_assert(std::is_nothrow_constructible<V, int>::value, "");
  36. }
  37. {
  38. using V = std::variant<Dummy, ThrowsT>;
  39. static_assert(!std::is_nothrow_constructible<V, int>::value, "");
  40. }
  41. }
  42. void test_T_ctor_sfinae() {
  43. {
  44. using V = std::variant<long, unsigned>;
  45. static_assert(!std::is_constructible<V, int>::value, "ambiguous");
  46. }
  47. {
  48. using V = std::variant<std::string, std::string>;
  49. static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
  50. }
  51. {
  52. using V = std::variant<std::string, void *>;
  53. static_assert(!std::is_constructible<V, int>::value,
  54. "no matching constructor");
  55. }
  56. {
  57. using V = std::variant<AnyConstructible, NoConstructible>;
  58. static_assert(
  59. !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
  60. "no matching constructor");
  61. static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
  62. "no matching constructor");
  63. }
  64. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  65. {
  66. using V = std::variant<int, int &&>;
  67. static_assert(!std::is_constructible<V, int>::value, "ambiguous");
  68. }
  69. {
  70. using V = std::variant<int, const int &>;
  71. static_assert(!std::is_constructible<V, int>::value, "ambiguous");
  72. }
  73. #endif
  74. }
  75. void test_T_ctor_basic() {
  76. {
  77. constexpr std::variant<int> v(42);
  78. static_assert(v.index() == 0, "");
  79. static_assert(std::get<0>(v) == 42, "");
  80. }
  81. {
  82. constexpr std::variant<int, long> v(42l);
  83. static_assert(v.index() == 1, "");
  84. static_assert(std::get<1>(v) == 42, "");
  85. }
  86. #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
  87. {
  88. using V = std::variant<const int &, int &&, long>;
  89. static_assert(std::is_convertible<int &, V>::value, "must be implicit");
  90. int x = 42;
  91. V v(x);
  92. assert(v.index() == 0);
  93. assert(&std::get<0>(v) == &x);
  94. }
  95. {
  96. using V = std::variant<const int &, int &&, long>;
  97. static_assert(std::is_convertible<int, V>::value, "must be implicit");
  98. int x = 42;
  99. V v(std::move(x));
  100. assert(v.index() == 1);
  101. assert(&std::get<1>(v) == &x);
  102. }
  103. #endif
  104. }
  105. int main(int, char**) {
  106. test_T_ctor_basic();
  107. test_T_ctor_noexcept();
  108. test_T_ctor_sfinae();
  109. return 0;
  110. }