yum-mirror/VkFFT
git clone https://git.yummers.dev/yum-mirror/VkFFT
ba7001c
master
1//------------------------------------------------------------------------------------------------------------------------------------------------------------- 2// 3// Foundation/NSObject.hpp 4// 5// Copyright 2020-2021 Apple Inc. 6// 7// Licensed under the Apache License, Version 2.0 (the "License"); 8// you may not use this file except in compliance with the License. 9// You may obtain a copy of the License at 10// 11// http://www.apache.org/licenses/LICENSE-2.0 12// 13// Unless required by applicable law or agreed to in writing, software 14// distributed under the License is distributed on an "AS IS" BASIS, 15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16// See the License for the specific language governing permissions and 17// limitations under the License. 18// 19//------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 21#pragma once 22 23//------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 25#include "NSDefines.hpp" 26#include "NSPrivate.hpp" 27#include "NSTypes.hpp" 28 29#include <objc/message.h> 30#include <objc/runtime.h> 31 32#include <type_traits> 33 34//------------------------------------------------------------------------------------------------------------------------------------------------------------- 35 36namespace NS 37{ 38template < class _Class ,class _Base = class Object > 39class Referencing :public _Base 40{ 41public : 42_Class * retain (); 43void release (); 44 45_Class * autorelease (); 46 47UInteger retainCount ()const ; 48}; 49 50template < class _Class ,class _Base = class Object > 51class Copying :public Referencing < _Class ,_Base > 52{ 53public : 54_Class * copy ()const ; 55}; 56 57class Object :public Referencing < Object ,objc_object > 58{ 59public : 60UInteger hash ()const ; 61bool isEqual (const Object * pObject )const ; 62 63class String * description ()const ; 64class String * debugDescription ()const ; 65 66protected : 67friend class Referencing < Object ,objc_object > ; 68 69template < class _Class > 70static _Class * alloc (const char * pClassName ); 71template < class _Class > 72static _Class * alloc (const void * pClass ); 73template < class _Class > 74_Class * init (); 75 76template < class _Dst > 77static _Dst bridgingCast (const void * pObj ); 78static class MethodSignature * methodSignatureForSelector (const void * pObj ,SEL selector ); 79static bool respondsToSelector (const void * pObj ,SEL selector ); 80template < typename _Type > 81static constexpr bool doesRequireMsgSendStret (); 82template < typename _Ret ,typename ..._Args > 83static _Ret sendMessage (const void * pObj ,SEL selector ,_Args ...args ); 84template < typename _Ret ,typename ..._Args > 85static _Ret sendMessageSafe (const void * pObj ,SEL selector ,_Args ...args ); 86 87private : 88Object ()= delete ; 89Object (const Object & )= delete ; 90 ~Object ()= delete ; 91 92Object & operator= (const Object & )= delete ; 93}; 94} 95 96//------------------------------------------------------------------------------------------------------------------------------------------------------------- 97 98template < class _Class ,class _Base /* = Object */ > 99_NS_INLINE _Class * NS ::Referencing < _Class ,_Base > ::retain () 100{ 101return Object ::sendMessage < _Class *> (this ,_NS_PRIVATE_SEL (retain )); 102} 103 104//------------------------------------------------------------------------------------------------------------------------------------------------------------- 105 106template < class _Class ,class _Base /* = Object */ > 107_NS_INLINE voidNS ::Referencing < _Class ,_Base > ::release () 108{ 109Object ::sendMessage < void > (this ,_NS_PRIVATE_SEL (release )); 110} 111 112//------------------------------------------------------------------------------------------------------------------------------------------------------------- 113 114template < class _Class ,class _Base /* = Object */ > 115_NS_INLINE _Class * NS ::Referencing < _Class ,_Base > ::autorelease () 116{ 117return Object ::sendMessage < _Class *> (this ,_NS_PRIVATE_SEL (autorelease )); 118} 119 120//------------------------------------------------------------------------------------------------------------------------------------------------------------- 121 122template < class _Class ,class _Base /* = Object */ > 123_NS_INLINE NS ::UInteger NS ::Referencing < _Class ,_Base > ::retainCount ()const 124{ 125return Object ::sendMessage < UInteger > (this ,_NS_PRIVATE_SEL (retainCount )); 126} 127 128//------------------------------------------------------------------------------------------------------------------------------------------------------------- 129 130template < class _Class ,class _Base /* = Object */ > 131_NS_INLINE _Class * NS ::Copying < _Class ,_Base > ::copy ()const 132{ 133return Object ::sendMessage < _Class *> (this ,_NS_PRIVATE_SEL (copy )); 134} 135 136//------------------------------------------------------------------------------------------------------------------------------------------------------------- 137 138template < class _Dst > 139_NS_INLINE _DstNS ::Object ::bridgingCast (const void * pObj ) 140{ 141#if __OBJC__ 142return (__bridge _Dst )pObj ; 143#else 144return (_Dst )pObj ; 145#endif // __OBJC__ 146} 147 148//------------------------------------------------------------------------------------------------------------------------------------------------------------- 149 150template < typename _Type > 151_NS_INLINE constexpr boolNS ::Object ::doesRequireMsgSendStret () 152{ 153#if (defined(__i386__ )|| defined(__x86_64__ )) 154constexpr size_t kStructLimit = (sizeof (std::uintptr_t ) <<1 ); 155 156return sizeof (_Type )> kStructLimit ; 157#elif defined(__arm64__ ) 158return false; 159#elif defined(__arm__ ) 160constexpr size_t kStructLimit = sizeof (std::uintptr_t ); 161 162return std::is_class (_Type )&& (sizeof (_Type )> kStructLimit ); 163#else 164#error "Unsupported architecture!" 165#endif 166} 167 168//------------------------------------------------------------------------------------------------------------------------------------------------------------- 169 170template <> 171_NS_INLINE constexpr boolNS ::Object ::doesRequireMsgSendStret < void > () 172{ 173return false; 174} 175 176//------------------------------------------------------------------------------------------------------------------------------------------------------------- 177 178template < typename _Ret ,typename ..._Args > 179_NS_INLINE _RetNS ::Object ::sendMessage (const void * pObj ,SEL selector ,_Args ...args ) 180{ 181#if (defined(__i386__ )|| defined(__x86_64__ )) 182if constexpr (std::is_floating_point < _Ret > ()) 183 { 184using SendMessageProcFpret = _Ret (* )(const void * ,SEL ,_Args ...); 185 186const SendMessageProcFpret pProc = reinterpret_cast < SendMessageProcFpret > (& objc_msgSend_fpret ); 187 188return (* pProc )(pObj ,selector ,args ...); 189 } 190else 191#endif // ( defined( __i386__ ) || defined( __x86_64__ ) ) 192#if !defined(__arm64__ ) 193if constexpr (doesRequireMsgSendStret < _Ret > ()) 194 { 195using SendMessageProcStret = void (* )(_Ret * ,const void * ,SEL ,_Args ...); 196 197const SendMessageProcStret pProc = reinterpret_cast < SendMessageProcStret > (& objc_msgSend_stret ); 198_Ret ret ; 199 200 (* pProc )(& ret ,pObj ,selector ,args ...); 201 202return ret ; 203 } 204else 205#endif // !defined( __arm64__ ) 206 { 207using SendMessageProc = _Ret (* )(const void * ,SEL ,_Args ...); 208 209const SendMessageProc pProc = reinterpret_cast < SendMessageProc > (& objc_msgSend ); 210 211return (* pProc )(pObj ,selector ,args ...); 212 } 213} 214 215//------------------------------------------------------------------------------------------------------------------------------------------------------------- 216 217_NS_INLINE NS ::MethodSignature * NS ::Object ::methodSignatureForSelector (const void * pObj ,SEL selector ) 218{ 219return sendMessage < MethodSignature *> (pObj ,_NS_PRIVATE_SEL (methodSignatureForSelector_ ),selector ); 220} 221 222//------------------------------------------------------------------------------------------------------------------------------------------------------------- 223 224_NS_INLINE boolNS ::Object ::respondsToSelector (const void * pObj ,SEL selector ) 225{ 226return sendMessage < bool > (pObj ,_NS_PRIVATE_SEL (respondsToSelector_ ),selector ); 227} 228 229//------------------------------------------------------------------------------------------------------------------------------------------------------------- 230 231template < typename _Ret ,typename ..._Args > 232_NS_INLINE _RetNS ::Object ::sendMessageSafe (const void * pObj ,SEL selector ,_Args ...args ) 233{ 234if ((respondsToSelector (pObj ,selector ))|| (nullptr != methodSignatureForSelector (pObj ,selector ))) 235 { 236return sendMessage < _Ret > (pObj ,selector ,args ...); 237 } 238 239if constexpr (!std::is_void < _Ret > ::value ) 240 { 241return 0 ; 242 } 243} 244 245//------------------------------------------------------------------------------------------------------------------------------------------------------------- 246 247template < class _Class > 248_NS_INLINE _Class * NS ::Object ::alloc (const char * pClassName ) 249{ 250return sendMessage < _Class *> (objc_lookUpClass (pClassName ),_NS_PRIVATE_SEL (alloc )); 251} 252 253//------------------------------------------------------------------------------------------------------------------------------------------------------------- 254 255template < class _Class > 256_NS_INLINE _Class * NS ::Object ::alloc (const void * pClass ) 257{ 258return sendMessage < _Class *> (pClass ,_NS_PRIVATE_SEL (alloc )); 259} 260 261//------------------------------------------------------------------------------------------------------------------------------------------------------------- 262 263template < class _Class > 264_NS_INLINE _Class * NS ::Object ::init () 265{ 266return sendMessage < _Class *> (this ,_NS_PRIVATE_SEL (init )); 267} 268 269//------------------------------------------------------------------------------------------------------------------------------------------------------------- 270 271_NS_INLINE NS ::UInteger NS ::Object ::hash ()const 272{ 273return sendMessage < UInteger > (this ,_NS_PRIVATE_SEL (hash )); 274} 275 276//------------------------------------------------------------------------------------------------------------------------------------------------------------- 277 278_NS_INLINE boolNS ::Object ::isEqual (const Object * pObject )const 279{ 280return sendMessage < bool > (this ,_NS_PRIVATE_SEL (isEqual_ ),pObject ); 281} 282 283//------------------------------------------------------------------------------------------------------------------------------------------------------------- 284 285_NS_INLINE NS ::String * NS ::Object ::description ()const 286{ 287return sendMessage < String *> (this ,_NS_PRIVATE_SEL (description )); 288} 289 290//------------------------------------------------------------------------------------------------------------------------------------------------------------- 291 292_NS_INLINE NS ::String * NS ::Object ::debugDescription ()const 293{ 294return sendMessageSafe < String *> (this ,_NS_PRIVATE_SEL (debugDescription )); 295} 296 297//-------------------------------------------------------------------------------------------------------------------------------------------------------------