File: lwg3545.cc

package info (click to toggle)
gcc-arm-none-eabi 15%3A12.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 959,712 kB
  • sloc: cpp: 3,275,382; ansic: 2,061,766; ada: 840,956; f90: 208,513; makefile: 76,132; asm: 73,433; xml: 50,448; exp: 34,146; sh: 32,436; objc: 15,637; fortran: 14,012; python: 11,991; pascal: 6,787; awk: 4,779; perl: 3,054; yacc: 338; ml: 285; lex: 201; haskell: 122
file content (101 lines) | stat: -rw-r--r-- 3,498 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// { dg-do compile { target c++11 } }

// LWG 3545. std::pointer_traits should be SFINAE-friendly

#include <memory>

using std::is_same;

template<typename> using void_t = void;

template<template<typename> class Probe, typename T, typename = void>
  struct has_member
  : std::false_type { };

template<template<typename> class Probe, typename T>
  struct has_member<Probe, T, void_t<Probe<T>>>
  : std::true_type { };

template<typename T>
  using element_type = typename T::element_type;
template<typename T>
  using pointer = typename T::pointer;
template<typename T>
  using difference_type = typename T::difference_type;
template<typename T>
  using rebind = typename T::template rebind<short>;
template<typename T>
  using pointer_to = decltype(T::pointer_to(std::declval<element_type<T>&>()));

using invalid = std::pointer_traits<int>;
invalid i; // invalid instantiation is not ill-formed

static_assert( !has_member<element_type, invalid>::value, "" );
static_assert( !has_member<pointer, invalid>::value, "" );
static_assert( !has_member<difference_type, invalid>::value, "" );
static_assert( !has_member<rebind, invalid>::value, "" );
static_assert( !has_member<pointer_to, invalid>::value, "" );

struct I
{
  // These members should not be used by pointer_traits<P>::pointer.
  using pointer = int;
  using difference_type = int;
  template<typename> using rebind = int;
};

using invalid2 = std::pointer_traits<I>;

static_assert( !has_member<element_type, invalid2>::value, "" );
static_assert( !has_member<pointer, invalid2>::value, "" );
static_assert( !has_member<difference_type, invalid2>::value, "" );
static_assert( !has_member<rebind, invalid2>::value, "" );
static_assert( !has_member<pointer_to, invalid2>::value, "" );

struct P
{
  using element_type = long;
  struct pointer { }; // should not be used by pointer_traits<P>::pointer

  P pointer_to(long&) const; // not static, should not be used.
};
using Ptraits = std::pointer_traits<P>;
Ptraits p;

static_assert( is_same<element_type<Ptraits>, long>::value, "" );
static_assert( is_same<pointer<Ptraits>, P>::value, "" );
static_assert( is_same<difference_type<Ptraits>, std::ptrdiff_t>::value, "" );
static_assert( !has_member<rebind, Ptraits>::value, "" );
#if __cplusplus >= 202002L
// pointer_traits<P>::pointer_to(long&) is constrained in C++20 and later.
static_assert( !has_member<pointer_to, Ptraits>::value, "" );
#else
static_assert( is_same<pointer_to<Ptraits>, P>::value, "" );
#endif

struct V { using element_type = const void; };
using Vtraits = std::pointer_traits<V>;
Vtraits v;

static_assert( is_same<element_type<Vtraits>, const void>::value, "" );
static_assert( is_same<pointer<Vtraits>, V>::value, "" );
static_assert( is_same<difference_type<Vtraits>, std::ptrdiff_t>::value, "" );
static_assert( !has_member<rebind, Vtraits>::value, "" );
static_assert( !has_member<pointer_to, Vtraits>::value, "" );

template<typename T>
struct clever_ptr
{
  static T obj;

  static clever_ptr pointer_to(T&) { return {}; }
  constexpr T* operator->() const { return &obj; }
};

using Ctraits = std::pointer_traits<clever_ptr<char>>;

static_assert( is_same<element_type<Ctraits>, char>::value, "" );
static_assert( is_same<pointer<Ctraits>, clever_ptr<char>>::value, "" );
static_assert( is_same<difference_type<Ctraits>, std::ptrdiff_t>::value, "" );
static_assert( is_same<rebind<Ctraits>, clever_ptr<short>>::value, "" );
static_assert( is_same<pointer_to<Ctraits>, clever_ptr<char>>::value, "" );