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, ""); 74