Skip to content

Commit

Permalink
move static_asserts to the original places, making the diff easier to…
Browse files Browse the repository at this point in the history
… read
  • Loading branch information
Werner Henze authored and Werner Henze committed Jan 2, 2025
1 parent df11fd4 commit 4279da5
Show file tree
Hide file tree
Showing 4 changed files with 381 additions and 366 deletions.
191 changes: 113 additions & 78 deletions tests/notnull_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
#include "deathTestCommon.h"
using namespace gsl;

#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l

struct MyBase
{
};
Expand Down Expand Up @@ -142,9 +149,38 @@ bool helper_const(not_null<const int*> p) { return *p == 12; }
int* return_pointer() { return nullptr; }
} // namespace

template <typename U, typename = void>
static constexpr bool CtorCompilesFor_A = false;
template <typename U>
static constexpr bool
CtorCompilesFor_A<U, void_t<decltype(gsl::not_null<void*>{std::declval<U>()})>> = true;

template <typename U, int N, typename = void>
static constexpr bool CtorCompilesFor_B = false;
template <typename U, int N>
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::not_null<U>{N})>> = true;

template <typename U, typename = void>
static constexpr bool DefaultCtorCompilesFor = false;
template <typename U>
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::not_null<U>{})>> = true;

template <typename U, typename = void>
static constexpr bool CtorCompilesFor_C = false;
template <typename U>
static constexpr bool
CtorCompilesFor_C<U, void_t<decltype(gsl::not_null<U*>{std::declval<std::unique_ptr<U>>()})>> =
true;

TEST(notnull_tests, TestNotNullConstructors)
{
{
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");

#ifdef CONFIRM_COMPILATION_ERRORS
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
Expand Down Expand Up @@ -271,6 +307,27 @@ TEST(notnull_tests, TestNotNullostream)
ostream_helper<std::string>("string");
}

template <typename U, typename V, typename = void>
static constexpr bool AssignmentCompilesFor = false;
template <typename U, typename V>
static constexpr bool
AssignmentCompilesFor<U, V,
void_t<decltype(std::declval<gsl::not_null<U*>&>().operator=(
std::declval<gsl::not_null<V*>&>()))>> = true;

template <typename U, typename V, typename = void>
static constexpr bool SCastCompilesFor = false;
template <typename U, typename V>
static constexpr bool
SCastCompilesFor<U, V, void_t<decltype(static_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> =
true;

template <typename U, typename V, typename = void>
static constexpr bool RCastCompilesFor = false;
template <typename U, typename V>
static constexpr bool RCastCompilesFor<
U, V, void_t<decltype(reinterpret_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;

TEST(notnull_tests, TestNotNullCasting)
{
MyBase base;
Expand All @@ -283,11 +340,30 @@ TEST(notnull_tests, TestNotNullCasting)
q = p; // allowed with heterogeneous copy ctor
EXPECT_TRUE(q == p);

static_assert(AssignmentCompilesFor<MyBase, MyDerived>,
"AssignmentCompilesFor<MyBase, MyDerived>");
static_assert(!AssignmentCompilesFor<MyBase, Unrelated>,
"!AssignmentCompilesFor<MyBase, Unrelated>");
static_assert(!AssignmentCompilesFor<Unrelated, MyDerived>,
"!AssignmentCompilesFor<Unrelated, MyDerived>");
static_assert(!AssignmentCompilesFor<MyDerived, MyBase>,
"!AssignmentCompilesFor<MyDerived, MyBase>");

static_assert(SCastCompilesFor<MyDerived, MyDerived>, "SCastCompilesFor<MyDerived, MyDerived>");
static_assert(SCastCompilesFor<MyBase, MyDerived>, "SCastCompilesFor<MyBase, MyDerived>");
static_assert(!SCastCompilesFor<MyDerived, MyBase>, "!SCastCompilesFor<MyDerived, MyBase>");
static_assert(!SCastCompilesFor<Unrelated, MyDerived>,
"!SCastCompilesFor<Unrelated, MyDerived>");
static_assert(!RCastCompilesFor<MyDerived, MyDerived>,
"!SCastCompilesFor<MyDerived, MyDerived>");
static_assert(!RCastCompilesFor<Unrelated, MyDerived>,
"!SCastCompilesFor<Unrelated, MyDerived>");

not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));

(void)static_cast<MyDerived*>(p);
(void)static_cast<MyBase*>(p);
(void) static_cast<MyDerived*>(p);
(void) static_cast<MyBase*>(p);
}

TEST(notnull_tests, TestNotNullAssignment)
Expand Down Expand Up @@ -429,6 +505,18 @@ TEST(notnull_tests, TestNotNullCustomPtrComparison)

#if defined(__cplusplus) && (__cplusplus >= 201703L)

template <typename U, typename = void>
static constexpr bool TypeDeductionCtorCompilesFor = false;
template <typename U>
static constexpr bool
TypeDeductionCtorCompilesFor<U, void_t<decltype(not_null{std::declval<U>()})>> = true;

template <typename U, typename = void>
static constexpr bool TypeDeductionHelperCompilesFor = false;
template <typename U>
static constexpr bool
TypeDeductionHelperCompilesFor<U, void_t<decltype(helper(not_null{std::declval<U>()}))>> = true;

TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
{
{
Expand All @@ -445,6 +533,9 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
const int i = 42;

not_null x{&i};
static_assert(TypeDeductionHelperCompilesFor<int*>, "TypeDeductionHelperCompilesFor<int*>");
static_assert(!TypeDeductionHelperCompilesFor<const int*>,
"!TypeDeductionHelperCompilesFor<const int*>");
helper_const(not_null{&i});

EXPECT_TRUE(*x == 42);
Expand Down Expand Up @@ -499,6 +590,17 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
EXPECT_DEATH(helper(not_null{p}), expected);
EXPECT_DEATH(helper_const(not_null{p}), expected);
}

static_assert(TypeDeductionCtorCompilesFor<void*>, "TypeDeductionCtorCompilesFor<void*>");
#if defined(_MSC_VER) && !defined(__clang__)
// Fails on gcc, clang, xcode, VS clang with
// "error : no type named 'type' in 'std::enable_if<false>'; 'enable_if' cannot be used to
// disable this declaration"
static_assert(!TypeDeductionCtorCompilesFor<std::nullptr_t>,
"!TypeDeductionCtorCompilesFor<std::nullptr_t>");
static_assert(!TypeDeductionHelperCompilesFor<std::nullptr_t>,
"!TypeDeductionHelperCompilesFor<std::nullptr_t>");
#endif
}

TEST(notnull_tests, TestVariantEmplace)
Expand All @@ -513,6 +615,11 @@ TEST(notnull_tests, TestVariantEmplace)
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)

