Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/move_only_function.h
1 // Implementation of std::move_only_function -*- C++ -*- 2 3 // Copyright The GNU Toolchain Authors. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/bits/move_only_function.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{functional} 28 */ 29 30 #ifndef _GLIBCXX_MOVE_ONLY_FUNCTION_H 31 #define _GLIBCXX_MOVE_ONLY_FUNCTION_H 1 32 33 #ifdef _GLIBCXX_SYSHDR 34 #pragma GCC system_header 35 #endif 36 37 #include <bits/version.h> 38 39 #ifdef __glibcxx_move_only_function // C++ >= 23 && HOSTED 40 41 #include <bits/invoke.h> 42 #include <bits/utility.h> 43 44 namespace std _GLIBCXX_VISIBILITY(default) 45 { 46 _GLIBCXX_BEGIN_NAMESPACE_VERSION 47 48 template<typename... _Signature> 49 class move_only_function; // not defined 50 51 /// @cond undocumented 52 class _Mofunc_base 53 { 54 protected: 55 _Mofunc_base() noexcept 56 : _M_manage(_S_empty) 57 { } 58 59 _Mofunc_base(_Mofunc_base&& __x) noexcept 60 { 61 _M_manage = std::__exchange(__x._M_manage, _S_empty); 62 _M_manage(_M_storage, &__x._M_storage); 63 } 64 65 template<typename _Tp, typename... _Args> 66 static constexpr bool 67 _S_nothrow_init() noexcept 68 { 69 if constexpr (__stored_locally<_Tp>) 70 return is_nothrow_constructible_v<_Tp, _Args...>; 71 return false; 72 } 73 74 template<typename _Tp, typename... _Args> 75 void 76 _M_init(_Args&&... __args) noexcept(_S_nothrow_init<_Tp, _Args...>()) 77 { 78 if constexpr (__stored_locally<_Tp>) 79 ::new (_M_storage._M_addr()) _Tp(std::forward<_Args>(__args)...); 80 else 81 _M_storage._M_p = new _Tp(std::forward<_Args>(__args)...); 82 83 _M_manage = &_S_manage<_Tp>; 84 } 85 86 _Mofunc_base& 87 operator=(_Mofunc_base&& __x) noexcept 88 { 89 _M_manage(_M_storage, nullptr); 90 _M_manage = std::__exchange(__x._M_manage, _S_empty); 91 _M_manage(_M_storage, &__x._M_storage); 92 return *this; 93 } 94 95 _Mofunc_base& 96 operator=(nullptr_t) noexcept 97 { 98 _M_manage(_M_storage, nullptr); 99 _M_manage = _S_empty; 100 return *this; 101 } 102 103 ~_Mofunc_base() { _M_manage(_M_storage, nullptr); } 104 105 void 106 swap(_Mofunc_base& __x) noexcept 107 { 108 // Order of operations here is more efficient if __x is empty. 109 _Storage __s; 110 __x._M_manage(__s, &__x._M_storage); 111 _M_manage(__x._M_storage, &_M_storage); 112 __x._M_manage(_M_storage, &__s); 113 std::swap(_M_manage, __x._M_manage); 114 } 115 116 template<typename _Tp, typename _Self> 117 static _Tp* 118 _S_access(_Self* __self) noexcept 119 { 120 if constexpr (__stored_locally<remove_const_t<_Tp>>) 121 return static_cast<_Tp*>(__self->_M_storage._M_addr()); 122 else 123 return static_cast<_Tp*>(__self->_M_storage._M_p); 124 } 125 126 private: 127 struct _Storage 128 { 129 void* _M_addr() noexcept { return &_M_bytes[0]; } 130 const void* _M_addr() const noexcept { return &_M_bytes[0]; } 131 132 // We want to have enough space to store a simple delegate type. 133 struct _Delegate { void (_Storage::*__pfm)(); _Storage* __obj; }; 134 union { 135 void* _M_p; 136 alignas(_Delegate) alignas(void(*)()) 137 unsigned char _M_bytes[sizeof(_Delegate)]; 138 }; 139 }; 140 141 template<typename _Tp> 142 static constexpr bool __stored_locally 143 = sizeof(_Tp) <= sizeof(_Storage) && alignof(_Tp) <= alignof(_Storage) 144 && is_nothrow_move_constructible_v<_Tp>; 145 146 // A function that either destroys the target object stored in __target, 147 // or moves the target object from *__src to __target. 148 using _Manager = void (*)(_Storage& __target, _Storage* __src) noexcept; 149 150 // The no-op manager function for objects with no target. 151 static void _S_empty(_Storage&, _Storage*) noexcept { } 152 153 // The real manager function for a target object of type _Tp. 154 template<typename _Tp> 155 static void 156 _S_manage(_Storage& __target, _Storage* __src) noexcept 157 { 158 if constexpr (__stored_locally<_Tp>) 159 { 160 if (__src) 161 { 162 _Tp* __rval = static_cast<_Tp*>(__src->_M_addr()); 163 ::new (__target._M_addr()) _Tp(std::move(*__rval)); 164 __rval->~_Tp(); 165 } 166 else 167 static_cast<_Tp*>(__target._M_addr())->~_Tp(); 168 } 169 else 170 { 171 if (__src) 172 __target._M_p = __src->_M_p; 173 else 174 delete static_cast<_Tp*>(__target._M_p); 175 } 176 } 177 178 _Storage _M_storage; 179 _Manager _M_manage; 180 }; 181 182 template<typename _Tp> 183 inline constexpr bool __is_move_only_function_v = false; 184 template<typename _Tp> 185 constexpr bool __is_move_only_function_v<move_only_function<_Tp>> = true; 186 /// @endcond 187 188 namespace __detail::__variant 189 { 190 template<typename> struct _Never_valueless_alt; // see <variant> 191 192 // Provide the strong exception-safety guarantee when emplacing a 193 // move_only_function into a variant. 194 template<typename... _Signature> 195 struct _Never_valueless_alt<std::move_only_function<_Signature...>> 196 : true_type 197 { }; 198 } // namespace __detail::__variant 199 200 _GLIBCXX_END_NAMESPACE_VERSION 201 } // namespace std 202 203 #include "mofunc_impl.h" 204 #define _GLIBCXX_MOF_CV const 205 #include "mofunc_impl.h" 206 #define _GLIBCXX_MOF_REF & 207 #include "mofunc_impl.h" 208 #define _GLIBCXX_MOF_REF && 209 #include "mofunc_impl.h" 210 #define _GLIBCXX_MOF_CV const 211 #define _GLIBCXX_MOF_REF & 212 #include "mofunc_impl.h" 213 #define _GLIBCXX_MOF_CV const 214 #define _GLIBCXX_MOF_REF && 215 #include "mofunc_impl.h" 216 217 #endif // __glibcxx_move_only_function 218 #endif // _GLIBCXX_MOVE_ONLY_FUNCTION_H