test_lazy_sfinae.pass.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // <tuple>
  10. // template <class... Types> class tuple;
  11. // UNSUPPORTED: c++98, c++03
  12. #include <tuple>
  13. #include <utility>
  14. #include <cassert>
  15. template <class ConstructFrom>
  16. struct ConstructibleFromT {
  17. ConstructibleFromT() = default;
  18. ConstructibleFromT(ConstructFrom v) : value(v) {}
  19. ConstructFrom value;
  20. };
  21. template <class AssertOn>
  22. struct CtorAssertsT {
  23. bool defaulted;
  24. CtorAssertsT() : defaulted(true) {}
  25. template <class T>
  26. constexpr CtorAssertsT(T) : defaulted(false) {
  27. static_assert(!std::is_same<T, AssertOn>::value, "");
  28. }
  29. };
  30. template <class AllowT, class AssertT>
  31. struct AllowAssertT {
  32. AllowAssertT() = default;
  33. AllowAssertT(AllowT) {}
  34. template <class U>
  35. constexpr AllowAssertT(U) {
  36. static_assert(!std::is_same<U, AssertT>::value, "");
  37. }
  38. };
  39. // Construct a tuple<T1, T2> from pair<int, int> where T1 and T2
  40. // are not constructible from ints but T1 is constructible from std::pair.
  41. // This considers the following constructors:
  42. // (1) tuple(TupleLike) -> checks is_constructible<Tn, int>
  43. // (2) tuple(UTypes...) -> checks is_constructible<T1, pair<int, int>>
  44. // and is_default_constructible<T2>
  45. // The point of this test is to ensure that the consideration of (1)
  46. // short circuits before evaluating is_constructible<T2, int>, which
  47. // will cause a static assertion.
  48. void test_tuple_like_lazy_sfinae() {
  49. #if defined(_LIBCPP_VERSION)
  50. // This test requires libc++'s reduced arity initialization.
  51. using T1 = ConstructibleFromT<std::pair<int, int>>;
  52. using T2 = CtorAssertsT<int>;
  53. std::pair<int, int> p(42, 100);
  54. std::tuple<T1, T2> t(p);
  55. assert(std::get<0>(t).value == p);
  56. assert(std::get<1>(t).defaulted);
  57. #endif
  58. }
  59. struct NonConstCopyable {
  60. NonConstCopyable() = default;
  61. explicit NonConstCopyable(int v) : value(v) {}
  62. NonConstCopyable(NonConstCopyable&) = default;
  63. NonConstCopyable(NonConstCopyable const&) = delete;
  64. int value;
  65. };
  66. template <class T>
  67. struct BlowsUpOnConstCopy {
  68. BlowsUpOnConstCopy() = default;
  69. constexpr BlowsUpOnConstCopy(BlowsUpOnConstCopy const&) {
  70. static_assert(!std::is_same<T, T>::value, "");
  71. }
  72. BlowsUpOnConstCopy(BlowsUpOnConstCopy&) = default;
  73. };
  74. // Test the following constructors:
  75. // (1) tuple(Types const&...)
  76. // (2) tuple(UTypes&&...)
  77. // Test that (1) short circuits before evaluating the copy constructor of the
  78. // second argument. Constructor (2) should be selected.
  79. void test_const_Types_lazy_sfinae()
  80. {
  81. NonConstCopyable v(42);
  82. BlowsUpOnConstCopy<int> b;
  83. std::tuple<NonConstCopyable, BlowsUpOnConstCopy<int>> t(v, b);
  84. assert(std::get<0>(t).value == 42);
  85. }
  86. int main() {
  87. test_tuple_like_lazy_sfinae();
  88. test_const_Types_lazy_sfinae();
  89. }