Thomas Psota | 79a97d6 | 2019-11-25 15:33:10 +0100 | [diff] [blame] | 1 | #ifndef OBJ_FUNCTION_H |
| 2 | #define OBJ_FUNCTION_H |
| 3 | |
| 4 | #include <functional> |
| 5 | |
Tobias Klausmann | f13b5e2 | 2019-12-13 11:56:37 +0100 | [diff] [blame] | 6 | #include <BaSyx/shared/object/object_header.h> |
Thomas Psota | 79a97d6 | 2019-11-25 15:33:10 +0100 | [diff] [blame] | 7 | |
Tobias Klausmann | f6ce45e | 2019-12-17 16:54:42 +0100 | [diff] [blame] | 8 | #include <nlohmann/json.hpp> |
Thomas Psota | 79a97d6 | 2019-11-25 15:33:10 +0100 | [diff] [blame] | 9 | |
| 10 | namespace basyx { |
| 11 | namespace detail { |
| 12 | |
| 13 | class functionWrapper |
| 14 | { |
| 15 | private: |
| 16 | std::function<basyx::object(basyx::object*)> func; |
| 17 | |
| 18 | template <typename R, typename... Args, std::size_t... Is> |
| 19 | static R invoke_helper(std::function<R(Args...)> f, basyx::object::object_list_t & params, util::index_sequence<Is...>) |
| 20 | { |
| 21 | return f(params[Is].Get<Args&>()...); |
| 22 | }; |
| 23 | public: |
| 24 | // Invoke wrapped function with no arguments |
Johannes Wendel | ed007a1 | 2019-11-25 17:09:45 +0100 | [diff] [blame] | 25 | basyx::object invoke() const |
Thomas Psota | 79a97d6 | 2019-11-25 15:33:10 +0100 | [diff] [blame] | 26 | { |
| 27 | return func(nullptr); |
| 28 | }; |
| 29 | |
| 30 | // Invoke wrapped function with argument |
| 31 | // Has to be primitive object or object list |
Johannes Wendel | ed007a1 | 2019-11-25 17:09:45 +0100 | [diff] [blame] | 32 | basyx::object invoke(basyx::object & obj) const |
Thomas Psota | 79a97d6 | 2019-11-25 15:33:10 +0100 | [diff] [blame] | 33 | { |
| 34 | return func(&obj); |
| 35 | }; |
| 36 | |
| 37 | // Wrap function with no arguments |
| 38 | template<typename RetType> |
| 39 | static functionWrapper wrap_func(std::function<RetType(void)> f) |
| 40 | { |
| 41 | functionWrapper fw; |
| 42 | fw.func = [f](basyx::object*) |
| 43 | { |
| 44 | return basyx::object{ f() }; |
| 45 | }; |
| 46 | return fw; |
| 47 | }; |
| 48 | |
| 49 | // Wrap function with single argument |
| 50 | template<typename RetType, typename Arg> |
| 51 | static functionWrapper wrap_func(std::function<RetType(Arg)> f) |
| 52 | { |
| 53 | functionWrapper fw; |
| 54 | fw.func = [f](basyx::object * obj) |
| 55 | { |
| 56 | // Only allow primitive object types |
| 57 | if (obj != nullptr && obj->GetObjectType() == basyx::type::objectType::Primitive && obj->GetValueType() == basyx::type::basyx_type<Arg>::value_type) |
| 58 | { |
| 59 | // Cast object to argument type and invoke |
| 60 | auto & i = obj->Get<Arg&>(); |
| 61 | return basyx::object{ f(i) }; |
| 62 | }; |
| 63 | |
| 64 | return basyx::object::make_null(); |
| 65 | }; |
| 66 | return fw; |
| 67 | }; |
| 68 | |
| 69 | // Wrap function with argument list |
| 70 | template<typename RetType, typename... Args> |
| 71 | static functionWrapper wrap_func(std::function<RetType(Args...)> f) |
| 72 | { |
| 73 | functionWrapper fw; |
| 74 | fw.func = [f](basyx::object * obj) |
| 75 | { |
| 76 | // Only allow object lists |
| 77 | if (obj != nullptr && obj->GetObjectType() == basyx::type::objectType::List && obj->GetValueType() == basyx::type::valueType::Object) |
| 78 | { |
| 79 | auto & list = obj->Get<basyx::object::object_list_t&>(); |
| 80 | |
| 81 | // if size of argument list differs from the functions parameter list, return null |
| 82 | if (list.size() != sizeof...(Args)) |
| 83 | return basyx::object::make_null(); |
| 84 | |
| 85 | // TODO: type check arguments |
| 86 | |
| 87 | // Invoke, using an integer sequence to pass the values from the list as single parameters to the function |
| 88 | return basyx::object{ invoke_helper<RetType, Args...>(f, list, util::make_index_sequence<sizeof...(Args)>{}) }; |
| 89 | }; |
| 90 | |
| 91 | return basyx::object::make_null(); |
| 92 | }; |
| 93 | return fw; |
| 94 | }; |
| 95 | |
| 96 | template<typename T> |
| 97 | bool operator==(const T &) const |
| 98 | { |
| 99 | return false; |
| 100 | }; |
| 101 | }; |
| 102 | |
| 103 | static void to_json(nlohmann::json & json, const functionWrapper &) |
| 104 | { |
| 105 | return; |
| 106 | }; |
| 107 | |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | |
| 112 | #endif /* OBJ_FUNCTION_H */ |