Home | History | Annotate | Download | only in pointer.conversion
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // <memory>
     11 
     12 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
     13 
     14 // template <class T> constexpr T* to_address(T* p) noexcept;
     15 // template <class Ptr> auto to_address(const Ptr& p) noexcept;
     16 
     17 #include <memory>
     18 #include <cassert>
     19 #include "test_macros.h"
     20 
     21 class P1
     22 {
     23 public:
     24     using element_type = int;
     25 
     26     explicit P1(int* p)
     27     : p_(p) { }
     28 
     29     int* operator->() const noexcept
     30     { return p_; }
     31 
     32 private:
     33     int* p_;
     34 };
     35 
     36 class P2
     37 {
     38 public:
     39     using element_type = int;
     40 
     41     explicit P2(int* p)
     42     : p_(p) { }
     43 
     44     P1 operator->() const noexcept
     45     { return p_; }
     46 
     47 private:
     48     P1 p_;
     49 };
     50 
     51 class P3
     52 {
     53 public:
     54     explicit P3(int* p)
     55     : p_(p) { }
     56 
     57     int* get() const noexcept
     58     { return p_; }
     59 
     60 private:
     61     int* p_;
     62 };
     63 
     64 namespace std
     65 {
     66 template<>
     67 struct pointer_traits<::P3>
     68 {
     69     static int* to_address(const ::P3& p) noexcept
     70     { return p.get(); }
     71 };
     72 }
     73 
     74 class P4
     75 {
     76 public:
     77     explicit P4(int* p)
     78     : p_(p) { }
     79 
     80     int* operator->() const noexcept
     81     { return nullptr; }
     82 
     83     int* get() const noexcept
     84     { return p_; }
     85 
     86 private:
     87     int* p_;
     88 };
     89 
     90 namespace std
     91 {
     92 template<>
     93 struct pointer_traits<::P4>
     94 {
     95     static int* to_address(const ::P4& p) noexcept
     96     { return p.get(); }
     97 };
     98 }
     99 
    100 int n = 0;
    101 static_assert(std::to_address(&n) == &n);
    102 
    103 int main()
    104 {
    105     int i = 0;
    106     ASSERT_NOEXCEPT(std::to_address(&i));
    107     assert(std::to_address(&i) == &i);
    108     P1 p1(&i);
    109     ASSERT_NOEXCEPT(std::to_address(p1));
    110     assert(std::to_address(p1) == &i);
    111     P2 p2(&i);
    112     ASSERT_NOEXCEPT(std::to_address(p2));
    113     assert(std::to_address(p2) == &i);
    114     P3 p3(&i);
    115     ASSERT_NOEXCEPT(std::to_address(p3));
    116     assert(std::to_address(p3) == &i);
    117     P4 p4(&i);
    118     ASSERT_NOEXCEPT(std::to_address(p4));
    119     assert(std::to_address(p4) == &i);
    120 }
    121