• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_MEMORY_H_
6 #define LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_MEMORY_H_
7 
8 #include <memory>
9 
10 #include "version.h"
11 
12 namespace cpp17 {
13 
14 #if defined(__cpp_lib_addressof_constexpr) && __cpp_lib_addressof_constexpr >= 201603L && \
15     !defined(LIB_STDCOMPAT_USE_POLYFILLS)
16 
17 using std::addressof;
18 
19 #else  // Provide constexpr polyfill for addressof.
20 
21 template <typename T>
22 constexpr T* addressof(T& arg) noexcept {
23   return __builtin_addressof(arg);
24 }
25 
26 template <typename T>
27 const T* addressof(const T&&) = delete;
28 
29 #endif  // __cpp_lib_addressof_constexpr >= 201603L && !defined(LIB_STDCOMPAT_USE_POLYFILLS)
30 
31 }  // namespace cpp17
32 
33 namespace cpp20 {
34 
35 #if defined(__cpp_lib_to_address) && __cpp_lib_to_address >= 201711L && \
36     !defined(LIB_STDCOMPAT_USE_POLYFILLS)
37 
38 using std::to_address;
39 
40 #else  // Provide to_address polyfill.
41 
42 template <typename T>
43 constexpr T* to_address(T* pointer) noexcept {
44   static_assert(!std::is_function<T>::value, "Cannot pass function pointers to std::to_address()");
45   return pointer;
46 }
47 
48 // TODO(fxbug.dev/70523): This std::pointer_traits stuff is only to be bug-compatible with the
49 // standard library implementations; switch back to auto when the linked bug is resolved.
50 template <typename T>
51 constexpr typename std::pointer_traits<T>::element_type* to_address(const T& pointer) noexcept {
52   static_assert(
53       std::is_same<decltype(pointer.operator->()),
54                    typename std::pointer_traits<T>::element_type*>::value,
55       "For compatibility with libc++ and libstdc++, operator->() must return "
56       "typename std::pointer_traits<T>::element_type*. 'Chaining' operator->() in "
57       "cpp20::to_address() will not be permitted until https://fxbug.dev/70523 is resolved.");
58 
59   return to_address(pointer.operator->());
60 }
61 
62 #endif  // __cpp_lib_to_address >= 201711L && !defined(LIB_STDCOMPAT_USE_POLYFILLS)
63 
64 }  // namespace cpp20
65 
66 #endif  // LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_MEMORY_H_
67