template <typename U, typename = void>
static constexpr bool HelperCompilesFor = false;
template <typename U>
static constexpr bool HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;

TEST(notnull_tests, TestMakeNotNull)
{
{
Expand All @@ -529,6 +636,8 @@ TEST(notnull_tests, TestMakeNotNull)
const int i = 42;

const auto x = make_not_null(&i);
static_assert(HelperCompilesFor<gsl::not_null<int*>>,
"HelperCompilesFor<gsl::not_null<int*>>");
helper_const(make_not_null(&i));

EXPECT_TRUE(*x == 42);
Expand All @@ -550,6 +659,8 @@ TEST(notnull_tests, TestMakeNotNull)
const int* p = &i;

const auto x = make_not_null(p);
static_assert(!HelperCompilesFor<gsl::not_null<const int*>>,
"!HelperCompilesFor<gsl::not_null<const int*>>");
helper_const(make_not_null(p));

EXPECT_TRUE(*x == 42);
Expand Down Expand Up @@ -625,79 +736,3 @@ TEST(notnull_tests, TestStdHash)
EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr));
}
}

#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l

template <typename U, typename = void>
static constexpr bool CtorCompilesFor_A = false;
template <typename U>
static constexpr bool
CtorCompilesFor_A<U, void_t<decltype(gsl::not_null<void*>{std::declval<U>()})>> = true;
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");

template <typename U, int N, typename = void>
static constexpr bool CtorCompilesFor_B = false;
template <typename U, int N>
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::not_null<U>{N})>> = true;
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");

template <typename U, typename = void>
static constexpr bool CtorCompilesFor_C = false;
template <typename U>
static constexpr bool
CtorCompilesFor_C<U, void_t<decltype(gsl::not_null<U*>{std::declval<std::unique_ptr<U>>()})>> =
true;
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");

template <typename U, typename = void>
static constexpr bool DefaultCtorCompilesFor = false;
template <typename U>
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::not_null<U>{})>> = true;
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");

