to_address.pass.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. // <memory>
  9. // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
  10. // template <class T> constexpr T* to_address(T* p) noexcept;
  11. // template <class Ptr> auto to_address(const Ptr& p) noexcept;
  12. #include <memory>
  13. #include <cassert>
  14. #include "test_macros.h"
  15. class P1
  16. {
  17. public:
  18. using element_type = int;
  19. explicit P1(int* p)
  20. : p_(p) { }
  21. int* operator->() const noexcept
  22. { return p_; }
  23. private:
  24. int* p_;
  25. };
  26. class P2
  27. {
  28. public:
  29. using element_type = int;
  30. explicit P2(int* p)
  31. : p_(p) { }
  32. P1 operator->() const noexcept
  33. { return p_; }
  34. private:
  35. P1 p_;
  36. };
  37. class P3
  38. {
  39. public:
  40. explicit P3(int* p)
  41. : p_(p) { }
  42. int* get() const noexcept
  43. { return p_; }
  44. private:
  45. int* p_;
  46. };
  47. namespace std
  48. {
  49. template<>
  50. struct pointer_traits<::P3>
  51. {
  52. static int* to_address(const ::P3& p) noexcept
  53. { return p.get(); }
  54. };
  55. }
  56. class P4
  57. {
  58. public:
  59. explicit P4(int* p)
  60. : p_(p) { }
  61. int* operator->() const noexcept
  62. { return nullptr; }
  63. int* get() const noexcept
  64. { return p_; }
  65. private:
  66. int* p_;
  67. };
  68. namespace std
  69. {
  70. template<>
  71. struct pointer_traits<::P4>
  72. {
  73. static int* to_address(const ::P4& p) noexcept
  74. { return p.get(); }
  75. };
  76. }
  77. int n = 0;
  78. static_assert(std::to_address(&n) == &n);
  79. int main(int, char**)
  80. {
  81. int i = 0;
  82. ASSERT_NOEXCEPT(std::to_address(&i));
  83. assert(std::to_address(&i) == &i);
  84. P1 p1(&i);
  85. ASSERT_NOEXCEPT(std::to_address(p1));
  86. assert(std::to_address(p1) == &i);
  87. P2 p2(&i);
  88. ASSERT_NOEXCEPT(std::to_address(p2));
  89. assert(std::to_address(p2) == &i);
  90. P3 p3(&i);
  91. ASSERT_NOEXCEPT(std::to_address(p3));
  92. assert(std::to_address(p3) == &i);
  93. P4 p4(&i);
  94. ASSERT_NOEXCEPT(std::to_address(p4));
  95. assert(std::to_address(p4) == &i);
  96. return 0;
  97. }