Fixes dereferencing operator issue #517 introduced in PR #513 (#516)

* Fixes issue with dereferencing operator issue #491 introduced in PR #513

dereferencing operator added in PR#513 returned a copy of the object
instead of reference to it.
Adding decltype(auto) as return type of operator* fixes this issue.

* added more tests for not_null::operator*
This commit is contained in:
Alexey Malov 2017-05-31 21:18:55 +03:00 committed by Neil MacIntosh
parent 30595c1f1d
commit 247c4250d4
2 changed files with 34 additions and 9 deletions

View File

@ -108,7 +108,7 @@ public:
constexpr operator T() const { return get(); } constexpr operator T() const { return get(); }
constexpr T operator->() const { return get(); } constexpr T operator->() const { return get(); }
constexpr auto operator*() const { return *get(); } constexpr decltype(auto) operator*() const { return *get(); }
// prevents compilation when someone attempts to assign a null pointer constant // prevents compilation when someone attempts to assign a null pointer constant
not_null(std::nullptr_t) = delete; not_null(std::nullptr_t) = delete;

View File

@ -95,6 +95,16 @@ std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
: "false"; : "false";
} }
struct NonCopyableNonMovable
{
NonCopyableNonMovable() = default;
NonCopyableNonMovable(const NonCopyableNonMovable&) = delete;
NonCopyableNonMovable& operator=(const NonCopyableNonMovable&) = delete;
NonCopyableNonMovable(NonCopyableNonMovable&&) = delete;
NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
};
SUITE(NotNullTests) SUITE(NotNullTests)
{ {
@ -253,18 +263,33 @@ SUITE(NotNullTests)
TEST(TestNotNullDereferenceOperator) TEST(TestNotNullDereferenceOperator)
{ {
auto sp1 = std::make_shared<int>(42); {
auto sp1 = std::make_shared<NonCopyableNonMovable>();
using NotNullSp1 = not_null<decltype(sp1)>; using NotNullSp1 = not_null<decltype(sp1)>;
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
}
CHECK(*NotNullSp1(sp1) == *sp1); {
int ints[1] = { 42 };
CustomPtr<int> p1(&ints[0]);
int ints[1] = {42}; using NotNull1 = not_null<decltype(p1)>;
CustomPtr<int> p1(&ints[0]); CHECK(typeid(*NotNull1(p1)) == typeid(*p1));
CHECK(*NotNull1(p1) == 42);
*NotNull1(p1) = 43;
CHECK(ints[0] == 43);
}
using NotNull1 = not_null<decltype(p1)>; {
CHECK(*NotNull1(p1) == 42); int v = 42;
} gsl::not_null<int*> p(&v);
CHECK(typeid(*p) == typeid(*(&v)));
*p = 43;
CHECK(v == 43);
}
}
} }
int main(int, const char* []) { return UnitTest::RunAllTests(); } int main(int, const char* []) { return UnitTest::RunAllTests(); }