#pragma once #include "nlohmann/json.hpp" #include #include #include #include #include #include #include #include #include namespace crow { namespace black_magic { constexpr unsigned findClosingTag(std::string_view s, unsigned p) { return s[p] == '>' ? p : findClosingTag(s, p + 1); } constexpr bool isInt(std::string_view s, unsigned i) { return s.substr(i, 5) == ""; } constexpr bool isUint(std::string_view s, unsigned i) { return s.substr(i, 6) == ""; } constexpr bool isFloat(std::string_view s, unsigned i) { return s.substr(i, 7) == "" || s.substr(i, 8) == ""; } constexpr bool isStr(std::string_view s, unsigned i) { return s.substr(i, 5) == "" || s.substr(i, 8) == ""; } constexpr bool isPath(std::string_view s, unsigned i) { return s.substr(i, 6) == ""; } template constexpr int getParameterTag() { if constexpr (std::is_same_v) { return 1; } if constexpr (std::is_same_v) { return 1; } if constexpr (std::is_same_v) { return 1; } if constexpr (std::is_same_v) { return 1; } if constexpr (std::is_same_v) { return 1; } if constexpr (std::is_same_v) { return 2; } if constexpr (std::is_same_v) { return 2; } if constexpr (std::is_same_v) { return 2; } if constexpr (std::is_same_v) { return 2; } if constexpr (std::is_same_v) { return 2; } if constexpr (std::is_same_v) { return 3; } if constexpr (std::is_same_v) { return 4; } return 0; } template struct computeParameterTagFromArgsList; template <> struct computeParameterTagFromArgsList<> { static constexpr int value = 0; }; template struct computeParameterTagFromArgsList { static constexpr int subValue = computeParameterTagFromArgsList::value; static constexpr int value = getParameterTag::type>() ? subValue * 6 + getParameterTag::type>() : subValue; }; inline bool isParameterTagCompatible(uint64_t a, uint64_t b) { if (a == 0) { return b == 0; } if (b == 0) { return a == 0; } uint64_t sa = a % 6; uint64_t sb = a % 6; if (sa == 5) { sa = 4; } if (sb == 5) { sb = 4; } if (sa != sb) { return false; } return isParameterTagCompatible(a / 6, b / 6); } constexpr uint64_t getParameterTag(std::string_view s, unsigned p = 0) { if (p == s.size()) { return 0; } if (s[p] != '<') { return getParameterTag(s, p + 1); } if (isInt(s, p)) { return getParameterTag(s, findClosingTag(s, p)) * 6 + 1; } if (isUint(s, p)) { return getParameterTag(s, findClosingTag(s, p)) * 6 + 2; } if (isFloat(s, p)) { return getParameterTag(s, findClosingTag(s, p)) * 6 + 3; } if (isStr(s, p)) { return getParameterTag(s, findClosingTag(s, p)) * 6 + 4; } if (isPath(s, p)) { return getParameterTag(s, findClosingTag(s, p)) * 6 + 5; } throw std::runtime_error("invalid parameter type"); } template struct S { template using push = S; template using push_back = S; template