Skip to content

Commit d3ff64f

Browse files
committed
Add MoveOnlyFunction implementation and remove uses of shared_ptr
PromptCallback used to be std::function which needed copy support, preventing move-only lambda which led to the use of shared_ptr to store ScopedSelectionEdition.
1 parent ca085f0 commit d3ff64f

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

src/function.hh

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ inline constexpr FunctionVTable<Res, Args...> unset_vtable{
2323
.destroy = [](void*) {},
2424
};
2525

26-
template<typename Target, typename Res, typename... Args>
26+
template<bool Copyable, typename Target, typename Res, typename... Args>
2727
inline constexpr FunctionVTable<Res, Args...> vtable_for{
2828
.call = [](void* target, Args... args) -> Res { return (*reinterpret_cast<Target*>(target))(std::forward<Args>(args)...); },
29-
.clone = [](void* target) -> void* { return new Target(*reinterpret_cast<Target*>(target)); },
29+
.clone = [](void* target) -> void* { if constexpr (Copyable) { return new Target(*reinterpret_cast<Target*>(target)); } return nullptr; },
3030
.destroy = [](void* target) { delete reinterpret_cast<Target*>(target); }
3131
};
3232

@@ -37,18 +37,18 @@ inline constexpr FunctionVTable<Res, Args...> vtable_for_func{
3737
.destroy = [](void* target) {}
3838
};
3939

40-
template<typename F>
41-
class Function;
40+
template<bool Copyable, typename F>
41+
class FunctionImpl;
4242

43-
template<typename Res, typename... Args>
44-
class Function<Res (Args...)>
43+
template<bool Copyable, typename Res, typename... Args>
44+
class FunctionImpl<Copyable, Res (Args...)>
4545
{
4646
public:
47-
Function() = default;
47+
FunctionImpl() = default;
4848

4949
template<typename Target>
50-
requires (not std::is_same_v<Function, std::remove_cvref_t<Target>>)
51-
Function(Target&& target)
50+
requires (not std::is_same_v<FunctionImpl, std::remove_cvref_t<Target>>)
51+
FunctionImpl(Target&& target)
5252
{
5353
using EffectiveTarget = std::remove_cvref_t<Target>;
5454
if constexpr (std::is_convertible_v<EffectiveTarget, Res(*)(Args...)>)
@@ -59,33 +59,34 @@ public:
5959
else
6060
{
6161
m_target = new EffectiveTarget(std::forward<Target>(target));
62-
m_vtable = &vtable_for<EffectiveTarget, Res, Args...>;
62+
m_vtable = &vtable_for<Copyable, EffectiveTarget, Res, Args...>;
6363
}
6464
}
6565

66-
Function(const Function& other) : m_target(other.m_vtable->clone(other.m_target)), m_vtable(other.m_vtable)
66+
FunctionImpl(const FunctionImpl& other) requires Copyable
67+
: m_target(other.m_vtable->clone(other.m_target)), m_vtable(other.m_vtable)
6768
{
6869
}
6970

70-
Function(Function&& other) : m_target(other.m_target), m_vtable(other.m_vtable)
71+
FunctionImpl(FunctionImpl&& other) : m_target(other.m_target), m_vtable(other.m_vtable)
7172
{
7273
other.m_target = nullptr;
7374
other.m_vtable = &unset_vtable<Res, Args...>;
7475
}
7576

76-
~Function()
77+
~FunctionImpl()
7778
{
7879
m_vtable->destroy(m_target);
7980
}
8081

81-
Function& operator=(const Function& other)
82+
FunctionImpl& operator=(const FunctionImpl& other) requires Copyable
8283
{
8384
m_target = other.m_vtable->clone(other.m_target);
8485
m_vtable = other.m_vtable;
8586
return *this;
8687
}
8788

88-
Function& operator=(Function&& other)
89+
FunctionImpl& operator=(FunctionImpl&& other)
8990
{
9091
m_target = other.m_target;
9192
m_vtable = other.m_vtable;
@@ -106,6 +107,12 @@ private:
106107
const FunctionVTable<Res, Args...>* m_vtable = &unset_vtable<Res, Args...>;
107108
};
108109

110+
template<typename F>
111+
using Function = FunctionImpl<true, F>;
112+
113+
template<typename F>
114+
using MoveOnlyFunction = FunctionImpl<false, F>;
115+
109116
}
110117

