diff --git a/hyper.h b/hyper.h index 036e8780..a4ccc666 100644 --- a/hyper.h +++ b/hyper.h @@ -407,9 +407,41 @@ struct movedir { // shmup -template class hookset_impl : public map> {}; -template using hookset = hookset_impl *; -using purehookset = hookset_impl *; +template +class hookset { + std::map> *map_ = nullptr; + +public: + template + int add(int prio, U&& hook) { + if (map_ == nullptr) map_ = new std::map>(); + while (map_->count(prio)) { + prio++; + } + map_->emplace(prio, static_cast(hook)); + return 0; + } + + template + void callhooks(U&&... args) const { + if (map_ == nullptr) return; + for (const auto& p : *map_) { + p.second(static_cast(args)...); + } + } + + template + V callhandlers(V zero, U&&... args) const { + if (map_ == nullptr) return zero; + for (const auto& p : *map_) { + auto z = p.second(static_cast(args)...); + if (z != zero) return z; + } + return zero; + } +}; + +using purehookset = hookset; static const int NOHINT = -1; @@ -634,25 +666,16 @@ color_t darkena(color_t c, int lev, int a); static const int DISTANCE_UNKNOWN = 127; -template int addHook(hookset& m, int prio, const U& hook) { - if(!m) m = new hookset_impl (); - while(m->count(prio)) { - prio++; - } - (*m)[prio] = hook; - return 0; +template int addHook(hookset& m, int prio, U&& hook) { + return m.add(prio, static_cast(hook)); } -template void callhooks(hookset h, U&&... args) { - if(h) for(auto& p: *h) p.second(std::forward(args)...); +template void callhooks(const hookset& h, U&&... args) { + return h.callhooks(static_cast(args)...); } -template V callhandlers(V zero, hookset h, U&&... args) { - if(h) for(auto& p: *h) { - auto z = p.second(std::forward(args)...); - if(z != zero) return z; - } - return zero; +template V callhandlers(V zero, const hookset& h, U&&... args) { + return h.callhandlers(zero, static_cast(args)...); } string XLAT(string);