diff options
| author | William A. Kennington III <wak@google.com> | 2018-07-17 14:40:14 -0700 |
|---|---|---|
| committer | William A. Kennington III <wak@google.com> | 2018-07-17 14:40:14 -0700 |
| commit | 1744c165f01a5a3861312abe9267c3156c9db71e (patch) | |
| tree | b0c5b0d7ad143625a7c286a41d1f4bf6eb749243 | |
| parent | e3de31b984401336a8ec02aba83a0fece7d79a60 (diff) | |
| download | sdeventplus-1744c165f01a5a3861312abe9267c3156c9db71e.tar.gz sdeventplus-1744c165f01a5a3861312abe9267c3156c9db71e.zip | |
sdref: Moves should actually invalidate the reference
This also makes it possible to use in boolean expressions to check
validity.
| -rw-r--r-- | src/sdeventplus/internal/sdref.cpp | 15 | ||||
| -rw-r--r-- | src/sdeventplus/internal/sdref.hpp | 3 | ||||
| -rw-r--r-- | test/internal/sdref.cpp | 41 |
3 files changed, 58 insertions, 1 deletions
diff --git a/src/sdeventplus/internal/sdref.cpp b/src/sdeventplus/internal/sdref.cpp index 47faa87..add6b90 100644 --- a/src/sdeventplus/internal/sdref.cpp +++ b/src/sdeventplus/internal/sdref.cpp @@ -49,6 +49,14 @@ SdRef<T>& SdRef<T>::operator=(const SdRef& other) } template <typename T> +SdRef<T>::SdRef(SdRef&& other) : + sdevent(std::move(other.sdevent)), take_ref(std::move(other.take_ref)), + release_ref(std::move(other.release_ref)), ref(std::move(other.ref)) +{ + other.ref = nullptr; +} + +template <typename T> SdRef<T>& SdRef<T>::operator=(SdRef&& other) { if (this != &other) @@ -63,6 +71,7 @@ SdRef<T>& SdRef<T>::operator=(SdRef&& other) take_ref = std::move(other.take_ref); release_ref = std::move(other.release_ref); ref = std::move(other.ref); + other.ref = nullptr; } return *this; } @@ -76,6 +85,12 @@ SdRef<T>::~SdRef() } template <typename T> +SdRef<T>::operator bool() const +{ + return ref != nullptr; +} + +template <typename T> T* SdRef<T>::get() const { return ref; diff --git a/src/sdeventplus/internal/sdref.hpp b/src/sdeventplus/internal/sdref.hpp index c0c77fc..12e395f 100644 --- a/src/sdeventplus/internal/sdref.hpp +++ b/src/sdeventplus/internal/sdref.hpp @@ -23,9 +23,10 @@ class SdRef SdRef(const SdRef& other); SdRef& operator=(const SdRef& other); - SdRef(SdRef&& other) = default; + SdRef(SdRef&& other); SdRef& operator=(SdRef&& other); + explicit operator bool() const; T* get() const; private: diff --git a/test/internal/sdref.cpp b/test/internal/sdref.cpp index 190d388..3b261d5 100644 --- a/test/internal/sdref.cpp +++ b/test/internal/sdref.cpp @@ -28,6 +28,7 @@ TEST_F(SdRefTest, ConstructRef) .WillOnce(testing::Return(expected_event)); SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -38,6 +39,7 @@ TEST_F(SdRefTest, ConstructNoRef) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -48,11 +50,15 @@ TEST_F(SdRefTest, CopyConstruct) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); EXPECT_CALL(mock, sd_event_ref(expected_event)) .WillOnce(testing::Return(expected_event)); SdRef<sd_event> event2(event); + EXPECT_TRUE(event); + EXPECT_EQ(expected_event, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -64,9 +70,13 @@ TEST_F(SdRefTest, MoveConstruct) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); SdRef<sd_event> event2(std::move(event)); + EXPECT_FALSE(event); + EXPECT_EQ(nullptr, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -77,9 +87,11 @@ TEST_F(SdRefTest, CopyAssignOverValid) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock2); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event2, event2.get()); EXPECT_CALL(mock2, sd_event_unref(expected_event2)) @@ -87,6 +99,9 @@ TEST_F(SdRefTest, CopyAssignOverValid) EXPECT_CALL(mock, sd_event_ref(expected_event)) .WillOnce(testing::Return(expected_event)); event2 = event; + EXPECT_TRUE(event); + EXPECT_EQ(expected_event, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -98,12 +113,17 @@ TEST_F(SdRefTest, CopyAssignOverMoved) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock2); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event2, event2.get()); { SdRef<sd_event> event_mover(std::move(event2)); + EXPECT_FALSE(event2); + EXPECT_EQ(nullptr, event2.get()); + EXPECT_TRUE(event_mover); EXPECT_EQ(expected_event2, event_mover.get()); EXPECT_CALL(mock2, sd_event_unref(expected_event2)) @@ -113,6 +133,9 @@ TEST_F(SdRefTest, CopyAssignOverMoved) EXPECT_CALL(mock, sd_event_ref(expected_event)) .WillOnce(testing::Return(expected_event)); event2 = event; + EXPECT_TRUE(event); + EXPECT_EQ(expected_event, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -124,9 +147,12 @@ TEST_F(SdRefTest, CopySelf) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); event = event; + EXPECT_TRUE(event); + EXPECT_EQ(expected_event, event.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) .WillOnce(testing::Return(nullptr)); } @@ -135,14 +161,19 @@ TEST_F(SdRefTest, MoveAssignOverValid) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock2); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event2, event2.get()); EXPECT_CALL(mock2, sd_event_unref(expected_event2)) .WillOnce(testing::Return(nullptr)); event2 = std::move(event); + EXPECT_FALSE(event); + EXPECT_EQ(nullptr, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -159,6 +190,9 @@ TEST_F(SdRefTest, MoveAssignOverMoved) EXPECT_EQ(expected_event2, event2.get()); { SdRef<sd_event> event_mover(std::move(event2)); + EXPECT_FALSE(event2); + EXPECT_EQ(nullptr, event2.get()); + EXPECT_TRUE(event_mover); EXPECT_EQ(expected_event2, event_mover.get()); EXPECT_CALL(mock2, sd_event_unref(expected_event2)) @@ -166,6 +200,9 @@ TEST_F(SdRefTest, MoveAssignOverMoved) } event2 = std::move(event); + EXPECT_FALSE(event); + EXPECT_EQ(nullptr, event.get()); + EXPECT_TRUE(event2); EXPECT_EQ(expected_event, event2.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) @@ -176,8 +213,12 @@ TEST_F(SdRefTest, MoveSelf) { SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, &SdEvent::sd_event_unref, std::false_type(), &mock); + EXPECT_TRUE(event); EXPECT_EQ(expected_event, event.get()); + event = std::move(event); + EXPECT_TRUE(event); + EXPECT_EQ(expected_event, event.get()); EXPECT_CALL(mock, sd_event_unref(expected_event)) .WillOnce(testing::Return(nullptr)); } |

