From 831584d94778e360d1616edc8b1562516795a853 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 13 Aug 2018 02:22:02 -0700 Subject: [PATCH] Dev/annagrin/make not null (#711) * Added c++17 test configurations for clang5.0 and clang6.0 * Added make_not_null helper to create a not_null Introduction of explicit not_null constructor made it cumbersome to create not_nulls in c++14. Adding make_not_null helper. Usage (see tests): int i = 42; auto x = make_not_null(&i); helper(make_not_null(&i)); helper_const(make_not_null(&i)); * Added std::forward to make_not_null, fixed some code analysis warnings * Fix build break in VS2015 Release configuration * Fix build break in VS2015 Release configuration --- include/gsl/pointers | 5 ++++ tests/notnull_tests.cpp | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/gsl/pointers b/include/gsl/pointers index 69499d6..a338856 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -119,6 +119,11 @@ private: T ptr_; }; +template +auto make_not_null(T&& t) { + return gsl::not_null>>{std::forward(t)}; +} + template std::ostream& operator<<(std::ostream& os, const not_null& val) { diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index e522fb5..673eab8 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -19,6 +19,8 @@ // so people aren't annoyed by them when running the tool. #pragma warning(disable : 26440 26426) // from catch +// Fix VS2015 build breaks in Release +#pragma warning(disable : 4702) // unreachable code #endif #include // for AssertionHandler, StringRef, CHECK, TEST_... @@ -32,6 +34,8 @@ #include // for basic_string, operator==, string, operator<< #include // for type_info + + namespace gsl { struct fail_fast; } // namespace gsl @@ -416,4 +420,61 @@ TEST_CASE("TestNotNullConstructorTypeDeduction") } #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) +TEST_CASE("TestMakeNotNull") +{ + { + int i = 42; + + const auto x = make_not_null(&i); + helper(make_not_null(&i)); + helper_const(make_not_null(&i)); + + CHECK(*x == 42); + } + + { + int i = 42; + int* p = &i; + + const auto x = make_not_null(p); + helper(make_not_null(p)); + helper_const(make_not_null(p)); + + CHECK(*x == 42); + } + + { + const auto workaround_macro = []() { + int* p1 = nullptr; + const auto x = make_not_null(p1); + CHECK(*x == 42); + }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } + + { + const auto workaround_macro = []() { + const int* p1 = nullptr; + const auto x = make_not_null(p1); + CHECK(*x == 42); + }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } + + { + int* p = nullptr; + + CHECK_THROWS_AS(helper(make_not_null(p)), fail_fast); + CHECK_THROWS_AS(helper_const(make_not_null(p)), fail_fast); + } + +#ifdef CONFIRM_COMPILATION_ERRORS + { + CHECK_THROWS_AS(make_not_null(nullptr), fail_fast); + CHECK_THROWS_AS(helper(make_not_null(nullptr)), fail_fast); + CHECK_THROWS_AS(helper_const(make_not_null(nullptr)), fail_fast); + } +#endif +} + static_assert(std::is_nothrow_move_constructible>::value, "not_null must be no-throw move constructible");