(root)/
gcc-13.2.0/
libstdc++-v3/
testsuite/
20_util/
to_address/
lwg3545.cc
// { dg-options "-std=gnu++20" }
// { dg-do compile { target c++20 } }

#include <memory>

template<typename T, bool> struct nttp_ptr
{
  T* operator->() const { return nullptr; }
};

// This gives an error in C++20, which the LWG 3545 resolution should fix:
auto x = std::to_address( nttp_ptr<int, true>() );

template<typename T>
struct clever_ptr
{
  static T obj;
  constexpr T* operator->() const { return &obj; }
};

// pointer_traits specialization is valid, but to_address uses operator->
static_assert( std::to_address(clever_ptr<char>{}) == &clever_ptr<char>::obj );

int the_int;

template<>
struct std::pointer_traits<clever_ptr<int>>
{
  using element_type = int;
  using difference_type = std::ptrdiff_t;
  using pointer = clever_ptr<int>;

  static constexpr int* to_address(pointer p) { return &the_int; }
};

// Uses pointer_traits<clever_ptr<int>>::to_address
static_assert( std::to_address(clever_ptr<int>{}) == &the_int );