使用c++14标准实现函数注册包装

调用方式bool res = FunctionRegistry::callFromFuncMap1<bool, type1&, type2*, type3,... >(...),其中第一个bool为返回值类型,第二个开始后面均为参数列表类型,可用于注册算子,包装函数指针等。

#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>

namespace op_select {

#define ORAM_BASE 0x15100000

class FunctionWrapperBase {
public:
    virtual ~FunctionWrapperBase() = default;
};

template <typename ReturnType, typename... Args>
class FunctionWrapper : public FunctionWrapperBase {
private:
    std::function<ReturnType(Args...)> func_;

public:
    FunctionWrapper(std::function<ReturnType(Args...)> func) : func_(func) {}

    ReturnType operator()(Args... args) {
        return func_(args...);
    }
};

class FunctionRegistry {
private:
    static std::unordered_map<std::string, std::shared_ptr<FunctionWrapperBase>>& getFuncMap1() {
        static std::unordered_map<std::string, std::shared_ptr<FunctionWrapperBase>> func_map1;
        return func_map1;
    }

    static std::unordered_map<std::string, std::shared_ptr<FunctionWrapperBase>>& getFuncMap2() {
        static std::unordered_map<std::string, std::shared_ptr<FunctionWrapperBase>> func_map2;
        return func_map2;
    }

    static std::mutex& getMutex1() {
        static std::mutex mutex1;
        return mutex1;
    }

    static std::mutex& getMutex2() {
        static std::mutex mutex2;
        return mutex2;
    }

public:
    FunctionRegistry() = delete;
    FunctionRegistry(const FunctionRegistry&) = delete;
    FunctionRegistry& operator=(const FunctionRegistry&) = delete;

    template <typename ReturnType, typename... Args>
    static bool registerToFuncMap1(const std::string& name, ReturnType (*func)(Args...)) {
        std::lock_guard<std::mutex> lock(getMutex1());
        std::function<ReturnType(Args...)> f = func;
        auto wrapper = std::make_shared<FunctionWrapper<ReturnType, Args...>>(f);
        return getFuncMap1().emplace(name, wrapper).second;
    }

    template <typename ReturnType, typename... Args>
    static bool registerToFuncMap1(const std::string& name, std::function<ReturnType(Args...)> func) {
        std::lock_guard<std::mutex> lock(getMutex1());
        auto wrapper = std::make_shared<FunctionWrapper<ReturnType, Args...>>(func);
        bool res = getFuncMap1().emplace(name, wrapper).second;
        return getFuncMap1().emplace(name, wrapper).second;
    }

    template <typename ReturnType, typename... Args>
    static bool registerToFuncMap2(const std::string& name, ReturnType (*func)(Args...)) {
        std::lock_guard<std::mutex> lock(getMutex2());
        std::function<ReturnType(Args...)> f = func;
        auto wrapper = std::make_shared<FunctionWrapper<ReturnType, Args...>>(f);
        return getFuncMap2().emplace(name, wrapper).second;
    }

    template <typename ReturnType, typename... Args>
    static bool registerToFuncMap2(const std::string& name, std::function<ReturnType(Args...)> func) {
        std::lock_guard<std::mutex> lock(getMutex2());
        auto wrapper = std::make_shared<FunctionWrapper<ReturnType, Args...>>(func);
        return getFuncMap2().emplace(name, wrapper).second;
    }

    template <typename ReturnType, typename... Args>
    static ReturnType callFromFuncMap1(const std::string& name, Args&&... args) {
        std::lock_guard<std::mutex> lock(getMutex1());

        auto it = getFuncMap1().find(name);
        if (it == getFuncMap1().end()) {
            throw std::runtime_error("Function '" + name + "' not found in FuncMap1");
        }

        auto wrapper = std::dynamic_pointer_cast<FunctionWrapper<ReturnType, Args...>>(it->second);
        if (!wrapper) {
            throw std::runtime_error("Type mismatch for function '" + name + "' in FuncMap1");
        }

        return (*wrapper)(std::forward<Args>(args)...);
    }

    template <typename ReturnType, typename... Args>
    static ReturnType callFromFuncMap2(const std::string& name, Args&&... args) {
        std::lock_guard<std::mutex> lock(getMutex2());
        auto it = getFuncMap2().find(name);
        if (it == getFuncMap2().end()) {
            throw std::runtime_error("Function '" + name + "' not found in FuncMap2");
        }

        auto wrapper = std::dynamic_pointer_cast<FunctionWrapper<ReturnType, Args...>>(it->second);
        if (!wrapper) {
            throw std::runtime_error("Type mismatch for function '" + name + "' in FuncMap2");
        }

        return (*wrapper)(std::forward<Args>(args)...);
    }
};

#define REGISTER_FUNCTION_TO_FUNC_MAP1(name, func)                                                                     \
    static bool _reg##name = [] {                                                                                      \
        FunctionRegistry::registerToFuncMap1(#name, func);                                                             \
        return true;                                                                                                   \
    }()

#define REGISTER_FUNCTION_TO_FUNC_MAP1(name, func)                                                                     \
    static bool _reg##name = [] {                                                                                      \
        FunctionRegistry::registerToFuncMap2(#name, func);                                                             \
        return true;                                                                                                   \
    }()

#define REGISTER_FUNCTION_TO_BOTH(name, func1, func2)                                                                  \
    static bool _reg##name = [] {                                                                                      \
        FunctionRegistry::registerToFuncMap1(#name, func1);                                                            \
        FunctionRegistry::registerToFuncMap2(#name, func2);                                                            \
        return true;                                                                                                   \
    }()

#define REGISTER_LAMBDA_TO_FUNC_MAP1(name, return_type, ...)                                                           \
    static bool _reg##name = [] {                                                                                      \
        FunctionRegistry::registerToFuncMap1<return_type, __VA_ARGS__>(name, std::function<return_type(__VA_ARGS__)>); \
        return true;                                                                                                   \
    }()

#define REGISTER_LAMBDA_TO_FUNC_MAP2(name, return_type, ...)                                                           \
    static bool _reg##name = [] {                                                                                      \
        FunctionRegistry::registerToFuncMap2<return_type, __VA_ARGS__>(name, std::function<return_type(__VA_ARGS__)>); \
        return true;                                                                                                   \
    }()

}  // namespace op_select
posted @ 2025-10-20 20:15  WEIWEI1095  阅读(6)  评论(0)    收藏  举报
*/
作品集 //