mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-25 09:11:58 -05:00
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
This commit is contained in:
parent
75ad0c1b40
commit
cb2d1af89a
@ -128,7 +128,7 @@ matrix:
|
|||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- llvm-toolchain-trusty-5.0
|
- 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'
|
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||||
|
|
||||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
|
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
|
||||||
|
@ -14,20 +14,31 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|||||||
set(GSL_STANDALONE_PROJECT ON)
|
set(GSL_STANDALONE_PROJECT ON)
|
||||||
endif ()
|
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
|
# when minimum version required is 3.8.0 remove if below
|
||||||
# both branches do exactly the same thing
|
# both branches do exactly the same thing
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.7.9)
|
if (CMAKE_VERSION VERSION_LESS 3.7.9)
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
|
|
||||||
if(COMPILER_SUPPORTS_CXX14)
|
if(COMPILER_SUPPORTS_CXX14)
|
||||||
target_compile_options(GSL INTERFACE "-std=c++14")
|
target_compile_options(GSL INTERFACE "-std=c++14")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
|
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
|
||||||
endif()
|
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()
|
endif()
|
||||||
else ()
|
else ()
|
||||||
# set the GSL library to be compiled only with c++14
|
|
||||||
target_compile_features(GSL INTERFACE cxx_std_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)
|
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
@ -77,6 +77,12 @@ public:
|
|||||||
Expects(ptr_ != nullptr);
|
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>>
|
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())
|
constexpr not_null(const not_null<U>& other) : not_null(other.get())
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,7 @@ struct NonCopyableNonMovable
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool helper(not_null<int*> p) { return *p == 12; }
|
bool helper(not_null<int*> p) { return *p == 12; }
|
||||||
|
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||||
|
|
||||||
TEST_CASE("TestNotNullConstructors")
|
TEST_CASE("TestNotNullConstructors")
|
||||||
{
|
{
|
||||||
@ -328,4 +329,62 @@ TEST_CASE("TestNotNullCustomPtrComparison")
|
|||||||
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
|
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");
|
static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");
|
||||||
|
Loading…
Reference in New Issue
Block a user