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
This commit is contained in:
Anna Gringauze 2018-08-13 02:22:02 -07:00 committed by GitHub
parent f1a2e91e4e
commit 831584d947
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 0 deletions

View File

@ -119,6 +119,11 @@ private:
T ptr_; T ptr_;
}; };
template <class T>
auto make_not_null(T&& t) {
return gsl::not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
template <class T> template <class T>
std::ostream& operator<<(std::ostream& os, const not_null<T>& val) std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
{ {

View File

@ -19,6 +19,8 @@
// so people aren't annoyed by them when running the tool. // so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch #pragma warning(disable : 26440 26426) // from catch
// Fix VS2015 build breaks in Release
#pragma warning(disable : 4702) // unreachable code
#endif #endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_... #include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
@ -32,6 +34,8 @@
#include <string> // for basic_string, operator==, string, operator<< #include <string> // for basic_string, operator==, string, operator<<
#include <typeinfo> // for type_info #include <typeinfo> // for type_info
namespace gsl { namespace gsl {
struct fail_fast; struct fail_fast;
} // namespace gsl } // namespace gsl
@ -416,4 +420,61 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
} }
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) #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<not_null<void *>>::value, "not_null must be no-throw move constructible"); static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");