Reactor: add type-safe FunctionT and RoutineT
Bug: b/143479561
Change-Id: Ie1b8dad6611d5fb1e2a6e4cc679c01ac98cf8e4d
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/37668
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index f4bc9b0..a8c050a 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -2522,6 +2522,39 @@
{
};
+ // FunctionT accepts a C-style function type template argument, allowing it to return a type-safe RoutineT wrapper
+ template<typename FunctionType>
+ class FunctionT;
+
+ template<typename Return, typename... Arguments>
+ class FunctionT<Return(Arguments...)> : public Function<CToReactor<Return>(CToReactor<Arguments>...)>
+ {
+ public:
+ // Type of base class
+ using BaseType = Function<CToReactor<Return>(CToReactor<Arguments>...)>;
+
+ // Function type, e.g. void(int,float)
+ using CFunctionType = Return(Arguments...);
+
+ // Reactor function type, e.g. Void(Int, Float)
+ using ReactorFunctionType = CToReactor<Return>(CToReactor<Arguments>...);
+
+ // Returned RoutineT type
+ using RoutineType = RoutineT<CFunctionType>;
+
+ // Hide base implementations of operator()
+
+ RoutineType operator()(const char* name, ...)
+ {
+ return RoutineType(BaseType::operator()(name));
+ }
+
+ RoutineType operator()(const Config::Edit& cfg, const char* name, ...)
+ {
+ return RoutineType(BaseType::operator()(cfg, name));
+ }
+ };
+
RValue<Long> Ticks();
}
diff --git a/src/Reactor/Routine.hpp b/src/Reactor/Routine.hpp
index 67560e8..f5dad2c 100644
--- a/src/Reactor/Routine.hpp
+++ b/src/Reactor/Routine.hpp
@@ -15,6 +15,8 @@
#ifndef rr_Routine_hpp
#define rr_Routine_hpp
+#include <memory>
+
namespace rr
{
class Routine
@@ -25,6 +27,47 @@
virtual const void *getEntry(int index = 0) = 0;
};
+
+ // RoutineT is a type-safe wrapper around a Routine and its callable entry, returned by FunctionT
+ template<typename FunctionType>
+ class RoutineT;
+
+ template<typename Return, typename... Arguments>
+ class RoutineT<Return(Arguments...)>
+ {
+ public:
+ RoutineT() = default;
+
+ explicit RoutineT(const std::shared_ptr<Routine>& routine)
+ : routine(routine)
+ {
+ if (routine)
+ {
+ callable = reinterpret_cast<CallableType>(const_cast<void*>(routine->getEntry(0)));
+ }
+ }
+
+ operator bool() const
+ {
+ return callable != nullptr;
+ }
+
+ template <typename... Args>
+ Return operator()(Args&&... args) const
+ {
+ return callable(std::forward<Args>(args)...);
+ }
+
+ const void* getEntry() const
+ {
+ return reinterpret_cast<void*>(callable);
+ }
+
+ private:
+ std::shared_ptr<Routine> routine;
+ using CallableType = Return(*)(Arguments...);
+ CallableType callable = nullptr;
+ };
}
#endif // rr_Routine_hpp