indirect_value_test.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "common/indirect_value.h"
  5. #include <gtest/gtest.h>
  6. #include <string>
  7. namespace Carbon {
  8. namespace {
  9. TEST(IndirectValueTest, ConstAccess) {
  10. const IndirectValue<int> v = 42;
  11. EXPECT_EQ(*v, 42);
  12. EXPECT_EQ(v.GetPointer(), &*v);
  13. }
  14. TEST(IndirectValueTest, MutableAccess) {
  15. IndirectValue<int> v = 42;
  16. EXPECT_EQ(*v, 42);
  17. EXPECT_EQ(v.GetPointer(), &*v);
  18. *v = 0;
  19. EXPECT_EQ(*v, 0);
  20. }
  21. struct NonMovable {
  22. explicit NonMovable(int i) : i(i) {}
  23. NonMovable(NonMovable&&) = delete;
  24. auto operator=(NonMovable&&) -> NonMovable& = delete;
  25. int i;
  26. };
  27. TEST(IndirectValueTest, Create) {
  28. IndirectValue<NonMovable> v =
  29. MakeIndirectValue([] { return NonMovable(42); });
  30. EXPECT_EQ(v->i, 42);
  31. }
  32. auto GetIntReference() -> const int& {
  33. static int i = 42;
  34. return i;
  35. }
  36. TEST(IndirectValueTest, CreateWithDecay) {
  37. auto v = MakeIndirectValue(GetIntReference);
  38. EXPECT_TRUE((std::is_same_v<decltype(v), IndirectValue<int>>));
  39. EXPECT_EQ(*v, 42);
  40. }
  41. // Test double which presents a value-like interface, but tracks which special
  42. // member function (if any) caused it to reach its present value.
  43. struct TestValue {
  44. TestValue() : state("default constructed") {}
  45. TestValue(const TestValue& /*rhs*/) : state("copy constructed") {}
  46. TestValue(TestValue&& other) noexcept : state("move constructed") {
  47. other.state = "move constructed from";
  48. }
  49. auto operator=(const TestValue& /*unused*/) noexcept -> TestValue& {
  50. state = "copy assigned";
  51. return *this;
  52. }
  53. auto operator=(TestValue&& other) noexcept -> TestValue& {
  54. state = "move assigned";
  55. other.state = "move assigned from";
  56. return *this;
  57. }
  58. std::string state;
  59. };
  60. TEST(IndirectValueTest, ConstArrow) {
  61. const IndirectValue<TestValue> v;
  62. EXPECT_EQ(v->state, "default constructed");
  63. }
  64. TEST(IndirectValueTest, MutableArrow) {
  65. IndirectValue<TestValue> v;
  66. EXPECT_EQ(v->state, "default constructed");
  67. v->state = "explicitly set";
  68. EXPECT_EQ(v->state, "explicitly set");
  69. }
  70. TEST(IndirectValueTest, CopyConstruct) {
  71. IndirectValue<TestValue> v1;
  72. auto v2 = v1;
  73. EXPECT_EQ(v1->state, "default constructed");
  74. EXPECT_EQ(v2->state, "copy constructed");
  75. }
  76. TEST(IndirectValueTest, CopyAssign) {
  77. IndirectValue<TestValue> v1;
  78. IndirectValue<TestValue> v2;
  79. v2 = v1;
  80. EXPECT_EQ(v1->state, "default constructed");
  81. EXPECT_EQ(v2->state, "copy assigned");
  82. }
  83. TEST(IndirectValueTest, MoveConstruct) {
  84. IndirectValue<TestValue> v1;
  85. auto v2 = std::move(v1);
  86. // While not entirely safe, the `v1->state` access tests move behavior.
  87. // NOLINTNEXTLINE(bugprone-use-after-move)
  88. EXPECT_EQ(v1->state, "move constructed from");
  89. EXPECT_EQ(v2->state, "move constructed");
  90. }
  91. TEST(IndirectValueTest, MoveAssign) {
  92. IndirectValue<TestValue> v1;
  93. IndirectValue<TestValue> v2;
  94. v2 = std::move(v1);
  95. // While not entirely safe, the `v1->state` access tests move behavior.
  96. // NOLINTNEXTLINE(bugprone-use-after-move)
  97. EXPECT_EQ(v1->state, "move assigned from");
  98. EXPECT_EQ(v2->state, "move assigned");
  99. }
  100. TEST(IndirectValueTest, IncompleteType) {
  101. struct S {
  102. std::optional<IndirectValue<S>> v;
  103. };
  104. S s = {.v = S{}};
  105. }
  106. } // namespace
  107. } // namespace Carbon