diff options
| author | Maxime Coste <mawww@kakoune.org> | 2019-09-01 13:03:01 +1000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2019-09-01 13:04:47 +1000 |
| commit | 4c4eb61c188347f6956dfcd075e190c79f0a970c (patch) | |
| tree | 4a39400d0dc21244066c77ab07d930848beeed04 | |
| parent | b24be99fa3e684201faed534c5988940d561df35 (diff) | |
Introduce FunctionRef to replace std::function when not storing
std::function is not necessary when we just want to pass a type
erased callback that does not need to own its target. FunctionRef
provides that functionality for a much lower compile time cost.
| -rw-r--r-- | src/command_manager.cc | 5 | ||||
| -rw-r--r-- | src/command_manager.hh | 2 | ||||
| -rw-r--r-- | src/line_modification.cc | 2 | ||||
| -rw-r--r-- | src/line_modification.hh | 4 | ||||
| -rw-r--r-- | src/utils.hh | 32 |
5 files changed, 37 insertions, 8 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc index dcf862ae..294d3eab 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -462,10 +462,9 @@ String expand(StringView str, const Context& context, String expand(StringView str, const Context& context, const ShellContext& shell_context, - const std::function<String (String)>& postprocess) + const FunctionRef<String (String)>& postprocess) { - return expand_impl(str, context, shell_context, - [&](String s) { return postprocess(std::move(s)); }); + return expand_impl(str, context, shell_context, postprocess); } struct command_not_found : runtime_error diff --git a/src/command_manager.hh b/src/command_manager.hh index 774b8b2c..8a3a9f23 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -168,7 +168,7 @@ String expand(StringView str, const Context& context, String expand(StringView str, const Context& context, const ShellContext& shell_context, - const std::function<String (String)>& postprocess); + const FunctionRef<String (String)>& postprocess); } diff --git a/src/line_modification.cc b/src/line_modification.cc index d052cb54..01ad22bf 100644 --- a/src/line_modification.cc +++ b/src/line_modification.cc @@ -145,7 +145,7 @@ void LineRangeSet::update(ConstArrayView<LineModification> modifs) erase(std::remove_if(begin(), end(), [](auto& r) { return r.begin >= r.end; }), end()); } -void LineRangeSet::add_range(LineRange range, std::function<void (LineRange)> on_new_range) +void LineRangeSet::add_range(LineRange range, FunctionRef<void (LineRange)> on_new_range) { auto it = std::lower_bound(begin(), end(), range.begin, [](LineRange range, LineCount line) { return range.end < line; }); diff --git a/src/line_modification.hh b/src/line_modification.hh index 5cb4d350..b9c9cfcd 100644 --- a/src/line_modification.hh +++ b/src/line_modification.hh @@ -7,8 +7,6 @@ #include "range.hh" #include "vector.hh" -#include <functional> - namespace Kakoune { @@ -40,7 +38,7 @@ struct LineRangeSet : private Vector<LineRange, MemoryDomain::Highlight> void reset(LineRange range) { Base::operator=({range}); } void update(ConstArrayView<LineModification> modifs); - void add_range(LineRange range, std::function<void (LineRange)> on_new_range); + void add_range(LineRange range, FunctionRef<void (LineRange)> on_new_range); void remove_range(LineRange range); }; diff --git a/src/utils.hh b/src/utils.hh index 9b6d87bb..f9c53509 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -154,6 +154,38 @@ auto to_underlying(E value) return static_cast<std::underlying_type_t<E>>(value); } +template<typename> class FunctionRef; + +template<typename Res, typename... Args> +class FunctionRef<Res(Args...)> +{ +public: + FunctionRef() + : m_target{nullptr}, + m_invoker{[](void* target, Args... args) { + if constexpr (!std::is_same_v<Res, void>) return Res{}; + }} + {} + + template<typename Target> + FunctionRef(Target&& target) + : m_target{&target}, + m_invoker{[](void* target, Args... args) { + return (*reinterpret_cast<Target*>(target))(static_cast<Args>(args)...); + }} + {} + + Res operator()(Args... args) const + { + return m_invoker(m_target, static_cast<Args>(args)...); + } + +private: + using Invoker = Res (void*, Args...); + void* m_target; + Invoker* m_invoker; +}; + } #endif // utils_hh_INCLUDED |
