#ifndef INCLUDE_INJA_FUNCTION_STORAGE_HPP_ #define INCLUDE_INJA_FUNCTION_STORAGE_HPP_ #include #include "string_view.hpp" namespace inja { using json = nlohmann::json; using Arguments = std::vector; using CallbackFunction = std::function; using VoidCallbackFunction = std::function; /*! * \brief Class for builtin functions and user-defined callbacks. */ class FunctionStorage { public: enum class Operation { Not, And, Or, In, Equal, NotEqual, Greater, GreaterEqual, Less, LessEqual, Add, Subtract, Multiplication, Division, Power, Modulo, AtId, At, Default, DivisibleBy, Even, Exists, ExistsInObject, First, Float, Int, IsArray, IsBoolean, IsFloat, IsInteger, IsNumber, IsObject, IsString, Last, Length, Lower, Max, Min, Odd, Range, Round, Sort, Upper, Super, Join, Callback, ParenLeft, ParenRight, None, }; struct FunctionData { explicit FunctionData(const Operation &op, const CallbackFunction &cb = CallbackFunction{}) : operation(op), callback(cb) {} const Operation operation; const CallbackFunction callback; }; private: const int VARIADIC {-1}; std::map, FunctionData> function_storage = { {std::make_pair("at", 2), FunctionData { Operation::At }}, {std::make_pair("default", 2), FunctionData { Operation::Default }}, {std::make_pair("divisibleBy", 2), FunctionData { Operation::DivisibleBy }}, {std::make_pair("even", 1), FunctionData { Operation::Even }}, {std::make_pair("exists", 1), FunctionData { Operation::Exists }}, {std::make_pair("existsIn", 2), FunctionData { Operation::ExistsInObject }}, {std::make_pair("first", 1), FunctionData { Operation::First }}, {std::make_pair("float", 1), FunctionData { Operation::Float }}, {std::make_pair("int", 1), FunctionData { Operation::Int }}, {std::make_pair("isArray", 1), FunctionData { Operation::IsArray }}, {std::make_pair("isBoolean", 1), FunctionData { Operation::IsBoolean }}, {std::make_pair("isFloat", 1), FunctionData { Operation::IsFloat }}, {std::make_pair("isInteger", 1), FunctionData { Operation::IsInteger }}, {std::make_pair("isNumber", 1), FunctionData { Operation::IsNumber }}, {std::make_pair("isObject", 1), FunctionData { Operation::IsObject }}, {std::make_pair("isString", 1), FunctionData { Operation::IsString }}, {std::make_pair("last", 1), FunctionData { Operation::Last }}, {std::make_pair("length", 1), FunctionData { Operation::Length }}, {std::make_pair("lower", 1), FunctionData { Operation::Lower }}, {std::make_pair("max", 1), FunctionData { Operation::Max }}, {std::make_pair("min", 1), FunctionData { Operation::Min }}, {std::make_pair("odd", 1), FunctionData { Operation::Odd }}, {std::make_pair("range", 1), FunctionData { Operation::Range }}, {std::make_pair("round", 2), FunctionData { Operation::Round }}, {std::make_pair("sort", 1), FunctionData { Operation::Sort }}, {std::make_pair("upper", 1), FunctionData { Operation::Upper }}, {std::make_pair("super", 0), FunctionData { Operation::Super }}, {std::make_pair("super", 1), FunctionData { Operation::Super }}, {std::make_pair("join", 2), FunctionData { Operation::Join }}, }; public: void add_builtin(nonstd::string_view name, int num_args, Operation op) { function_storage.emplace(std::make_pair(static_cast(name), num_args), FunctionData { op }); } void add_callback(nonstd::string_view name, int num_args, const CallbackFunction &callback) { function_storage.emplace(std::make_pair(static_cast(name), num_args), FunctionData { Operation::Callback, callback }); } FunctionData find_function(nonstd::string_view name, int num_args) const { auto it = function_storage.find(std::make_pair(static_cast(name), num_args)); if (it != function_storage.end()) { return it->second; // Find variadic function } else if (num_args > 0) { it = function_storage.find(std::make_pair(static_cast(name), VARIADIC)); if (it != function_storage.end()) { return it->second; } } return FunctionData { Operation::None }; } }; } // namespace inja #endif // INCLUDE_INJA_FUNCTION_STORAGE_HPP_