summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-09-01 13:03:01 +1000
committerMaxime Coste <mawww@kakoune.org>2019-09-01 13:04:47 +1000
commit4c4eb61c188347f6956dfcd075e190c79f0a970c (patch)
tree4a39400d0dc21244066c77ab07d930848beeed04
parentb24be99fa3e684201faed534c5988940d561df35 (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.cc5
-rw-r--r--src/command_manager.hh2
-rw-r--r--src/line_modification.cc2
-rw-r--r--src/line_modification.hh4
-rw-r--r--src/utils.hh32
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