X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2Fmstch%2Fmstch.hpp;fp=lib%2Fmstch%2Fmstch.hpp;h=58d3330e05e612a47d016497a73e5d6d1067755d;hb=2e142df11d6f312a2a2b5097b8da73571ed523e8;hp=0000000000000000000000000000000000000000;hpb=61b3659afe961ed248f30e26f9ca8f28fcfafddc;p=cpPlugins.git diff --git a/lib/mstch/mstch.hpp b/lib/mstch/mstch.hpp new file mode 100644 index 0000000..58d3330 --- /dev/null +++ b/lib/mstch/mstch.hpp @@ -0,0 +1,113 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace mstch { + +struct config { + static std::function escape; +}; + +namespace internal { + +template +class object_t { + public: + const N& at(const std::string& name) const { + cache[name] = (methods.at(name))(); + return cache[name]; + } + + bool has(const std::string name) const { + return methods.count(name) != 0; + } + + protected: + template + void register_methods(S* s, std::map methods) { + for(auto& item: methods) + this->methods.insert({item.first, std::bind(item.second, s)}); + } + + private: + std::map> methods; + mutable std::map cache; +}; + +template +class is_fun { + private: + using not_fun = char; + using fun_without_args = char[2]; + using fun_with_args = char[3]; + template struct really_has; + template static fun_without_args& test( + really_has*); + template static fun_with_args& test( + really_has*); + template static not_fun& test(...); + + public: + static bool const no_args = sizeof(test(0)) == sizeof(fun_without_args); + static bool const has_args = sizeof(test(0)) == sizeof(fun_with_args); +}; + +template +using node_renderer = std::function; + +template +class lambda_t { + public: + template + lambda_t(F f, typename std::enable_if::no_args>::type* = 0): + fun([f](node_renderer renderer, const std::string&) { + return renderer(f()); + }) + { + } + + template + lambda_t(F f, typename std::enable_if::has_args>::type* = 0): + fun([f](node_renderer renderer, const std::string& text) { + return renderer(f(text)); + }) + { + } + + std::string operator()(node_renderer renderer, + const std::string& text = "") const + { + return fun(renderer, text); + } + + private: + std::function renderer, const std::string&)> fun; +}; + +} + +using node = boost::make_recursive_variant< + std::nullptr_t, std::string, int, double, bool, + internal::lambda_t, + std::shared_ptr>, + std::map, + std::vector>::type; +using object = internal::object_t; +using lambda = internal::lambda_t; +using map = std::map; +using array = std::vector; + +std::string render( + const std::string& tmplt, + const node& root, + const std::map& partials = + std::map()); + +}