derived_from_tuple_like.pass.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. // template <class... UTypes>
  12. // tuple& operator=(const tuple<UTypes...>& u);
  13. // UNSUPPORTED: c++98, c++03
  14. #include <tuple>
  15. #include <array>
  16. #include <string>
  17. #include <utility>
  18. #include <cassert>
  19. #include "propagate_value_category.hpp"
  20. struct TracksIntQuals {
  21. TracksIntQuals() : value(-1), value_category(VC_None), assigned(false) {}
  22. template <class Tp,
  23. class = typename std::enable_if<!std::is_same<
  24. typename std::decay<Tp>::type, TracksIntQuals>::value>::type>
  25. TracksIntQuals(Tp &&x)
  26. : value(x), value_category(getValueCategory<Tp &&>()), assigned(false) {
  27. static_assert(std::is_same<UnCVRef<Tp>, int>::value, "");
  28. }
  29. template <class Tp,
  30. class = typename std::enable_if<!std::is_same<
  31. typename std::decay<Tp>::type, TracksIntQuals>::value>::type>
  32. TracksIntQuals &operator=(Tp &&x) {
  33. static_assert(std::is_same<UnCVRef<Tp>, int>::value, "");
  34. value = x;
  35. value_category = getValueCategory<Tp &&>();
  36. assigned = true;
  37. return *this;
  38. }
  39. void reset() {
  40. value = -1;
  41. value_category = VC_None;
  42. assigned = false;
  43. }
  44. bool checkConstruct(int expect, ValueCategory expect_vc) const {
  45. return value != 1 && value == expect && value_category == expect_vc &&
  46. assigned == false;
  47. }
  48. bool checkAssign(int expect, ValueCategory expect_vc) const {
  49. return value != 1 && value == expect && value_category == expect_vc &&
  50. assigned == true;
  51. }
  52. int value;
  53. ValueCategory value_category;
  54. bool assigned;
  55. };
  56. template <class Tup>
  57. struct DerivedFromTup : Tup {
  58. using Tup::Tup;
  59. };
  60. template <ValueCategory VC>
  61. void do_derived_assign_test() {
  62. using Tup1 = std::tuple<long, TracksIntQuals>;
  63. Tup1 t;
  64. auto reset = [&]() {
  65. std::get<0>(t) = -1;
  66. std::get<1>(t).reset();
  67. };
  68. {
  69. DerivedFromTup<std::tuple<int, int>> d(42, 101);
  70. t = ValueCategoryCast<VC>(d);
  71. assert(std::get<0>(t) == 42);
  72. assert(std::get<1>(t).checkAssign(101, VC));
  73. }
  74. reset();
  75. {
  76. DerivedFromTup<std::pair<int, int>> d(42, 101);
  77. t = ValueCategoryCast<VC>(d);
  78. assert(std::get<0>(t) == 42);
  79. assert(std::get<1>(t).checkAssign(101, VC));
  80. }
  81. reset();
  82. {
  83. DerivedFromTup<std::array<int, 2>> d;
  84. d[0] = 42;
  85. d[1] = 101;
  86. t = ValueCategoryCast<VC>(d);
  87. assert(std::get<0>(t) == 42);
  88. assert(std::get<1>(t).checkAssign(101, VC));
  89. }
  90. }
  91. int main() {
  92. do_derived_assign_test<VC_LVal | VC_Const>();
  93. do_derived_assign_test<VC_RVal>();
  94. #if defined(_LIBCPP_VERSION)
  95. // Non-const copy assign and const move assign are libc++ extensions.
  96. do_derived_assign_test<VC_LVal>();
  97. do_derived_assign_test<VC_RVal | VC_Const>();
  98. #endif
  99. }