convert_move.pass.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. // <tuple>
  9. // template <class... Types> class tuple;
  10. // template <class... UTypes>
  11. // tuple& operator=(tuple<UTypes...>&& u);
  12. // UNSUPPORTED: c++98, c++03
  13. #include <tuple>
  14. #include <string>
  15. #include <memory>
  16. #include <utility>
  17. #include <cassert>
  18. struct B
  19. {
  20. int id_;
  21. explicit B(int i= 0) : id_(i) {}
  22. virtual ~B() {}
  23. };
  24. struct D
  25. : B
  26. {
  27. explicit D(int i) : B(i) {}
  28. };
  29. struct E {
  30. E() = default;
  31. E& operator=(int) {
  32. return *this;
  33. }
  34. };
  35. int main(int, char**)
  36. {
  37. {
  38. typedef std::tuple<long> T0;
  39. typedef std::tuple<long long> T1;
  40. T0 t0(2);
  41. T1 t1;
  42. t1 = std::move(t0);
  43. assert(std::get<0>(t1) == 2);
  44. }
  45. {
  46. typedef std::tuple<long, char> T0;
  47. typedef std::tuple<long long, int> T1;
  48. T0 t0(2, 'a');
  49. T1 t1;
  50. t1 = std::move(t0);
  51. assert(std::get<0>(t1) == 2);
  52. assert(std::get<1>(t1) == int('a'));
  53. }
  54. {
  55. typedef std::tuple<long, char, D> T0;
  56. typedef std::tuple<long long, int, B> T1;
  57. T0 t0(2, 'a', D(3));
  58. T1 t1;
  59. t1 = std::move(t0);
  60. assert(std::get<0>(t1) == 2);
  61. assert(std::get<1>(t1) == int('a'));
  62. assert(std::get<2>(t1).id_ == 3);
  63. }
  64. {
  65. D d(3);
  66. D d2(2);
  67. typedef std::tuple<long, char, D&> T0;
  68. typedef std::tuple<long long, int, B&> T1;
  69. T0 t0(2, 'a', d2);
  70. T1 t1(1, 'b', d);
  71. t1 = std::move(t0);
  72. assert(std::get<0>(t1) == 2);
  73. assert(std::get<1>(t1) == int('a'));
  74. assert(std::get<2>(t1).id_ == 2);
  75. }
  76. {
  77. typedef std::tuple<long, char, std::unique_ptr<D>> T0;
  78. typedef std::tuple<long long, int, std::unique_ptr<B>> T1;
  79. T0 t0(2, 'a', std::unique_ptr<D>(new D(3)));
  80. T1 t1;
  81. t1 = std::move(t0);
  82. assert(std::get<0>(t1) == 2);
  83. assert(std::get<1>(t1) == int('a'));
  84. assert(std::get<2>(t1)->id_ == 3);
  85. }
  86. {
  87. // Test that tuple evaluates correctly applies an lvalue reference
  88. // before evaluating is_assignable (ie 'is_assignable<int&, int&&>')
  89. // instead of evaluating 'is_assignable<int&&, int&&>' which is false.
  90. int x = 42;
  91. int y = 43;
  92. std::tuple<int&&, E> t(std::move(x), E{});
  93. std::tuple<int&&, int> t2(std::move(y), 44);
  94. t = std::move(t2);
  95. assert(std::get<0>(t) == 43);
  96. assert(&std::get<0>(t) == &x);
  97. }
  98. return 0;
  99. }