Skip to content

Commit 029c9c3

Browse files
authored
[libc++] Refactor tests for std::pointer_traits (#66645)
After landing the implementation of LWG3545, I realized that the tests for std::pointer_traits had become a bit disorganized. This patch is a NFC that refactors the tests: - Move compile-only tests to `.compile.pass.cpp` tests - Re-create the clear distinction between tests for the std::pointer_traits base tempate and for the T* specialization. - De-duplicate test coverage -- we had a bunch of things that were tested in duplication.
1 parent 95ce3c2 commit 029c9c3

File tree

9 files changed

+208
-351
lines changed

9 files changed

+208
-351
lines changed

libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,33 @@
2222
#include "test_macros.h"
2323

2424
template <class T>
25-
struct A
26-
{
25+
struct A {
2726
private:
28-
struct nat {};
27+
struct nat {};
28+
2929
public:
30-
typedef T element_type;
31-
element_type* t_;
30+
typedef T element_type;
31+
element_type* t_;
3232

33-
A(element_type* t) : t_(t) {}
33+
A(element_type* t) : t_(t) {}
3434

35-
static A pointer_to(typename std::conditional<std::is_void<element_type>::value,
36-
nat, element_type>::type& et)
37-
{return A(&et);}
35+
static A pointer_to(typename std::conditional<std::is_void<element_type>::value, nat, element_type>::type& et) {
36+
return A(&et);
37+
}
3838
};
3939

40-
int main(int, char**)
41-
{
42-
{
43-
int i = 0;
44-
static_assert((std::is_same<A<int>, decltype(std::pointer_traits<A<int> >::pointer_to(i))>::value), "");
45-
A<int> a = std::pointer_traits<A<int> >::pointer_to(i);
46-
assert(a.t_ == &i);
47-
}
48-
{
49-
(std::pointer_traits<A<void> >::element_type)0;
50-
}
40+
template <class Pointer>
41+
void test() {
42+
typename Pointer::element_type obj;
43+
static_assert(std::is_same<Pointer, decltype(std::pointer_traits<Pointer>::pointer_to(obj))>::value, "");
44+
Pointer p = std::pointer_traits<Pointer>::pointer_to(obj);
45+
assert(p.t_ == &obj);
46+
}
47+
48+
int main(int, char**) {
49+
test<A<int> >();
50+
test<A<long> >();
51+
{ (std::pointer_traits<A<void> >::element_type)0; }
5152

5253
return 0;
5354
}

libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp renamed to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.compile.pass.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,11 @@ struct F {
5252
typedef int difference_type;
5353
};
5454

55-
int main(int, char**)
56-
{
57-
static_assert((std::is_same<std::pointer_traits<A>::difference_type, char>::value), "");
58-
static_assert((std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value), "");
59-
static_assert((std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value), "");
60-
static_assert((std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value), "");
61-
static_assert((std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value), "");
55+
static_assert(std::is_same<std::pointer_traits<A>::difference_type, char>::value, "");
56+
static_assert(std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value, "");
57+
static_assert(std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value, "");
58+
static_assert(std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value, "");
59+
static_assert(std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value, "");
6260
#if TEST_STD_VER >= 11
63-
static_assert((std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value), "");
61+
static_assert(std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value, "");
6462
#endif
65-
66-
return 0;
67-
}

libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp renamed to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.compile.pass.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,11 @@ struct F {
5353
typedef int element_type;
5454
};
5555

56-
int main(int, char**)
57-
{
58-
static_assert((std::is_same<std::pointer_traits<A>::element_type, char>::value), "");
59-
static_assert((std::is_same<std::pointer_traits<B<int> >::element_type, char>::value), "");
60-
static_assert((std::is_same<std::pointer_traits<C<int> >::element_type, int>::value), "");
61-
static_assert((std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value), "");
62-
static_assert((std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value), "");
56+
static_assert(std::is_same<std::pointer_traits<A>::element_type, char>::value, "");
57+
static_assert(std::is_same<std::pointer_traits<B<int> >::element_type, char>::value, "");
58+
static_assert(std::is_same<std::pointer_traits<C<int> >::element_type, int>::value, "");
59+
static_assert(std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value, "");
60+
static_assert(std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value, "");
6361
#if TEST_STD_VER >= 11
64-
static_assert((std::is_same<std::pointer_traits<F<double>>::element_type, double>::value), "");
62+
static_assert(std::is_same<std::pointer_traits<F<double>>::element_type, double>::value, "");
6563
#endif
66-
67-
68-
return 0;
69-
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <memory>
10+
11+
// Test that `std::pointer_traits` is empty when the pointer type has
12+
// no element_type typedef. See http://wg21.link/LWG3545 for details.
13+
14+
#include <memory>
15+
#include <type_traits>
16+
#include <utility>
17+
18+
#include "test_macros.h"
19+
20+
template <typename... Ts>
21+
struct VoidifyImpl {
22+
using type = void;
23+
};
24+
25+
template <typename... Ts>
26+
using Voidify = typename VoidifyImpl<Ts...>::type;
27+
28+
template <class T, class = void>
29+
struct HasElementType : std::false_type {};
30+
31+
template <class T>
32+
struct HasElementType<T, Voidify<typename std::pointer_traits<T>::element_type> > : std::true_type {};
33+
34+
template <class T, class = void>
35+
struct HasPointerType : std::false_type {};
36+
37+
template <class T>
38+
struct HasPointerType<T, Voidify<typename std::pointer_traits<T>::pointer> > : std::true_type {};
39+
40+
template <class T, class = void>
41+
struct HasDifferenceType : std::false_type {};
42+
43+
template <class T>
44+
struct HasDifferenceType<T, Voidify<typename std::pointer_traits<T>::difference_type> > : std::true_type {};
45+
46+
template <class T, class U, class = void>
47+
struct HasRebind : std::false_type {};
48+
49+
#if TEST_STD_VER >= 11
50+
template <class T, class U>
51+
struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U> > > : std::true_type {};
52+
#else
53+
template <class T, class U>
54+
struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U>::other> > : std::true_type {};
55+
#endif
56+
57+
template <class T, class = void>
58+
struct HasPointerTo : std::false_type {};
59+
60+
template <class T>
61+
struct HasPointerTo<
62+
T,
63+
Voidify<decltype(std::pointer_traits<T>::pointer_to(
64+
std::declval<typename std::add_lvalue_reference<typename std::pointer_traits<T>::element_type>::type>()))> >
65+
: std::true_type {};
66+
67+
struct NotAPtr {};
68+
69+
static_assert(!HasElementType<NotAPtr>::value, "");
70+
static_assert(!HasPointerType<NotAPtr>::value, "");
71+
static_assert(!HasDifferenceType<NotAPtr>::value, "");
72+
static_assert(!HasRebind<NotAPtr, long>::value, "");
73+
static_assert(!HasPointerTo<NotAPtr>::value, "");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <memory>
10+
11+
// template <class Ptr>
12+
// struct pointer_traits
13+
// {
14+
// typedef <details> pointer;
15+
// ...
16+
// };
17+
18+
#include <memory>
19+
#include <type_traits>
20+
21+
struct Foo {
22+
using element_type = int;
23+
};
24+
25+
static_assert(std::is_same<std::pointer_traits<Foo>::pointer, Foo>::value, "");

libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp renamed to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.compile.pass.cpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,26 +81,22 @@ struct G
8181
#endif
8282

8383

84-
int main(int, char**)
85-
{
8684
#if TEST_STD_VER >= 11
87-
static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value), "");
88-
static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value), "");
89-
static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value), "");
90-
static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value), "");
91-
static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value), "");
92-
static_assert((std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value), "");
85+
static_assert(std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value, "");
86+
static_assert(std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value, "");
87+
static_assert(std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value, "");
88+
static_assert(std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value, "");
89+
static_assert(std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value, "");
90+
static_assert(std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value, "");
9391

