From 247c4250d40d362953f5566d1527576c6c0ba352 Mon Sep 17 00:00:00 2001 From: Alexey Malov Date: Wed, 31 May 2017 21:18:55 +0300 Subject: [PATCH] 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* --- include/gsl/gsl | 2 +- tests/notnull_tests.cpp | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/gsl/gsl b/include/gsl/gsl index bc46aac..3679fa1 100644 --- a/include/gsl/gsl +++ b/include/gsl/gsl @@ -108,7 +108,7 @@ public: constexpr operator T() 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 not_null(std::nullptr_t) = delete; diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 85ed5b5..caab476 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -95,6 +95,16 @@ std::string operator>=(CustomPtr const& lhs, CustomPtr const& rhs) : "false"; } +struct NonCopyableNonMovable +{ + NonCopyableNonMovable() = default; + NonCopyableNonMovable(const NonCopyableNonMovable&) = delete; + NonCopyableNonMovable& operator=(const NonCopyableNonMovable&) = delete; + NonCopyableNonMovable(NonCopyableNonMovable&&) = delete; + NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete; +}; + + SUITE(NotNullTests) { @@ -253,18 +263,33 @@ SUITE(NotNullTests) TEST(TestNotNullDereferenceOperator) { - auto sp1 = std::make_shared(42); + { + auto sp1 = std::make_shared(); - using NotNullSp1 = not_null; + using NotNullSp1 = not_null; + CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1))); + CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1)); + } - CHECK(*NotNullSp1(sp1) == *sp1); + { + int ints[1] = { 42 }; + CustomPtr p1(&ints[0]); - int ints[1] = {42}; - CustomPtr p1(&ints[0]); + using NotNull1 = not_null; + CHECK(typeid(*NotNull1(p1)) == typeid(*p1)); + CHECK(*NotNull1(p1) == 42); + *NotNull1(p1) = 43; + CHECK(ints[0] == 43); + } - using NotNull1 = not_null; - CHECK(*NotNull1(p1) == 42); - } + { + int v = 42; + gsl::not_null p(&v); + CHECK(typeid(*p) == typeid(*(&v))); + *p = 43; + CHECK(v == 43); + } + } } int main(int, const char* []) { return UnitTest::RunAllTests(); }