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