[libcxx-commits] [libcxx] [libc++] Refactor tests for std::pointer_traits (PR #66645)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 18 06:36:46 PDT 2023
https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/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.
>From 91922f54badbe174ad5d15ceb7418f75dd260bbe Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 18 Sep 2023 08:51:04 -0400
Subject: [PATCH] [libc++] Refactor tests for std::pointer_traits
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.
---
.../pointer_to.pass.cpp | 41 +--
...s.cpp => difference_type.compile.pass.cpp} | 17 +-
...pass.cpp => element_type.compile.pass.cpp} | 18 +-
.../lwg3545.compile.pass.cpp | 73 +++++
.../pointer.compile.pass.cpp | 25 ++
...ebind.pass.cpp => rebind.compile.pass.cpp} | 32 +-
...er_to.pass.cpp => ptr.pointer_to.pass.cpp} | 13 +-
.../pointer.traits/ptr.types.compile.pass.cpp | 50 +++
.../pointer.traits/types.compile.pass.cpp | 289 ------------------
9 files changed, 207 insertions(+), 351 deletions(-)
rename libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/{difference_type.pass.cpp => difference_type.compile.pass.cpp} (59%)
rename libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/{element_type.pass.cpp => element_type.compile.pass.cpp} (59%)
create mode 100644 libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/lwg3545.compile.pass.cpp
create mode 100644 libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/pointer.compile.pass.cpp
rename libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/{rebind.pass.cpp => rebind.compile.pass.cpp} (50%)
rename libcxx/test/std/utilities/memory/pointer.traits/{pointer_to.pass.cpp => ptr.pointer_to.pass.cpp} (71%)
create mode 100644 libcxx/test/std/utilities/memory/pointer.traits/ptr.types.compile.pass.cpp
delete mode 100644 libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
index 62ea10cccc249bd..e4c62f3d3df5cf6 100644
--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
@@ -22,32 +22,33 @@
#include "test_macros.h"
template <class T>
-struct A
-{
+struct A {
private:
- struct nat {};
+ struct nat {};
+
public:
- typedef T element_type;
- element_type* t_;
+ typedef T element_type;
+ element_type* t_;
- A(element_type* t) : t_(t) {}
+ A(element_type* t) : t_(t) {}
- static A pointer_to(typename std::conditional<std::is_void<element_type>::value,
- nat, element_type>::type& et)
- {return A(&et);}
+ static A pointer_to(typename std::conditional<std::is_void<element_type>::value, nat, element_type>::type& et) {
+ return A(&et);
+ }
};
-int main(int, char**)
-{
- {
- int i = 0;
- static_assert((std::is_same<A<int>, decltype(std::pointer_traits<A<int> >::pointer_to(i))>::value), "");
- A<int> a = std::pointer_traits<A<int> >::pointer_to(i);
- assert(a.t_ == &i);
- }
- {
- (std::pointer_traits<A<void> >::element_type)0;
- }
+template <class Pointer>
+void test() {
+ typename Pointer::element_type obj;
+ static_assert(std::is_same<Pointer, decltype(std::pointer_traits<Pointer>::pointer_to(obj))>::value, "");
+ Pointer p = std::pointer_traits<Pointer>::pointer_to(obj);
+ assert(p.t_ == &obj);
+}
+
+int main(int, char**) {
+ test<A<int> >();
+ test<A<long> >();
+ { (std::pointer_traits<A<void> >::element_type)0; }
return 0;
}
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.compile.pass.cpp
similarity index 59%
rename from libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp
rename to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.compile.pass.cpp
index d4d763c69eaeca8..f5fd27cffba84f0 100644
--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.compile.pass.cpp
@@ -52,16 +52,11 @@ struct F {
typedef int difference_type;
};
-int main(int, char**)
-{
- static_assert((std::is_same<std::pointer_traits<A>::difference_type, char>::value), "");
- static_assert((std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value), "");
- static_assert((std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value), "");
- static_assert((std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value), "");
- static_assert((std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value), "");
+static_assert(std::is_same<std::pointer_traits<A>::difference_type, char>::value, "");
+static_assert(std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value, "");
+static_assert(std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value, "");
#if TEST_STD_VER >= 11
- static_assert((std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value), "");
+static_assert(std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value, "");
#endif
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.compile.pass.cpp
similarity index 59%
rename from libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp
rename to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.compile.pass.cpp
index c0efdeab0b31bdb..21ce7e579ad4317 100644
--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.compile.pass.cpp
@@ -53,17 +53,11 @@ struct F {
typedef int element_type;
};
-int main(int, char**)
-{
- static_assert((std::is_same<std::pointer_traits<A>::element_type, char>::value), "");
- static_assert((std::is_same<std::pointer_traits<B<int> >::element_type, char>::value), "");
- static_assert((std::is_same<std::pointer_traits<C<int> >::element_type, int>::value), "");
- static_assert((std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value), "");
- static_assert((std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value), "");
+static_assert(std::is_same<std::pointer_traits<A>::element_type, char>::value, "");
+static_assert(std::is_same<std::pointer_traits<B<int> >::element_type, char>::value, "");
+static_assert(std::is_same<std::pointer_traits<C<int> >::element_type, int>::value, "");
+static_assert(std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value, "");
+static_assert(std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value, "");
#if TEST_STD_VER >= 11
- static_assert((std::is_same<std::pointer_traits<F<double>>::element_type, double>::value), "");
+static_assert(std::is_same<std::pointer_traits<F<double>>::element_type, double>::value, "");
#endif
-
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/lwg3545.compile.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/lwg3545.compile.pass.cpp
new file mode 100644
index 000000000000000..21b021ef6cd0807
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/lwg3545.compile.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test that `std::pointer_traits` is empty when the pointer type has
+// no element_type typedef. See http://wg21.link/LWG3545 for details.
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+template <typename... Ts>
+struct VoidifyImpl {
+ using type = void;
+};
+
+template <typename... Ts>
+using Voidify = typename VoidifyImpl<Ts...>::type;
+
+template <class T, class = void>
+struct HasElementType : std::false_type {};
+
+template <class T>
+struct HasElementType<T, Voidify<typename std::pointer_traits<T>::element_type> > : std::true_type {};
+
+template <class T, class = void>
+struct HasPointerType : std::false_type {};
+
+template <class T>
+struct HasPointerType<T, Voidify<typename std::pointer_traits<T>::pointer> > : std::true_type {};
+
+template <class T, class = void>
+struct HasDifferenceType : std::false_type {};
+
+template <class T>
+struct HasDifferenceType<T, Voidify<typename std::pointer_traits<T>::difference_type> > : std::true_type {};
+
+template <class T, class U, class = void>
+struct HasRebind : std::false_type {};
+
+#if TEST_STD_VER >= 11
+template <class T, class U>
+struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U> > > : std::true_type {};
+#else
+template <class T, class U>
+struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U>::other> > : std::true_type {};
+#endif
+
+template <class T, class = void>
+struct HasPointerTo : std::false_type {};
+
+template <class T>
+struct HasPointerTo<
+ T,
+ Voidify<decltype(std::pointer_traits<T>::pointer_to(
+ std::declval<typename std::add_lvalue_reference<typename std::pointer_traits<T>::element_type>::type>()))> >
+ : std::true_type {};
+
+struct NotAPtr {};
+
+static_assert(!HasElementType<NotAPtr>::value, "");
+static_assert(!HasPointerType<NotAPtr>::value, "");
+static_assert(!HasDifferenceType<NotAPtr>::value, "");
+static_assert(!HasRebind<NotAPtr, long>::value, "");
+static_assert(!HasPointerTo<NotAPtr>::value, "");
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/pointer.compile.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/pointer.compile.pass.cpp
new file mode 100644
index 000000000000000..66eb660ef4efbcf
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/pointer.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class Ptr>
+// struct pointer_traits
+// {
+// typedef <details> pointer;
+// ...
+// };
+
+#include <memory>
+#include <type_traits>
+
+struct Foo {
+ using element_type = int;
+};
+
+static_assert(std::is_same<std::pointer_traits<Foo>::pointer, Foo>::value, "");
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.compile.pass.cpp
similarity index 50%
rename from libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp
rename to libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.compile.pass.cpp
index a79f3391664620d..17d952c3af3beda 100644
--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp
+++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.compile.pass.cpp
@@ -81,26 +81,22 @@ struct G
#endif
-int main(int, char**)
-{
#if TEST_STD_VER >= 11
- static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value), "");
- static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value), "");
- static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value), "");
- static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value), "");
- static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value), "");
- static_assert((std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value), "");
+static_assert(std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value, "");
+static_assert(std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value, "");
+static_assert(std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value, "");
+static_assert(std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value, "");
+static_assert(std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value, "");
+static_assert(std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value, "");
#if TEST_STD_VER >= 14
- static_assert((std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value), "");
-#endif
-#else // TEST_STD_VER < 11
- static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value), "");
- static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value), "");
- static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value), "");
- static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value), "");
- static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value), "");
+static_assert(std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value, "");
#endif
- return 0;
-}
+#else // TEST_STD_VER < 11
+static_assert(std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value, "");
+static_assert(std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value, "");
+static_assert(std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value, "");
+static_assert(std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value, "");
+static_assert(std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value, "");
+#endif
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/ptr.pointer_to.pass.cpp
similarity index 71%
rename from libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
rename to libcxx/test/std/utilities/memory/pointer.traits/ptr.pointer_to.pass.cpp
index c4b5ca1a03263c9..104d507330c0b76 100644
--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
+++ b/libcxx/test/std/utilities/memory/pointer.traits/ptr.pointer_to.pass.cpp
@@ -11,7 +11,7 @@
// template <class T>
// struct pointer_traits<T*>
// {
-// static pointer pointer_to(<details>); // constexpr in C++20
+// static pointer pointer_to(<details>) noexcept; // constexpr in C++20
// ...
// };
@@ -23,14 +23,25 @@
TEST_CONSTEXPR_CXX20 bool test()
{
+ // pointer_traits<T*>
{
int i = 0;
static_assert(std::is_same<decltype(std::pointer_traits<int*>::pointer_to(i)), int*>::value, "");
+ ASSERT_NOEXCEPT(std::pointer_traits<int*>::pointer_to(i));
assert(std::pointer_traits<int*>::pointer_to(i) == &i);
}
+ // pointer_traits<const T*>
+ {
+ int const i = 0;
+ static_assert(std::is_same<decltype(std::pointer_traits<const int*>::pointer_to(i)), const int*>::value, "");
+ ASSERT_NOEXCEPT(std::pointer_traits<const int*>::pointer_to(i));
+ assert(std::pointer_traits<const int*>::pointer_to(i) == &i);
+ }
+ // pointer_traits<const T*> with a non-const argument
{
int i = 0;
static_assert(std::is_same<decltype(std::pointer_traits<const int*>::pointer_to(i)), const int*>::value, "");
+ ASSERT_NOEXCEPT(std::pointer_traits<const int*>::pointer_to(i));
assert(std::pointer_traits<const int*>::pointer_to(i) == &i);
}
return true;
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/ptr.types.compile.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/ptr.types.compile.pass.cpp
new file mode 100644
index 000000000000000..134da01b7007dfc
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/pointer.traits/ptr.types.compile.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class T>
+// struct pointer_traits<T*>
+// {
+// using pointer = T*;
+// using element_type = T;
+// using difference_type = ptrdiff_t;
+// template <class U> using rebind = U*;
+// };
+
+#include <memory>
+
+#include "test_macros.h"
+
+void f() {
+ {
+ using Ptr = int*;
+
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::element_type, int);
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::pointer, Ptr);
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
+#if TEST_STD_VER >= 11
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>, long*);
+#else
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>::other, long*);
+#endif
+ }
+
+ {
+ using Ptr = const int*;
+
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::element_type, const int);
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::pointer, Ptr);
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
+#if TEST_STD_VER >= 11
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>, long*);
+#else
+ ASSERT_SAME_TYPE(std::pointer_traits<Ptr>::rebind<long>::other, long*);
+#endif
+ }
+}
diff --git a/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
deleted file mode 100644
index 19461508ca0f328..000000000000000
--- a/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// template <class Ptr>
-// struct pointer_traits
-// {
-// <details>
-// };
-//
-// template <class T>
-// struct pointer_traits<T*>
-// {
-// using pointer = T*;
-// using element_type = T;
-// using difference_type = ptrdiff_t;
-// template <class U> using rebind = U*;
-// static constexpr pointer pointer_to(<details>) noexcept;
-// ...
-// };
-
-#include <memory>
-#include <type_traits>
-
-#include "test_macros.h"
-
-template <typename... Ts>
-struct VoidifyImpl {
- using type = void;
-};
-
-template <typename... Ts>
-using Voidify = typename VoidifyImpl<Ts...>::type;
-
-template <class T, class = void>
-struct HasElementType : std::false_type {};
-
-template <class T>
-struct HasElementType<T, Voidify<typename std::pointer_traits<T>::element_type> > : std::true_type {};
-
-template <class T, class = void>
-struct HasPointerType : std::false_type {};
-
-template <class T>
-struct HasPointerType<T, Voidify<typename std::pointer_traits<T>::pointer> > : std::true_type {};
-
-template <class T, class = void>
-struct HasDifferenceType : std::false_type {};
-
-template <class T>
-struct HasDifferenceType<T, Voidify<typename std::pointer_traits<T>::difference_type> > : std::true_type {};
-
-template <class T, class U, class = void>
-struct HasRebind : std::false_type {};
-
-template <class T, class U>
-struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U> > > : std::true_type {};
-
-template <class T, class = void>
-struct HasPointerTo : std::false_type {};
-
-template <class T>
-struct HasPointerTo<
- T,
- Voidify<decltype(std::pointer_traits<T>::pointer_to(
- std::declval<typename std::add_lvalue_reference<typename std::pointer_traits<T>::element_type>::type>()))> >
- : std::true_type {};
-
-struct Irrelevant;
-
-struct NotAPtr {};
-
-struct LongPtr {};
-
-int global_int;
-
-template <class T, class Arg>
-struct TemplatedPtr;
-
-struct PtrWithElementType {
- using element_type = int;
- template <class U>
-#if TEST_STD_VER >= 11
- using rebind = TemplatedPtr<U, Irrelevant>;
-#else
- struct rebind {
- using other = TemplatedPtr<U, Irrelevant>;
- };
-#endif
- static TEST_CONSTEXPR_CXX14 PtrWithElementType pointer_to(element_type&) { return {&global_int}; }
- int* ptr;
-};
-
-template <class T, class Arg>
-struct TemplatedPtr {
- template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
-#if TEST_STD_VER >= 11
- using rebind = LongPtr;
-#else
- struct rebind {
- using other = LongPtr;
- };
-#endif
- static TEST_CONSTEXPR_CXX14 TemplatedPtr pointer_to(T&) { return {&global_int}; }
-
- T* ptr;
-};
-
-template <class T, class Arg>
-struct TemplatedPtrWithElementType {
- using element_type = int;
-#if TEST_STD_VER >= 11
- template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
- using rebind = LongPtr;
-#else
- template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
- struct rebind {
- using other = LongPtr;
- };
-#endif
- static TEST_CONSTEXPR_CXX14 TemplatedPtrWithElementType pointer_to(element_type&) { return {&global_int}; }
-
- element_type* ptr;
-};
-
-int main() {
- {
- using Ptr = NotAPtr;
- static_assert(!HasElementType<Ptr>::value, "");
- static_assert(!HasPointerType<Ptr>::value, "");
- static_assert(!HasDifferenceType<Ptr>::value, "");
- static_assert(!HasRebind<Ptr, long>::value, "");
- static_assert(!HasPointerTo<Ptr>::value, "");
- }
-
- {
- using Ptr = int*;
-
- static_assert(HasElementType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
-
- static_assert(HasPointerType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
-
- static_assert(HasDifferenceType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
-
- static_assert(HasRebind<Ptr, long>::value, "");
-#if TEST_STD_VER >= 11
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, long*);
-#else
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, long*);
-#endif
-
- static_assert(HasPointerTo<Ptr>::value, "");
- int variable = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(variable)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(variable) == &variable, "");
-#endif
- }
-
- {
- using Ptr = const int*;
-
- static_assert(HasElementType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, const int);
-
- static_assert(HasPointerType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
-
- static_assert(HasDifferenceType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
-
- static_assert(HasRebind<Ptr, long>::value, "");
-#if TEST_STD_VER >= 11
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, long*);
-#else
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, long*);
-#endif
-
- static_assert(HasPointerTo<Ptr>::value, "");
- const int const_variable = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(const_variable)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(const_variable) == &const_variable, "");
-#endif
- int variable = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(variable)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(variable) == &variable, "");
-#endif
- }
-
- {
- using Ptr = PtrWithElementType;
-
- static_assert(HasElementType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
-
- static_assert(HasPointerType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
-
- static_assert(HasDifferenceType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
-
- static_assert(HasRebind<Ptr, long>::value, "");
-#if TEST_STD_VER >= 11
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, TemplatedPtr<long, Irrelevant>);
-#else
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, TemplatedPtr<long, Irrelevant>);
-#endif
-
- static_assert(HasPointerTo<Ptr>::value, "");
- int ignored = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
-#endif
- }
-
- {
- using Ptr = TemplatedPtr<int, Irrelevant>;
-
- static_assert(HasElementType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
-
- static_assert(HasPointerType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
-
- static_assert(HasDifferenceType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
-
- static_assert(HasRebind<Ptr, long>::value, "");
- static_assert(HasRebind<Ptr, long long>::value, "");
-#if TEST_STD_VER >= 11
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, LongPtr);
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>, TemplatedPtr<long long, Irrelevant>);
-#else
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, LongPtr);
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>::other, TemplatedPtr<long long, Irrelevant>);
-#endif
-
- static_assert(HasPointerTo<Ptr>::value, "");
- int ignored = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
-#endif
- }
-
- {
- using Ptr = TemplatedPtrWithElementType<Irrelevant, Irrelevant>;
-
- static_assert(HasElementType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
-
- static_assert(HasPointerType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
-
- static_assert(HasDifferenceType<Ptr>::value, "");
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
-
- static_assert(HasRebind<Ptr, long>::value, "");
- static_assert(HasRebind<Ptr, long long>::value, "");
-#if TEST_STD_VER >= 11
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, LongPtr);
- ASSERT_SAME_TYPE(
- typename std::pointer_traits<Ptr>::rebind<long long>, TemplatedPtrWithElementType<long long, Irrelevant>);
-#else
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, LongPtr);
- ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>::other,
- TemplatedPtrWithElementType<long long, Irrelevant>);
-#endif
-
- static_assert(HasPointerTo<Ptr>::value, "");
- int ignored = 0;
- ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
-#if TEST_STD_VER >= 20
- static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
-#endif
- }
-}
More information about the libcxx-commits
mailing list