extend_unittest.cc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/containers/extend.h"
  5. #include <initializer_list>
  6. #include <type_traits>
  7. #include <utility>
  8. #include <vector>
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace base {
  11. namespace {
  12. struct NonCopyable {
  13. char c_;
  14. explicit NonCopyable(char c) : c_(c) {}
  15. NonCopyable(NonCopyable&&) = default;
  16. NonCopyable& operator=(NonCopyable&& other) = default;
  17. NonCopyable(const NonCopyable&) = delete;
  18. NonCopyable& operator=(const NonCopyable&) = delete;
  19. };
  20. bool operator==(const NonCopyable& a, const NonCopyable& b) {
  21. return a.c_ == b.c_;
  22. }
  23. static_assert(std::is_move_constructible<NonCopyable>::value, "");
  24. static_assert(!std::is_copy_constructible<NonCopyable>::value, "");
  25. struct CopyableMovable {
  26. bool copied_;
  27. char c_;
  28. explicit CopyableMovable(char c) : copied_(false), c_(c) {}
  29. CopyableMovable(const CopyableMovable& other) : copied_(true), c_(other.c_) {}
  30. CopyableMovable& operator=(const CopyableMovable&) = default;
  31. CopyableMovable(CopyableMovable&&) = default;
  32. CopyableMovable& operator=(CopyableMovable&& other) = default;
  33. };
  34. bool operator==(const CopyableMovable& a, const CopyableMovable& b) {
  35. return a.c_ == b.c_;
  36. }
  37. } // namespace
  38. TEST(ExtendTest, ExtendWithMove) {
  39. std::vector<NonCopyable> dst;
  40. for (char c : {'a', 'b', 'c', 'd'})
  41. dst.emplace_back(c);
  42. std::vector<NonCopyable> src;
  43. for (char c : {'e', 'f', 'g'})
  44. src.emplace_back(c);
  45. std::vector<NonCopyable> expected;
  46. for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'})
  47. expected.emplace_back(c);
  48. Extend(dst, std::move(src));
  49. EXPECT_EQ(dst, expected);
  50. EXPECT_TRUE(src.empty());
  51. }
  52. TEST(ExtendTest, ExtendCopyableWithMove) {
  53. std::vector<CopyableMovable> dst;
  54. for (char c : {'a', 'b', 'c', 'd'})
  55. dst.emplace_back(c);
  56. std::vector<CopyableMovable> src;
  57. for (char c : {'e', 'f', 'g'})
  58. src.emplace_back(c);
  59. std::vector<CopyableMovable> expected;
  60. for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'})
  61. expected.emplace_back(c);
  62. Extend(dst, std::move(src));
  63. EXPECT_EQ(dst, expected);
  64. EXPECT_TRUE(src.empty());
  65. }
  66. TEST(ExtendTest, ExtendWithCopy) {
  67. std::vector<CopyableMovable> dst;
  68. for (char c : {'a', 'b', 'c', 'd'})
  69. dst.emplace_back(c);
  70. std::vector<CopyableMovable> src;
  71. for (char c : {'e', 'f', 'g'})
  72. src.emplace_back(c);
  73. std::vector<CopyableMovable> expected;
  74. for (char c : {'a', 'b', 'c', 'd', 'e', 'f', 'g'})
  75. expected.emplace_back(c);
  76. EXPECT_FALSE(dst[0].copied_);
  77. Extend(dst, src);
  78. EXPECT_EQ(dst, expected);
  79. EXPECT_FALSE(dst[0].copied_);
  80. EXPECT_TRUE(dst[dst.size() - 1].copied_);
  81. }
  82. } // namespace base