convert_move.pass.cpp 2.8 KB

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