9492
#if TEST_STD_VER >= 14
95-
static_assert((std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value), "");
96-
#endif
97-
#else // TEST_STD_VER < 11
98-
static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value), "");
99-
static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value), "");
100-
static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value), "");
101-
static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value), "");
102-
static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value), "");
93+
static_assert(std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value, "");
10394
#endif
10495

105-
return 0;
106-
}
96+
#else // TEST_STD_VER < 11
97+
static_assert(std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value, "");
98+
static_assert(std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value, "");
99+
static_assert(std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value, "");
100+
static_assert(std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value, "");
101+
static_assert(std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value, "");
102+
#endif

libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp renamed to libcxx/test/std/utilities/memory/pointer.traits/ptr.pointer_to.pass.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// template <class T>
1212
// struct pointer_traits<T*>
1313
// {
14-
// static pointer pointer_to(<details>); // constexpr in C++20
14+
// static pointer pointer_to(<details>) noexcept; // constexpr in C++20
1515
// ...
1616
// };
1717

@@ -23,14 +23,25 @@
2323

2424
TEST_CONSTEXPR_CXX20 bool test()
2525
{
26+
// pointer_traits<T*>
2627
{
2728
int i = 0;
2829
static_assert(std::is_same<decltype(std::pointer_traits<int*>::pointer_to(i)), int*>::value, "");
30+
ASSERT_NOEXCEPT(std::pointer_traits<int*>::pointer_to(i));
2931
assert(std::pointer_traits<int*>::pointer_to(i) == &i);
3032
}
33+
// pointer_traits<const T*>
34+
{
35+
int const i = 0;
36+
static_assert(std::is_same<decltype(std::pointer_traits<const int*>::pointer_to(i)), const int*>::value, "");
37+
ASSERT_NOEXCEPT(std::pointer_traits<const int*>::pointer_to(i));
38+
assert(std::pointer_traits<const int*>::pointer_to(i) == &i);
39+
}
40+
// pointer_traits<const T*> with a non-const argument
3141
{
3242
int i = 0;
3343
static_assert(std::is_same<decltype(std::pointer_traits<const int*>::pointer_to(i)), const int*>::value, "");
44+
ASSERT_NOEXCEPT(std::pointer_traits<const int*>::pointer_to(i));
3445
assert(std::pointer_traits<const int*>::pointer_to(i) == &i);
3546
}
3647
return true;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <memory>
10+
11+
// template <class T>
12+
// struct pointer_traits<T*>
13+
// {
14+
// using pointer = T*;
15+
// using element_type = T;
16+
// using difference_type = ptrdiff_t;
17+
// template <class U> using rebind = U*;
18+
// };
19+
20+
#include <memory>
21+
#include <cstddef>
22+
23+
#include "test_macros.h"
24+
25+
void f() {
26+
{
27+
using Ptr = int*;
28+
29+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::element_type, int);
30+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::pointer, Ptr);
31+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::difference_type, std::ptrdiff_t);
32+
#if TEST_STD_VER >= 11
33+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>, long*);
34+
#else
35+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>::other, long*);
36+
#endif
37+
}
38+
39+
{
40+
using Ptr = const int*;
41+
42+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::element_type, const int);
43+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::pointer, Ptr);
44+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::difference_type, std::ptrdiff_t);
45+
#if TEST_STD_VER >= 11
46+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>, long*);
47+
#else
48+
ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>::other, long*);
49+
#endif
50+
}
51+
}

0 commit comments

Comments
 (0)