yum-mirror/VkFFT

git clone https://git.yummers.dev/yum-mirror/VkFFT

Tolmachev DmitriiMetal support in VkFFTba7001c

master
10.7 KiB297 linesraw
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();
43    void     release();
44
45    _Class*  autorelease();
46
47    UInteger 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:
60    UInteger      hash() const;
61    bool          isEqual(const Object* pObject) const;
62
63    class String* description() const;
64    class String* debugDescription() const;
65
66protected:
67    friend class Referencing<Object, objc_object>;
68
69    template <class _Class>
70    static _Class* alloc(const char* pClassName);
71    template <class _Class>
72    static _Class* alloc(const void* pClass);
73    template <class _Class>
74    _Class* init();
75
76    template <class _Dst>
77    static _Dst                   bridgingCast(const void* pObj);
78    static class MethodSignature* methodSignatureForSelector(const void* pObj, SEL selector);
79    static bool                   respondsToSelector(const void* pObj, SEL selector);
80    template <typename _Type>
81    static constexpr bool doesRequireMsgSendStret();
82    template <typename _Ret, typename... _Args>
83    static _Ret sendMessage(const void* pObj, SEL selector, _Args... args);
84    template <typename _Ret, typename... _Args>
85    static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args);
86
87private:
88    Object() = delete;
89    Object(const Object&) = delete;
90    ~Object() = delete;
91
92    Object& 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{
101    return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(retain));
102}
103
104//-------------------------------------------------------------------------------------------------------------------------------------------------------------
105
106template <class _Class, class _Base /* = Object */>
107_NS_INLINE void NS::Referencing<_Class, _Base>::release()
108{
109    Object::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{
117    return 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{
125    return 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{
133    return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(copy));
134}
135
136//-------------------------------------------------------------------------------------------------------------------------------------------------------------
137
138template <class _Dst>
139_NS_INLINE _Dst NS::Object::bridgingCast(const void* pObj)
140{
141#if __OBJC__
142    return (__bridge _Dst)pObj;
143#else
144    return (_Dst)pObj;
145#endif // __OBJC__
146}
147
148//-------------------------------------------------------------------------------------------------------------------------------------------------------------
149
150template <typename _Type>
151_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret()
152{
153#if (defined(__i386__) || defined(__x86_64__))
154    constexpr size_t kStructLimit = (sizeof(std::uintptr_t) << 1);
155
156    return sizeof(_Type) > kStructLimit;
157#elif defined(__arm64__)
158    return false;
159#elif defined(__arm__)
160    constexpr size_t kStructLimit = sizeof(std::uintptr_t);
161
162    return std::is_class(_Type) && (sizeof(_Type) > kStructLimit);
163#else
164#error "Unsupported architecture!"
165#endif
166}
167
168//-------------------------------------------------------------------------------------------------------------------------------------------------------------
169
170template <>
171_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret<void>()
172{
173    return false;
174}
175
176//-------------------------------------------------------------------------------------------------------------------------------------------------------------
177
178template <typename _Ret, typename... _Args>
179_NS_INLINE _Ret NS::Object::sendMessage(const void* pObj, SEL selector, _Args... args)
180{
181#if (defined(__i386__) || defined(__x86_64__))
182    if constexpr (std::is_floating_point<_Ret>())
183    {
184        using SendMessageProcFpret = _Ret (*)(const void*, SEL, _Args...);
185
186        const SendMessageProcFpret pProc = reinterpret_cast<SendMessageProcFpret>(&objc_msgSend_fpret);
187
188        return (*pProc)(pObj, selector, args...);
189    }
190    else
191#endif // ( defined( __i386__ )  || defined( __x86_64__ )  )
192#if !defined(__arm64__)
193        if constexpr (doesRequireMsgSendStret<_Ret>())
194    {
195        using SendMessageProcStret = void (*)(_Ret*, const void*, SEL, _Args...);
196
197        const SendMessageProcStret pProc = reinterpret_cast<SendMessageProcStret>(&objc_msgSend_stret);
198        _Ret                       ret;
199
200        (*pProc)(&ret, pObj, selector, args...);
201
202        return ret;
203    }
204    else
205#endif // !defined( __arm64__ )
206    {
207        using SendMessageProc = _Ret (*)(const void*, SEL, _Args...);
208
209        const SendMessageProc pProc = reinterpret_cast<SendMessageProc>(&objc_msgSend);
210
211        return (*pProc)(pObj, selector, args...);
212    }
213}
214
215//-------------------------------------------------------------------------------------------------------------------------------------------------------------
216
217_NS_INLINE NS::MethodSignature* NS::Object::methodSignatureForSelector(const void* pObj, SEL selector)
218{
219    return sendMessage<MethodSignature*>(pObj, _NS_PRIVATE_SEL(methodSignatureForSelector_), selector);
220}
221
222//-------------------------------------------------------------------------------------------------------------------------------------------------------------
223
224_NS_INLINE bool NS::Object::respondsToSelector(const void* pObj, SEL selector)
225{
226    return sendMessage<bool>(pObj, _NS_PRIVATE_SEL(respondsToSelector_), selector);
227}
228
229//-------------------------------------------------------------------------------------------------------------------------------------------------------------
230
231template <typename _Ret, typename... _Args>
232_NS_INLINE _Ret NS::Object::sendMessageSafe(const void* pObj, SEL selector, _Args... args)
233{
234    if ((respondsToSelector(pObj, selector)) || (nullptr != methodSignatureForSelector(pObj, selector)))
235    {
236        return sendMessage<_Ret>(pObj, selector, args...);
237    }
238
239    if constexpr (!std::is_void<_Ret>::value)
240    {
241        return 0;
242    }
243}
244
245//-------------------------------------------------------------------------------------------------------------------------------------------------------------
246
247template <class _Class>
248_NS_INLINE _Class* NS::Object::alloc(const char* pClassName)
249{
250    return 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{
258    return sendMessage<_Class*>(pClass, _NS_PRIVATE_SEL(alloc));
259}
260
261//-------------------------------------------------------------------------------------------------------------------------------------------------------------
262
263template <class _Class>
264_NS_INLINE _Class* NS::Object::init()
265{
266    return sendMessage<_Class*>(this, _NS_PRIVATE_SEL(init));
267}
268
269//-------------------------------------------------------------------------------------------------------------------------------------------------------------
270
271_NS_INLINE NS::UInteger NS::Object::hash() const
272{
273    return sendMessage<UInteger>(this, _NS_PRIVATE_SEL(hash));
274}
275
276//-------------------------------------------------------------------------------------------------------------------------------------------------------------
277
278_NS_INLINE bool NS::Object::isEqual(const Object* pObject) const
279{
280    return sendMessage<bool>(this, _NS_PRIVATE_SEL(isEqual_), pObject);
281}
282
283//-------------------------------------------------------------------------------------------------------------------------------------------------------------
284
285_NS_INLINE NS::String* NS::Object::description() const
286{
287    return sendMessage<String*>(this, _NS_PRIVATE_SEL(description));
288}
289
290//-------------------------------------------------------------------------------------------------------------------------------------------------------------
291
292_NS_INLINE NS::String* NS::Object::debugDescription() const
293{
294    return sendMessageSafe<String*>(this, _NS_PRIVATE_SEL(debugDescription));
295}
296
297//-------------------------------------------------------------------------------------------------------------------------------------------------------------