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_MEMORY_H_ 6 #define LIB_STDCOMPAT_MEMORY_H_ 7 8 #include <memory> 9 10 #include "version.h" 11 12 namespace cpp17 { 13 14 using std::addressof; 15 16 } // namespace cpp17 17 18 namespace cpp20 { 19 20 #if defined(__cpp_lib_to_address) && __cpp_lib_to_address >= 201711L && \ 21 !defined(LIB_STDCOMPAT_USE_POLYFILLS) 22 23 using std::to_address; 24 25 #else // Provide to_address polyfill. 26 27 template <typename T> 28 constexpr T* to_address(T* pointer) noexcept { 29 static_assert(!std::is_function<T>::value, "Cannot pass function pointers to std::to_address()"); 30 return pointer; 31 } 32 33 // TODO(https://fxbug.dev/42149777): This std::pointer_traits stuff is only to be bug-compatible 34 // with the standard library implementations; switch back to auto when the linked bug is resolved. 35 template <typename T> 36 constexpr typename std::pointer_traits<T>::element_type* to_address(const T& pointer) noexcept { 37 static_assert( 38 std::is_same<decltype(pointer.operator->()), 39 typename std::pointer_traits<T>::element_type*>::value, 40 "For compatibility with libc++ and libstdc++, operator->() must return " 41 "typename std::pointer_traits<T>::element_type*. 'Chaining' operator->() in " 42 "cpp20::to_address() will not be permitted until https://fxbug.dev/42149777 is resolved."); 43 44 return to_address(pointer.operator->()); 45 } 46 47 #endif // __cpp_lib_to_address >= 201711L && !defined(LIB_STDCOMPAT_USE_POLYFILLS) 48 49 } // namespace cpp20 50 51 #endif // LIB_STDCOMPAT_MEMORY_H_ 52