Add assertions to unique_ref

This commit is contained in:
Sebastian Messmer 2016-07-14 16:29:02 +02:00
parent 7ea08fc2b0
commit 457ca52eb3
4 changed files with 23 additions and 9 deletions

View File

@ -13,7 +13,7 @@ CachedBlock::CachedBlock(unique_ref<Block> baseBlock, CachingBlockStore *blockSt
} }
CachedBlock::~CachedBlock() { CachedBlock::~CachedBlock() {
if (_baseBlock.get() != nullptr) { if (_baseBlock.isValid()) {
_blockStore->release(std::move(_baseBlock)); _blockStore->release(std::move(_baseBlock));
} }
} }

View File

@ -7,6 +7,7 @@
#include "../macros.h" #include "../macros.h"
#include "gcc_4_8_compatibility.h" #include "gcc_4_8_compatibility.h"
#include "cast.h" #include "cast.h"
#include "../assert/assert.h"
namespace cpputils { namespace cpputils {
@ -28,24 +29,32 @@ template<typename T>
class unique_ref final { class unique_ref final {
public: public:
unique_ref(unique_ref&& from): _target(std::move(from._target)) {} unique_ref(unique_ref&& from): _target(std::move(from._target)) {
from._target = nullptr;
}
// TODO Test this upcast-allowing move constructor // TODO Test this upcast-allowing move constructor
template<typename U> unique_ref(unique_ref<U>&& from): _target(std::move(from._target)) {} template<typename U> unique_ref(unique_ref<U>&& from): _target(std::move(from._target)) {
from._target = nullptr;
}
unique_ref& operator=(unique_ref&& from) { unique_ref& operator=(unique_ref&& from) {
_target = std::move(from._target); _target = std::move(from._target);
from._target = nullptr;
return *this; return *this;
} }
// TODO Test this upcast-allowing assignment // TODO Test this upcast-allowing assignment
template<typename U> unique_ref& operator=(unique_ref<U>&& from) { template<typename U> unique_ref& operator=(unique_ref<U>&& from) {
_target = std::move(from._target); _target = std::move(from._target);
from._target = nullptr;
return *this; return *this;
} }
typename std::add_lvalue_reference<T>::type operator*() const& { typename std::add_lvalue_reference<T>::type operator*() const& {
ASSERT(_target.get() != nullptr, "Member was moved out to another unique_ref. This instance is invalid.");
return *_target; return *_target;
} }
typename std::add_rvalue_reference<T>::type operator*() && { typename std::add_rvalue_reference<T>::type operator*() && {
ASSERT(_target.get() != nullptr, "Member was moved out to another unique_ref. This instance is invalid.");
return std::move(*_target); return std::move(*_target);
} }
@ -54,6 +63,7 @@ public:
} }
T* get() const { T* get() const {
ASSERT(_target.get() != nullptr, "Member was moved out to another unique_ref. This instance is invalid.");
return _target.get(); return _target.get();
} }
@ -61,6 +71,10 @@ public:
std::swap(_target, rhs._target); std::swap(_target, rhs._target);
} }
bool isValid() const {
return _target.get() != nullptr;
}
private: private:
unique_ref(std::unique_ptr<T> target): _target(std::move(target)) {} unique_ref(std::unique_ptr<T> target): _target(std::move(target)) {}
template<typename U, typename... Args> friend unique_ref<U> make_unique_ref(Args&&... args); template<typename U, typename... Args> friend unique_ref<U> make_unique_ref(Args&&... args);

View File

@ -5,7 +5,7 @@ namespace cryfs {
namespace cachingfsblobstore { namespace cachingfsblobstore {
FsBlobRef::~FsBlobRef() { FsBlobRef::~FsBlobRef() {
if (_baseBlob.get() != nullptr) { if (_baseBlob.isValid()) {
_fsBlobStore->releaseForCache(std::move(_baseBlob)); _fsBlobStore->releaseForCache(std::move(_baseBlob));
} }
} }

View File

@ -15,25 +15,25 @@ public:
TYPED_TEST_CASE_P(FsppSymlinkTest); TYPED_TEST_CASE_P(FsppSymlinkTest);
TYPED_TEST_P(FsppSymlinkTest, Create_AbsolutePath) { TYPED_TEST_P(FsppSymlinkTest, Create_AbsolutePath) {
this->CreateSymlink("mysymlink", "/my/symlink/target"); this->CreateSymlink("/mysymlink", "/my/symlink/target");
} }
TYPED_TEST_P(FsppSymlinkTest, Create_RelativePath) { TYPED_TEST_P(FsppSymlinkTest, Create_RelativePath) {
this->CreateSymlink("mysymlink", "../target"); this->CreateSymlink("/mysymlink", "../target");
} }
TYPED_TEST_P(FsppSymlinkTest, Read_AbsolutePath) { TYPED_TEST_P(FsppSymlinkTest, Read_AbsolutePath) {
this->CreateSymlink("mysymlink", "/my/symlink/target"); this->CreateSymlink("/mysymlink", "/my/symlink/target");
EXPECT_EQ("/my/symlink/target", this->LoadSymlink("/mysymlink")->target()); EXPECT_EQ("/my/symlink/target", this->LoadSymlink("/mysymlink")->target());
} }
TYPED_TEST_P(FsppSymlinkTest, Read_RelativePath) { TYPED_TEST_P(FsppSymlinkTest, Read_RelativePath) {
this->CreateSymlink("mysymlink", "../target"); this->CreateSymlink("/mysymlink", "../target");
EXPECT_EQ("../target", this->LoadSymlink("/mysymlink")->target()); EXPECT_EQ("../target", this->LoadSymlink("/mysymlink")->target());
} }
TYPED_TEST_P(FsppSymlinkTest, Remove) { TYPED_TEST_P(FsppSymlinkTest, Remove) {
this->CreateSymlink("mysymlink", "/my/symlink/target"); this->CreateSymlink("/mysymlink", "/my/symlink/target");
EXPECT_NE(boost::none, this->device->Load("/mysymlink")); EXPECT_NE(boost::none, this->device->Load("/mysymlink"));
this->LoadSymlink("/mysymlink")->remove(); this->LoadSymlink("/mysymlink")->remove();
EXPECT_EQ(boost::none, this->device->Load("/mysymlink")); EXPECT_EQ(boost::none, this->device->Load("/mysymlink"));