111118
#endif // function_hh_INCLUDED

src/input_handler.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ enum class PromptEvent
2525
Abort,
2626
Validate
2727
};
28-
using PromptCallback = Function<void (StringView, PromptEvent, Context&)>;
28+
using PromptCallback = MoveOnlyFunction<void (StringView, PromptEvent, Context&)>;
2929

3030
enum class PromptFlags
3131
{

src/normal.cc

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#include "window.hh"
2929
#include "word_db.hh"
3030

31-
#include <memory>
32-
3331
namespace Kakoune
3432
{
3533

@@ -665,7 +663,7 @@ void pipe(Context& context, NormalParams params)
665663
prompt, {}, default_command, context.faces()["Prompt"],
666664
PromptFlags::DropHistoryEntriesWithBlankPrefix, '|',
667665
shell_complete,
668-
[default_command, selection_edition=std::make_shared<ScopedSelectionEdition>(context)]
666+
[default_command, selection_edition=ScopedSelectionEdition(context)]
669667
(StringView cmdline, PromptEvent event, Context& context)
670668
{
671669
if (event != PromptEvent::Validate)
@@ -880,7 +878,7 @@ void insert_output(Context& context, NormalParams params)
880878
prompt, {}, default_command, context.faces()["Prompt"],
881879
PromptFlags::DropHistoryEntriesWithBlankPrefix, '|',
882880
shell_complete,
883-
[default_command, selection_edition=std::make_shared<ScopedSelectionEdition>(context)]
881+
[default_command, selection_edition=ScopedSelectionEdition(context)]
884882
(StringView cmdline, PromptEvent event, Context& context)
885883
{
886884
if (event != PromptEvent::Validate)
@@ -954,7 +952,7 @@ void regex_prompt(Context& context, String prompt, char reg, RegexMode mode, Fun
954952
return {(int)(word.begin() - regex.begin()), pos, std::move(candidates) };
955953
},
956954
[=, func=std::move(func), saved_reg=RegisterManager::instance()[reg].save(context),
957-
selection_edition=std::make_shared<ScopedSelectionEdition>(context)]
955+
selection_edition=ScopedSelectionEdition(context)]
958956
(StringView str, PromptEvent event, Context& context) mutable {
959957
try
960958
{
@@ -1247,7 +1245,7 @@ void keep(Context& context, NormalParams params)
12471245
const char reg = to_lower(params.reg ? params.reg : '/');
12481246

12491247
regex_prompt(context, prompt.str(), reg, RegexMode::Forward,
1250-
[selection_edition=std::make_shared<ScopedSelectionEdition>(context)]
1248+
[selection_edition=ScopedSelectionEdition(context)]
12511249
(const Regex& regex, PromptEvent event, Context& context) {
12521250
if (regex.empty() or regex.str().empty())
12531251
return;
@@ -1278,7 +1276,7 @@ void keep_pipe(Context& context, NormalParams params)
12781276
context.input_handler().prompt(
12791277
"keep pipe:", {}, default_command, context.faces()["Prompt"],
12801278
PromptFlags::DropHistoryEntriesWithBlankPrefix, '|', shell_complete,
1281-
[default_command, selection_edition=std::make_shared<ScopedSelectionEdition>(context)]
1279+
[default_command, selection_edition=ScopedSelectionEdition(context)]
12821280
(StringView cmdline, PromptEvent event, Context& context) {
12831281
if (event != PromptEvent::Validate)
12841282
return;

0 commit comments

Comments
 (0)