yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
5.8 KiB211 linesraw
1#ifndef SLANG_CORE_FUNC_PTR_H
2#define SLANG_CORE_FUNC_PTR_H
3
4#include "slang-smart-pointer.h"
5
6namespace Slang
7{
8
9template<typename TResult, typename... Arguments>
10class FuncPtr : public RefObject
11{
12public:
13    virtual TResult operator()(Arguments...) const = 0;
14    virtual bool operator==(const FuncPtr<TResult, Arguments...>*) { return false; }
15    virtual FuncPtr<TResult, Arguments...>* clone() = 0;
16    virtual ~FuncPtr() {}
17};
18
19template<typename TResult, typename... Arguments>
20class CdeclFuncPtr : public FuncPtr<TResult, Arguments...>
21{
22public:
23    typedef TResult (*FuncType)(Arguments...);
24
25private:
26    FuncType funcPtr;
27
28public:
29    CdeclFuncPtr(FuncType func)
30        : funcPtr(func)
31    {
32    }
33    virtual FuncPtr<TResult, Arguments...>* clone() override
34    {
35        auto rs = new CdeclFuncPtr<TResult, Arguments...>(funcPtr);
36        return rs;
37    }
38
39    virtual TResult operator()(Arguments... params) const override { return funcPtr(params...); }
40
41    virtual bool operator==(const FuncPtr<TResult, Arguments...>* ptr) override
42    {
43        auto cptr = dynamic_cast<const CdeclFuncPtr<TResult, Arguments...>*>(ptr);
44        if (cptr)
45            return funcPtr == cptr->funcPtr;
46        else
47            return false;
48    }
49};
50
51template<typename Class, typename TResult, typename... Arguments>
52class MemberFuncPtr : public FuncPtr<TResult, Arguments...>
53{
54public:
55    typedef TResult (Class::*FuncType)(Arguments...);
56
57private:
58    FuncType funcPtr;
59    Class* object;
60
61public:
62    MemberFuncPtr(Class* obj, FuncType func)
63        : funcPtr(func), object(obj)
64    {
65    }
66    virtual FuncPtr<TResult, Arguments...>* clone() override
67    {
68        auto rs = new MemberFuncPtr<Class, TResult, Arguments...>(object, funcPtr);
69        return rs;
70    }
71    virtual TResult operator()(Arguments... params) const override
72    {
73        return (object->*funcPtr)(params...);
74    }
75
76    virtual bool operator==(const FuncPtr<TResult, Arguments...>* ptr) override
77    {
78        auto cptr = dynamic_cast<const MemberFuncPtr<Class, TResult, Arguments...>*>(ptr);
79        if (cptr)
80            return funcPtr == cptr->funcPtr && object == cptr->object;
81        else
82            return false;
83    }
84};
85
86template<typename F, typename TResult, typename... Arguments>
87class LambdaFuncPtr : public FuncPtr<TResult, Arguments...>
88{
89private:
90    F func;
91
92public:
93    LambdaFuncPtr(const F& _func)
94        : func(_func)
95    {
96    }
97    virtual TResult operator()(Arguments... params) const override { return func(params...); }
98    virtual FuncPtr<TResult, Arguments...>* clone() override
99    {
100        auto rs = new LambdaFuncPtr<F, TResult, Arguments...>(func);
101        return rs;
102    }
103    virtual bool operator==(const FuncPtr<TResult, Arguments...>* /*ptr*/) override
104    {
105        return false;
106    }
107};
108
109template<typename TResult, typename... Arguments>
110class Func
111{
112private:
113    RefPtr<FuncPtr<TResult, Arguments...>> funcPtr;
114
115public:
116    Func() {}
117    Func(typename CdeclFuncPtr<TResult, Arguments...>::FuncType func)
118    {
119        funcPtr = new CdeclFuncPtr<TResult, Arguments...>(func);
120    }
121    template<typename Class>
122    Func(Class* object, typename MemberFuncPtr<Class, TResult, Arguments...>::FuncType func)
123    {
124        funcPtr = new MemberFuncPtr<Class, TResult, Arguments...>(object, func);
125    }
126    template<typename TFuncObj>
127    Func(const TFuncObj& func)
128    {
129        funcPtr = new LambdaFuncPtr<TFuncObj, TResult, Arguments...>(func);
130    }
131    Func& operator=(typename CdeclFuncPtr<TResult, Arguments...>::FuncType func)
132    {
133        funcPtr = new CdeclFuncPtr<TResult, Arguments...>(func);
134        return *this;
135    }
136    template<typename Class>
137    Func& operator=(const MemberFuncPtr<Class, TResult, Arguments...>& func)
138    {
139        funcPtr = new MemberFuncPtr<Class, TResult, Arguments...>(func);
140        return *this;
141    }
142    template<typename TFuncObj>
143    Func& operator=(const TFuncObj& func)
144    {
145        funcPtr = new LambdaFuncPtr<TFuncObj, TResult, Arguments...>(func);
146        return *this;
147    }
148    bool operator==(const Func& f) { return *funcPtr == f.funcPtr.Ptr(); }
149    bool operator!=(const Func& f) { return !(*this == f); }
150    TResult operator()(Arguments... params) const { return (*funcPtr)(params...); }
151};
152
153// template<typename... Arguments>
154// using Action = Func<void, Arguments...>;
155
156template<typename... Arguments>
157class Action : public Func<void, Arguments...>
158{
159private:
160    RefPtr<FuncPtr<void, Arguments...>> funcPtr;
161
162public:
163    Action() {}
164    Action(const Action& proc) { funcPtr = proc.funcPtr; }
165    Action(typename CdeclFuncPtr<void, Arguments...>::FuncType func)
166    {
167        funcPtr = new CdeclFuncPtr<void, Arguments...>(func);
168    }
169    template<typename Class>
170    Action(Class* object, typename MemberFuncPtr<Class, void, Arguments...>::FuncType func)
171    {
172        funcPtr = new MemberFuncPtr<Class, void, Arguments...>(object, func);
173    }
174    template<typename TFuncObj>
175    Action(const TFuncObj& func)
176    {
177        funcPtr = new LambdaFuncPtr<TFuncObj, void, Arguments...>(func);
178    }
179    Action& operator=(typename CdeclFuncPtr<void, Arguments...>::FuncType func)
180    {
181        funcPtr = new CdeclFuncPtr<void, Arguments...>(func);
182        return *this;
183    }
184    template<typename Class>
185    Action& operator=(const MemberFuncPtr<Class, void, Arguments...>& func)
186    {
187        funcPtr = new MemberFuncPtr<Class, void, Arguments...>(func);
188        return *this;
189    }
190    template<typename TFuncObj>
191    Action& operator=(const TFuncObj& func)
192    {
193        funcPtr = new LambdaFuncPtr<TFuncObj, void, Arguments...>(func);
194        return *this;
195    }
196    Action& operator=(const Action& proc)
197    {
198        funcPtr = proc.funcPtr;
199        return *this;
200    }
201    void clear() { funcPtr = nullptr; }
202    void operator()(Arguments... params) const
203    {
204        if (funcPtr)
205            (*funcPtr)(params...);
206    }
207};
208
209} // namespace Slang
210
211#endif