xref: /aosp_15_r20/external/pigweed/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/memory.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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