template <typename U, typename V, typename = void>
static constexpr bool AssignmentCompilesFor = false;
template <typename U, typename V>
static constexpr bool
AssignmentCompilesFor<U, V,
void_t<decltype(std::declval<gsl::not_null<U*>&>().operator=(
std::declval<gsl::not_null<V*>&>()))>> = true;
static_assert(AssignmentCompilesFor<MyBase, MyDerived>, "AssignmentCompilesFor<MyBase, MyDerived>");
static_assert(!AssignmentCompilesFor<MyBase, Unrelated>,
"!AssignmentCompilesFor<MyBase, Unrelated>");
static_assert(!AssignmentCompilesFor<Unrelated, MyDerived>,
"!AssignmentCompilesFor<Unrelated, MyDerived>");
static_assert(!AssignmentCompilesFor<MyDerived, MyBase>,
"!AssignmentCompilesFor<MyDerived, MyBase>");

template <typename U, typename V, typename = void>
static constexpr bool CastCompilesFor_A = false;
template <typename U, typename V>
static constexpr bool CastCompilesFor_A<
U, V, void_t<decltype(static_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;
static_assert(CastCompilesFor_A<MyDerived, MyDerived>, "CastCompilesFor_A<MyDerived, MyDerived>");
static_assert(CastCompilesFor_A<MyBase, MyDerived>, "CastCompilesFor_A<MyBase, MyDerived>");
static_assert(!CastCompilesFor_A<MyDerived, MyBase>, "!CastCompilesFor_A<MyDerived, MyBase>");
static_assert(!CastCompilesFor_A<Unrelated, MyDerived>, "!CastCompilesFor_A<Unrelated, MyDerived>");

template <typename U, typename V, typename = void>
static constexpr bool CastCompilesFor_B = false;
template <typename U, typename V>
static constexpr bool CastCompilesFor_B<
U, V, void_t<decltype(reinterpret_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;
static_assert(!CastCompilesFor_B<MyDerived, MyDerived>, "!CastCompilesFor_A<MyDerived, MyDerived>");
static_assert(!CastCompilesFor_B<Unrelated, MyDerived>, "!CastCompilesFor_A<Unrelated, MyDerived>");

template <typename U, typename = void>
static constexpr bool HelperCompilesFor = false;
template <typename U>
static constexpr bool HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;
static_assert(HelperCompilesFor<gsl::not_null<int*>>, "HelperCompilesFor<gsl::not_null<int*>>");
static_assert(!HelperCompilesFor<gsl::not_null<const int*>>,
"!HelperCompilesFor<gsl::not_null<const int*>>");
33 changes: 17 additions & 16 deletions tests/pointers_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
#include <type_traits>
#include <utility>

#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l

namespace
{
// Custom pointer type that can be used for gsl::not_null, but for which these cannot be swapped.
Expand All @@ -22,6 +29,13 @@ struct NotMoveAssignableCustomPtr
int dummy{}; // Without this clang warns, that NotMoveAssignableCustomPtr() is unneeded
};

template <typename U, typename = void>
static constexpr bool SwapCompilesFor = false;
template <typename U>
static constexpr bool
SwapCompilesFor<U, void_t<decltype(gsl::swap<U>(std::declval<gsl::not_null<U>&>(),
std::declval<gsl::not_null<U>&>()))>> = true;

TEST(pointers_test, swap)
{
// taken from gh-1129:
Expand Down Expand Up @@ -69,22 +83,9 @@ TEST(pointers_test, swap)
EXPECT_TRUE(*a == 1);
EXPECT_TRUE(*b == 0);
}
}

#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l

template <typename U, typename = void>
static constexpr bool SwapCompilesFor = false;
template <typename U>
static constexpr bool
SwapCompilesFor<U, void_t<decltype(gsl::swap<U>(std::declval<gsl::not_null<U>&>(),
std::declval<gsl::not_null<U>&>()))>> = true;
static_assert(!SwapCompilesFor<NotMoveAssignableCustomPtr>,
"!SwapCompilesFor<NotMoveAssignableCustomPtr>");
static_assert(!SwapCompilesFor<NotMoveAssignableCustomPtr>,
"!SwapCompilesFor<NotMoveAssignableCustomPtr>");
}

} // namespace
Loading

0 comments on commit 4279da5

Please sign in to comment.