aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Gringauze <annagrin@microsoft.com>2018-06-07 13:36:56 -0700
committerGitHub <noreply@github.com>2018-06-07 13:36:56 -0700
commitcb2d1af89afb76bf50efe8e068c5ea1fc2872274 (patch)
tree88464c546dbcbcb1c093d3a19f47e0b080f99a51
parent75ad0c1b40d27a2d0749861df923cb38f866a6c2 (diff)
downloadplatform_external_Microsoft-GSL-cb2d1af89afb76bf50efe8e068c5ea1fc2872274.tar.gz
platform_external_Microsoft-GSL-cb2d1af89afb76bf50efe8e068c5ea1fc2872274.tar.bz2
platform_external_Microsoft-GSL-cb2d1af89afb76bf50efe8e068c5ea1fc2872274.zip
Added template argument deduction for not_null (#689)
* Added template argument deduction for not_null This allows compilers with c++17 support to infer template instantiation types when calling not_null constructor: int foo(not_null<const int*> x); int main() { int t = 0; not_null x{ &t }; return foo(not_null{ &t }); } * replaced deduction guides by a simple constructor * Updated tests * fixed check for availability of std::byte * testing c++1z on clang * fixed cmakelists extra endif * include cstddef header for clang and gcc in pointers * fixed a typo * fix missing nullptr_t type * fixed typo in CMakeLists.tst * change approach to c++17 testing, step one: revert cmake testing, update clang5.0 package removed using latest c++ due to clang5.0 failing, update clang5.0 travis config to use llvm-toolchain-trusty-5.0 * addressed comments
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt17
-rw-r--r--include/gsl/pointers6
-rw-r--r--tests/notnull_tests.cpp59
4 files changed, 80 insertions, 4 deletions
diff --git a/.travis.yml b/.travis.yml
index 647a1c1..d2e4d9d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -128,7 +128,7 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main'
+ - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0ab5e44..e96fb64 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,20 +14,31 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(GSL_STANDALONE_PROJECT ON)
endif ()
+
+include(CheckCXXCompilerFlag)
+if (NOT MSVC)
+ CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
+else()
+ CHECK_CXX_COMPILER_FLAG("-std:c++14" COMPILER_SUPPORTS_CXX14)
+endif()
+
# when minimum version required is 3.8.0 remove if below
# both branches do exactly the same thing
if (CMAKE_VERSION VERSION_LESS 3.7.9)
if (NOT MSVC)
- include(CheckCXXCompilerFlag)
- CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
if(COMPILER_SUPPORTS_CXX14)
target_compile_options(GSL INTERFACE "-std=c++14")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()
+ else()
+ if(COMPILER_SUPPORTS_CXX14)
+ target_compile_options(GSL INTERFACE "-std:c++14")
+ else()
+ message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
+ endif()
endif()
else ()
- # set the GSL library to be compiled only with c++14
target_compile_features(GSL INTERFACE cxx_std_14)
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/include/gsl/pointers b/include/gsl/pointers
index ad15ce3..69499d6 100644
--- a/include/gsl/pointers
+++ b/include/gsl/pointers
@@ -77,6 +77,12 @@ public:
Expects(ptr_ != nullptr);
}
+ template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
+ constexpr explicit not_null(T u) : ptr_(u)
+ {
+ Expects(ptr_ != nullptr);
+ }
+
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(const not_null<U>& other) : not_null(other.get())
{
diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp
index fa99bb7..1cb9c10 100644
--- a/tests/notnull_tests.cpp
+++ b/tests/notnull_tests.cpp
@@ -112,6 +112,7 @@ struct NonCopyableNonMovable
};
bool helper(not_null<int*> p) { return *p == 12; }
+bool helper_const(not_null<const int*> p) { return *p == 12; }
TEST_CASE("TestNotNullConstructors")
{
@@ -328,4 +329,62 @@ TEST_CASE("TestNotNullCustomPtrComparison")
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
}
+
+#if defined(__cplusplus) && (__cplusplus >= 201703L)
+TEST_CASE("TestNotNullConstructorTypeDeduction")
+{
+ {
+ int i = 42;
+
+ not_null x{&i};
+ helper(not_null{&i});
+ helper_const(not_null{&i});
+
+ CHECK(*x == 42);
+ }
+
+ {
+ int i = 42;
+ int* p = &i;
+
+ not_null x{p};
+ helper(not_null{p});
+ helper_const(not_null{p});
+
+ CHECK(*x == 42);
+ }
+
+ {
+ auto workaround_macro = []() {
+ int* p1 = nullptr;
+ not_null x{p1};
+ };
+ CHECK_THROWS_AS(workaround_macro(), fail_fast);
+ }
+
+ {
+ auto workaround_macro = []() {
+ const int* p1 = nullptr;
+ not_null x{p1};
+ };
+ CHECK_THROWS_AS(workaround_macro(), fail_fast);
+ }
+
+ {
+ int* p = nullptr;
+
+ CHECK_THROWS_AS(helper(not_null{p}), fail_fast);
+ CHECK_THROWS_AS(helper_const(not_null{p}), fail_fast);
+ }
+
+#ifdef CONFIRM_COMPILATION_ERRORS
+ {
+ not_null x{nullptr};
+ helper(not_null{nullptr});
+ helper_const(not_null{nullptr});
+ }
+#endif
+}
+#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
+
static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");