summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2025-07-08 11:43:17 +1000
committerMaxime Coste <mawww@kakoune.org>2025-07-08 12:07:33 +1000
commitce1d512a0c1922ab5f43f28e7bae573508c98601 (patch)
tree7af8effd6b00c304cda1c87f657a0014fcdae2ae /src
parentfea08fc18d268ace4f843ec2b57cc33e36562098 (diff)
Replace std::unique_ptr with a custom implementation
<memory> is a costly header we can avoid by just implementing UniquePtr ourselves, which is a pretty straightforward in modern C++, this saves around 10% of the compilation time here.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.cc2
-rw-r--r--src/buffer_manager.cc2
-rw-r--r--src/buffer_manager.hh5
-rw-r--r--src/client.cc4
-rw-r--r--src/client.hh8
-rw-r--r--src/client_manager.cc10
-rw-r--r--src/client_manager.hh10
-rw-r--r--src/commands.cc8
-rw-r--r--src/diff.hh4
-rw-r--r--src/highlighter.cc2
-rw-r--r--src/highlighter.hh7
-rw-r--r--src/highlighter_group.cc2
-rw-r--r--src/highlighter_group.hh4
-rw-r--r--src/highlighters.cc76
-rw-r--r--src/hook_manager.cc6
-rw-r--r--src/hook_manager.hh7
-rw-r--r--src/input_handler.cc2
-rw-r--r--src/main.cc18
-rw-r--r--src/option_manager.cc4
-rw-r--r--src/option_manager.hh14
-rw-r--r--src/regex_impl.cc4
-rw-r--r--src/regex_impl.hh6
-rw-r--r--src/register_manager.cc2
-rw-r--r--src/register_manager.hh12
-rw-r--r--src/remote.cc4
-rw-r--r--src/remote.hh13
-rw-r--r--src/terminal_ui.hh4
-rw-r--r--src/unique_ptr.hh69
-rw-r--r--src/utils.hh11
-rw-r--r--src/value.hh4
30 files changed, 190 insertions, 134 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index 9a735aaf..5c7d26fa 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -87,7 +87,7 @@ void Buffer::on_registered()
m_flags &= ~Flags::NoBufSetOption;
for (auto& option : options().flatten_options()
- | transform(&std::unique_ptr<Option>::get)
+ | transform(&UniquePtr<Option>::get)
| gather<Vector<Option*>>())
on_option_changed(*option);
}
diff --git a/src/buffer_manager.cc b/src/buffer_manager.cc
index 539f160b..8b1309a0 100644
--- a/src/buffer_manager.cc
+++ b/src/buffer_manager.cc
@@ -34,7 +34,7 @@ Buffer* BufferManager::create_buffer(String name, Buffer::Flags flags, BufferLin
throw runtime_error{"buffer name is already in use"};
}
- m_buffers.push_back(std::make_unique<Buffer>(std::move(name), flags, std::move(lines), bom, eolformat, fs_status));
+ m_buffers.push_back(make_unique_ptr<Buffer>(std::move(name), flags, std::move(lines), bom, eolformat, fs_status));
auto* buffer = m_buffers.back().get();
buffer->on_registered();
diff --git a/src/buffer_manager.hh b/src/buffer_manager.hh
index 2b4c0b31..f441aa9b 100644
--- a/src/buffer_manager.hh
+++ b/src/buffer_manager.hh
@@ -4,8 +4,7 @@
#include "buffer.hh"
#include "vector.hh"
#include "utils.hh"
-
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -13,7 +12,7 @@ namespace Kakoune
class BufferManager : public Singleton<BufferManager>
{
public:
- using BufferList = Vector<std::unique_ptr<Buffer>, MemoryDomain::BufferMeta>;
+ using BufferList = Vector<UniquePtr<Buffer>, MemoryDomain::BufferMeta>;
using iterator = BufferList::const_iterator;
~BufferManager();
diff --git a/src/client.cc b/src/client.cc
index 14b7b7bc..51750208 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -24,8 +24,8 @@
namespace Kakoune
{
-Client::Client(std::unique_ptr<UserInterface>&& ui,
- std::unique_ptr<Window>&& window,
+Client::Client(UniquePtr<UserInterface>&& ui,
+ UniquePtr<Window>&& window,
SelectionList selections, int pid,
EnvVarMap env_vars,
String name,
diff --git a/src/client.hh b/src/client.hh
index 43584c42..0963fae4 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -27,8 +27,8 @@ class Client final : public SafeCountable, public OptionManagerWatcher
public:
using OnExitCallback = std::function<void (int status)>;
- Client(std::unique_ptr<UserInterface>&& ui,
- std::unique_ptr<Window>&& window,
+ Client(UniquePtr<UserInterface>&& ui,
+ UniquePtr<Window>&& window,
SelectionList selections,
int pid, EnvVarMap env_vars,
String name,
@@ -88,8 +88,8 @@ private:
DisplayLine generate_mode_line() const;
- std::unique_ptr<UserInterface> m_ui;
- std::unique_ptr<Window> m_window;
+ UniquePtr<UserInterface> m_ui;
+ UniquePtr<Window> m_window;
const int m_pid;
diff --git a/src/client_manager.cc b/src/client_manager.cc
index 8d4f2de0..1548f502 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -44,7 +44,7 @@ String ClientManager::generate_name() const
}
}
-Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui, int pid,
+Client* ClientManager::create_client(UniquePtr<UserInterface>&& ui, int pid,
String name, EnvVarMap env_vars, StringView init_cmds,
StringView init_buffer, Optional<BufferCoord> init_coord,
Client::OnExitCallback on_exit)
@@ -156,7 +156,7 @@ WindowAndSelections ClientManager::get_free_window(Buffer& buffer)
{ return &ws.window->buffer() == &buffer; });
if (it == m_free_windows.rend())
- return { std::make_unique<Window>(buffer), { buffer, Selection{} } };
+ return { make_unique_ptr<Window>(buffer), { buffer, Selection{} } };
WindowAndSelections res = std::move(*it);
m_free_windows.erase(it.base()-1);
@@ -164,7 +164,7 @@ WindowAndSelections ClientManager::get_free_window(Buffer& buffer)
return res;
}
-void ClientManager::add_free_window(std::unique_ptr<Window>&& window, SelectionList selections)
+void ClientManager::add_free_window(UniquePtr<Window>&& window, SelectionList selections)
{
if (not contains(BufferManager::instance(), &window->buffer()))
{
@@ -181,7 +181,7 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
for (auto& client : m_clients)
client->context().forget_buffer(buffer);
- Vector<std::unique_ptr<Window>> removed_windows;
+ Vector<UniquePtr<Window>> removed_windows;
m_free_windows.erase(remove_if(m_free_windows,
[&buffer, &removed_windows](WindowAndSelections& ws) {
if (&ws.window->buffer() != &buffer)
@@ -240,7 +240,7 @@ void ClientManager::redraw_clients() const
CandidateList ClientManager::complete_client_name(StringView prefix,
ByteCount cursor_pos) const
{
- auto c = m_clients | transform([](const std::unique_ptr<Client>& c) -> const String&
+ auto c = m_clients | transform([](const UniquePtr<Client>& c) -> const String&
{ return c->context().name(); });
return complete(prefix, cursor_pos, c);
}
diff --git a/src/client_manager.hh b/src/client_manager.hh
index 8edeb790..daf351fc 100644
--- a/src/client_manager.hh
+++ b/src/client_manager.hh
@@ -9,7 +9,7 @@ namespace Kakoune
struct WindowAndSelections
{
- std::unique_ptr<Window> window;
+ UniquePtr<Window> window;
SelectionList selections;
};
@@ -19,7 +19,7 @@ public:
ClientManager();
~ClientManager();
- Client* create_client(std::unique_ptr<UserInterface>&& ui, int pid,
+ Client* create_client(UniquePtr<UserInterface>&& ui, int pid,
String name, EnvVarMap env_vars, StringView init_cmds,
StringView init_buffer, Optional<BufferCoord> init_coord,
Client::OnExitCallback on_exit);
@@ -32,7 +32,7 @@ public:
void ensure_no_client_uses_buffer(Buffer& buffer);
WindowAndSelections get_free_window(Buffer& buffer);
- void add_free_window(std::unique_ptr<Window>&& window, SelectionList selections);
+ void add_free_window(UniquePtr<Window>&& window, SelectionList selections);
void redraw_clients() const;
bool process_pending_inputs();
@@ -43,7 +43,7 @@ public:
bool client_name_exists(StringView name) const;
void remove_client(Client& client, bool graceful, int status);
- using ClientList = Vector<std::unique_ptr<Client>, MemoryDomain::Client>;
+ using ClientList = Vector<UniquePtr<Client>, MemoryDomain::Client>;
using iterator = ClientList::const_iterator;
iterator begin() const { return m_clients.begin(); }
@@ -60,7 +60,7 @@ private:
ClientList m_clients;
ClientList m_client_trash;
Vector<WindowAndSelections, MemoryDomain::Client> m_free_windows;
- Vector<std::unique_ptr<Window>, MemoryDomain::Client> m_window_trash;
+ Vector<UniquePtr<Window>, MemoryDomain::Client> m_window_trash;
};
}
diff --git a/src/commands.cc b/src/commands.cc
index e7faf5ec..351134f2 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -707,7 +707,7 @@ const CommandDesc write_all_cmd = {
static void ensure_all_buffers_are_saved()
{
- auto is_modified = [](const std::unique_ptr<Buffer>& buf) {
+ auto is_modified = [](const UniquePtr<Buffer>& buf) {
return (buf->flags() & Buffer::Flags::File) and buf->is_modified();
};
@@ -899,7 +899,7 @@ void cycle_buffer(const ParametersParser& parser, Context& context, const ShellC
{
Buffer* oldbuf = &context.buffer();
auto it = find_if(BufferManager::instance(),
- [oldbuf](const std::unique_ptr<Buffer>& lhs)
+ [oldbuf](const UniquePtr<Buffer>& lhs)
{ return lhs.get() == oldbuf; });
kak_assert(it != BufferManager::instance().end());
@@ -2093,7 +2093,7 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d
if (*bufnames == "*")
{
for (auto&& buffer : BufferManager::instance()
- | transform(&std::unique_ptr<Buffer>::get)
+ | transform(&UniquePtr<Buffer>::get)
| filter([](Buffer* buf) { return not (buf->flags() & Buffer::Flags::Debug); })
| gather<Vector<SafePtr<Buffer>>>()) // gather as we might be mutating the buffer list in the loop.
context_wrap_for_buffer(*buffer);
@@ -2197,7 +2197,7 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d
if (*client_names == "*")
{
for (auto&& client : ClientManager::instance()
- | transform(&std::unique_ptr<Client>::get)
+ | transform(&UniquePtr<Client>::get)
| gather<Vector<SafePtr<Client>>>()) // gather as we might be mutating the client list in the loop.
context_wrap_for_context(client->context());
}
diff --git a/src/diff.hh b/src/diff.hh
index 2f582b16..bcca655a 100644
--- a/src/diff.hh
+++ b/src/diff.hh
@@ -7,7 +7,7 @@
#include <algorithm>
#include <functional>
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -175,7 +175,7 @@ template<typename IteratorA, typename IteratorB, typename OnDiff, typename Equal
void for_each_diff(IteratorA a, int N, IteratorB b, int M, OnDiff&& on_diff, Equal&& eq = Equal{})
{
const int max = 2 * (N + M) + 1;
- std::unique_ptr<int[]> data(new int[2*max]);
+ UniquePtr<int[]> data(new int[2*max]);
constexpr int cost_limit = 1000;
Diff last{};
diff --git a/src/highlighter.cc b/src/highlighter.cc
index 7a6b2155..3e253343 100644
--- a/src/highlighter.cc
+++ b/src/highlighter.cc
@@ -35,7 +35,7 @@ Highlighter& Highlighter::get_child(StringView path)
throw runtime_error("this highlighter does not hold children");
}
-void Highlighter::add_child(String, std::unique_ptr<Highlighter>&&, bool)
+void Highlighter::add_child(String, UniquePtr<Highlighter>&&, bool)
{
throw runtime_error("this highlighter does not hold children");
}
diff --git a/src/highlighter.hh b/src/highlighter.hh
index fbeef9e4..3583c788 100644
--- a/src/highlighter.hh
+++ b/src/highlighter.hh
@@ -9,8 +9,7 @@
#include "string.hh"
#include "utils.hh"
#include "parameters_parser.hh"
-
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -68,7 +67,7 @@ struct Highlighter
virtual bool has_children() const;
virtual Highlighter& get_child(StringView path);
- virtual void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override = false);
+ virtual void add_child(String name, UniquePtr<Highlighter>&& hl, bool override = false);
virtual void remove_child(StringView id);
virtual Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const;
virtual void fill_unique_ids(Vector<StringView>& unique_ids) const;
@@ -83,7 +82,7 @@ private:
};
using HighlighterParameters = ConstArrayView<String>;
-using HighlighterFactory = std::unique_ptr<Highlighter> (*)(HighlighterParameters params, Highlighter* parent);
+using HighlighterFactory = UniquePtr<Highlighter> (*)(HighlighterParameters params, Highlighter* parent);
struct HighlighterDesc
{
diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc
index 57bbd7d2..77364274 100644
--- a/src/highlighter_group.cc
+++ b/src/highlighter_group.cc
@@ -26,7 +26,7 @@ void HighlighterGroup::fill_unique_ids(Vector<StringView>& unique_ids) const
hl.value->fill_unique_ids(unique_ids);
}
-void HighlighterGroup::add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override)
+void HighlighterGroup::add_child(String name, UniquePtr<Highlighter>&& hl, bool override)
{
if ((hl->passes() & passes()) != hl->passes())
throw runtime_error{"cannot add that highlighter to this group, passes don't match"};
diff --git a/src/highlighter_group.hh b/src/highlighter_group.hh
index 1502b796..658b85be 100644
--- a/src/highlighter_group.hh
+++ b/src/highlighter_group.hh
@@ -21,7 +21,7 @@ public:
HighlighterGroup(HighlightPass passes) : Highlighter{passes} {}
bool has_children() const override { return true; }
- void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override = false) override;
+ void add_child(String name, UniquePtr<Highlighter>&& hl, bool override = false) override;
void remove_child(StringView id) override;
Highlighter& get_child(StringView path) override;
@@ -34,7 +34,7 @@ protected:
void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override;
void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) const override;
- using HighlighterMap = HashMap<String, std::unique_ptr<Highlighter>, MemoryDomain::Highlight>;
+ using HighlighterMap = HashMap<String, UniquePtr<Highlighter>, MemoryDomain::Highlight>;
HighlighterMap m_highlighters;
};
diff --git a/src/highlighters.cc b/src/highlighters.cc
index ff46081a..9787b487 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -29,7 +29,7 @@ namespace Kakoune
using Utf8Iterator = utf8::iterator<BufferIterator>;
template<typename Func>
-std::unique_ptr<Highlighter> make_highlighter(Func func, HighlightPass pass = HighlightPass::Colorize)
+UniquePtr<Highlighter> make_highlighter(Func func, HighlightPass pass = HighlightPass::Colorize)
{
struct SimpleHighlighter : public Highlighter
{
@@ -43,7 +43,7 @@ std::unique_ptr<Highlighter> make_highlighter(Func func, HighlightPass pass = Hi
}
Func m_func;
};
- return std::make_unique<SimpleHighlighter>(std::move(func), pass);
+ return make_unique_ptr<SimpleHighlighter>(std::move(func), pass);
}
template<typename T>
@@ -138,7 +138,7 @@ const HighlighterDesc fill_desc = {
"Fill the whole highlighted range with the given face",
{}
};
-static std::unique_ptr<Highlighter> create_fill_highlighter(HighlighterParameters params, Highlighter*)
+static UniquePtr<Highlighter> create_fill_highlighter(HighlighterParameters params, Highlighter*)
{
if (params.size() != 1)
throw runtime_error("wrong parameter count");
@@ -221,7 +221,7 @@ public:
++m_regex_version;
}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
if (params.size() < 2)
throw runtime_error("wrong parameter count");
@@ -244,7 +244,7 @@ public:
faces.emplace_back(capture, parse_face({colon+1, spec.end()}));
}
- return std::make_unique<RegexHighlighter>(std::move(re), std::move(faces));
+ return make_unique_ptr<RegexHighlighter>(std::move(re), std::move(faces));
}
private:
@@ -403,7 +403,7 @@ const HighlighterDesc dynamic_regex_desc = {
"Evaluate expression at every redraw to gather a regex",
{}
};
-std::unique_ptr<Highlighter> create_dynamic_regex_highlighter(HighlighterParameters params, Highlighter*)
+UniquePtr<Highlighter> create_dynamic_regex_highlighter(HighlighterParameters params, Highlighter*)
{
if (params.size() < 2)
throw runtime_error("wrong parameter count");
@@ -419,7 +419,7 @@ std::unique_ptr<Highlighter> create_dynamic_regex_highlighter(HighlighterParamet
}
auto make_hl = [](auto& get_regex, auto& resolve_faces) {
- return std::make_unique<DynamicRegexHighlighter<std::remove_cvref_t<decltype(get_regex)>,
+ return make_unique_ptr<DynamicRegexHighlighter<std::remove_cvref_t<decltype(get_regex)>,
std::remove_cvref_t<decltype(resolve_faces)>>>(
std::move(get_regex), std::move(resolve_faces));
};
@@ -473,7 +473,7 @@ const HighlighterDesc line_desc = {
"Highlight the line given by evaluating <value string> with <face>",
{}
};
-std::unique_ptr<Highlighter> create_line_highlighter(HighlighterParameters params, Highlighter*)
+UniquePtr<Highlighter> create_line_highlighter(HighlighterParameters params, Highlighter*)
{
if (params.size() != 2)
throw runtime_error("wrong parameter count");
@@ -523,7 +523,7 @@ const HighlighterDesc column_desc = {
"Highlight the column given by evaluating <value string> with <face>",
{}
};
-std::unique_ptr<Highlighter> create_column_highlighter(HighlighterParameters params, Highlighter*)
+UniquePtr<Highlighter> create_column_highlighter(HighlighterParameters params, Highlighter*)
{
if (params.size() != 2)
throw runtime_error("wrong parameter count");
@@ -756,13 +756,13 @@ struct WrapHighlighter : Highlighter
return get_column(buffer, tabstop, {line, col});
}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
ParametersParser parser(params, wrap_desc.params);
ColumnCount max_width = parser.get_switch("width").map(str_to_int)
.value_or(std::numeric_limits<int>::max());
- return std::make_unique<WrapHighlighter>(max_width, (bool)parser.get_switch("word"),
+ return make_unique_ptr<WrapHighlighter>(max_width, (bool)parser.get_switch("word"),
(bool)parser.get_switch("indent"),
parser.get_switch("marker").value_or("").str());
}
@@ -874,7 +874,7 @@ struct ShowWhitespacesHighlighter : Highlighter
m_spc{std::move(spc)}, m_lf{std::move(lf)}, m_nbsp{std::move(nbsp)}, m_indent{std::move(indent)}, m_only_trailing{std::move(only_trailing)}
{}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
ParametersParser parser(params, show_whitespace_desc.params);
@@ -886,7 +886,7 @@ struct ShowWhitespacesHighlighter : Highlighter
return value.str();
};
- return std::make_unique<ShowWhitespacesHighlighter>(
+ return make_unique_ptr<ShowWhitespacesHighlighter>(
get_param("tab", "→"), get_param("tabpad", " "), get_param("spc", "·"),
get_param("lf", "¬"), get_param("nbsp", "⍽"), get_param("indent", "│"), only_trailing);
}
@@ -1000,7 +1000,7 @@ struct LineNumbersHighlighter : Highlighter
m_cursor_separator{std::move(cursor_separator)},
m_min_digits{min_digits} {}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
ParametersParser parser(params, line_numbers_desc.params);
@@ -1019,7 +1019,7 @@ struct LineNumbersHighlighter : Highlighter
if (min_digits > 10)
throw runtime_error("min digits is limited to 10");
- return std::make_unique<LineNumbersHighlighter>((bool)parser.get_switch("relative"), (bool)parser.get_switch("hlcursor"), separator.str(), cursor_separator.str(), min_digits);
+ return make_unique_ptr<LineNumbersHighlighter>((bool)parser.get_switch("relative"), (bool)parser.get_switch("hlcursor"), separator.str(), cursor_separator.str(), min_digits);
}
private:
@@ -1164,7 +1164,7 @@ void show_matching_char(HighlightContext context, DisplayBuffer& display_buffer,
}
}
-std::unique_ptr<Highlighter> create_matching_char_highlighter(HighlighterParameters params, Highlighter*)
+UniquePtr<Highlighter> create_matching_char_highlighter(HighlighterParameters params, Highlighter*)
{
ParametersParser parser{params, show_matching_desc.params};
return make_highlighter(parser.get_switch("previous") ? show_matching_char<true> : show_matching_char<false>);
@@ -1294,7 +1294,7 @@ struct FlagLinesHighlighter : Highlighter
m_default_face{std::move(default_face)},
m_after(after) {}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
ParametersParser parser{params, {
{{"after", {{}, "display at line end" }}},
@@ -1307,7 +1307,7 @@ struct FlagLinesHighlighter : Highlighter
// throw if wrong option type
GlobalScope::instance().options()[option_name].get<LineAndSpecList>();
- return std::make_unique<FlagLinesHighlighter>(option_name, default_face, (bool)parser.get_switch("after"));
+ return make_unique_ptr<FlagLinesHighlighter>(option_name, default_face, (bool)parser.get_switch("after"));
}
private:
@@ -1451,7 +1451,7 @@ struct OptionBasedHighlighter : Highlighter
: Highlighter{pass}
, m_option_name{std::move(option_name)} {}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
if (params.size() != 1)
throw runtime_error("wrong parameter count");
@@ -1460,7 +1460,7 @@ struct OptionBasedHighlighter : Highlighter
// throw if wrong option type
GlobalScope::instance().options()[option_name].get<OptionType>();
- return std::make_unique<DerivedType>(option_name);
+ return make_unique_ptr<DerivedType>(option_name);
}
OptionType& get_option(const HighlightContext& context) const
@@ -1649,12 +1649,12 @@ const HighlighterDesc higlighter_group_desc = {
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 0
}
};
-std::unique_ptr<Highlighter> create_highlighter_group(HighlighterParameters params, Highlighter*)
+UniquePtr<Highlighter> create_highlighter_group(HighlighterParameters params, Highlighter*)
{
ParametersParser parser{params, higlighter_group_desc.params};
HighlightPass passes = parse_passes(parser.get_switch("passes").value_or("colorize"));
- return std::make_unique<HighlighterGroup>(passes);
+ return make_unique_ptr<HighlighterGroup>(passes);
}
const HighlighterDesc ref_desc = {
@@ -1672,11 +1672,11 @@ struct ReferenceHighlighter : Highlighter
ReferenceHighlighter(HighlightPass passes, String name)
: Highlighter{passes}, m_name{std::move(name)} {}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
ParametersParser parser{params, ref_desc.params};
HighlightPass passes = parse_passes(parser.get_switch("passes").value_or("colorize"));
- return std::make_unique<ReferenceHighlighter>(passes, parser[0]);
+ return make_unique_ptr<ReferenceHighlighter>(passes, parser[0]);
}
private:
@@ -1894,7 +1894,7 @@ public:
return it->value->get_child({sep_it+1, path.end()});
}
- void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override) override
+ void add_child(String name, UniquePtr<Highlighter>&& hl, bool override) override
{
if (not dynamic_cast<RegionHighlighter*>(hl.get()))
throw runtime_error{"only region highlighter can be added as child of a regions highlighter"};
@@ -1902,7 +1902,7 @@ public:
if (not override and it != m_regions.end())
throw runtime_error{format("duplicate id: '{}'", name)};
- std::unique_ptr<RegionHighlighter> region_hl{dynamic_cast<RegionHighlighter*>(hl.release())};
+ UniquePtr<RegionHighlighter> region_hl{dynamic_cast<RegionHighlighter*>(hl.release())};
if (region_hl->is_default())
{
if (not m_default_region.empty())
@@ -1944,11 +1944,11 @@ public:
return { 0, 0, complete(path, cursor_pos, container), completions_flags };
}
- static std::unique_ptr<Highlighter> create(HighlighterParameters params, Highlighter*)
+ static UniquePtr<Highlighter> create(HighlighterParameters params, Highlighter*)
{
if (not params.empty())
throw runtime_error{"unexpected parameters"};
- return std::make_unique<RegionsHighlighter>();
+ return make_unique_ptr<RegionsHighlighter>();
}
static bool is_regions(Highlighter* parent)
@@ -1960,7 +1960,7 @@ public:
return false;
}
- static std::unique_ptr<Highlighter> create_region(HighlighterParameters params, Highlighter* parent)
+ static UniquePtr<Highlighter> create_region(HighlighterParameters params, Highlighter* parent)
{
if (not is_regions(parent))
throw runtime_error{"region highlighter can only be added to a regions parent"};
@@ -1984,10 +1984,10 @@ public:
Regex{*recurse_switch};
auto delegate = it->value.factory(parser.positionals_from(3), nullptr);
- return std::make_unique<RegionHighlighter>(std::move(delegate), parser[0], parser[1], parser.get_switch("recurse").value_or("").str(), match_capture);
+ return make_unique_ptr<RegionHighlighter>(std::move(delegate), parser[0], parser[1], parser.get_switch("recurse").value_or("").str(), match_capture);
}
- static std::unique_ptr<Highlighter> create_default_region(HighlighterParameters params, Highlighter* parent)
+ static UniquePtr<Highlighter> create_default_region(HighlighterParameters params, Highlighter* parent)
{
if (not is_regions(parent))
throw runtime_error{"default-region highlighter can only be added to a regions parent"};
@@ -2002,13 +2002,13 @@ public:
throw runtime_error(format("no such highlighter type: '{}'", type));
auto delegate = it->value.factory(parser.positionals_from(1), nullptr);
- return std::make_unique<RegionHighlighter>(std::move(delegate));
+ return make_unique_ptr<RegionHighlighter>(std::move(delegate));
}
private:
struct RegionHighlighter : public Highlighter
{
- RegionHighlighter(std::unique_ptr<Highlighter>&& delegate,
+ RegionHighlighter(UniquePtr<Highlighter>&& delegate,
String begin, String end, String recurse,
bool match_capture)
: Highlighter{delegate->passes()},
@@ -2018,7 +2018,7 @@ private:
{
}
- RegionHighlighter(std::unique_ptr<Highlighter>&& delegate)
+ RegionHighlighter(UniquePtr<Highlighter>&& delegate)
: Highlighter{delegate->passes()}, m_delegate{std::move(delegate)}, m_default{true}
{
}
@@ -2033,7 +2033,7 @@ private:
return m_delegate->get_child(path);
}
- void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override) override
+ void add_child(String name, UniquePtr<Highlighter>&& hl, bool override) override
{
return m_delegate->add_child(name, std::move(hl), override);
}
@@ -2065,7 +2065,7 @@ private:
Highlighter& delegate() { return *m_delegate; }
// private:
- std::unique_ptr<Highlighter> m_delegate;
+ UniquePtr<Highlighter> m_delegate;
String m_begin;
String m_end;
@@ -2365,7 +2365,7 @@ private:
return regions;
}
- HashMap<String, std::unique_ptr<RegionHighlighter>, MemoryDomain::Highlight> m_regions;
+ HashMap<String, UniquePtr<RegionHighlighter>, MemoryDomain::Highlight> m_regions;
HashMap<RegexKey, Regex> m_regexes;
String m_default_region;
@@ -2375,7 +2375,7 @@ private:
void setup_builtin_highlighters(HighlighterGroup& group)
{
- group.add_child("tabulations"_str, std::make_unique<TabulationHighlighter>());
+ group.add_child("tabulations"_str, make_unique_ptr<TabulationHighlighter>());
group.add_child("unprintable"_str, make_highlighter(expand_unprintable));
group.add_child("selections"_str, make_highlighter(highlight_selections));
}
diff --git a/src/hook_manager.cc b/src/hook_manager.cc
index ee461a83..31634e9d 100644
--- a/src/hook_manager.cc
+++ b/src/hook_manager.cc
@@ -56,7 +56,7 @@ HookManager::~HookManager() = default;
void HookManager::add_hook(Hook hook, String group, HookFlags flags, Regex filter, String commands, Context& context)
{
- std::unique_ptr<HookData> hook_data{new HookData{std::move(group), flags, std::move(filter), std::move(commands)}};
+ UniquePtr<HookData> hook_data{new HookData{std::move(group), flags, std::move(filter), std::move(commands)}};
if (hook == Hook::ModuleLoaded)
{
const bool only_always = context.hooks_disabled();
@@ -80,7 +80,7 @@ void HookManager::remove_hooks(const Regex& regex)
{
for (auto& list : m_hooks)
{
- list.erase(remove_if(list, [this, &regex](std::unique_ptr<HookData>& h) {
+ list.erase(remove_if(list, [this, &regex](UniquePtr<HookData>& h) {
if (not regex_match(h->group.begin(), h->group.end(), regex))
return false;
m_hooks_trash.push_back(std::move(h));
@@ -94,7 +94,7 @@ CandidateList HookManager::complete_hook_group(StringView prefix, ByteCount pos_
CandidateList res;
for (auto& list : m_hooks)
{
- auto container = list | transform([](const std::unique_ptr<HookData>& h) -> const String& { return h->group; });
+ auto container = list | transform([](const UniquePtr<HookData>& h) -> const String& { return h->group; });
for (auto& c : complete(prefix, pos_in_token, container))
{
if (!contains(res, c))
diff --git a/src/hook_manager.hh b/src/hook_manager.hh
index 97c768a3..f0b66c71 100644
--- a/src/hook_manager.hh
+++ b/src/hook_manager.hh
@@ -6,8 +6,7 @@
#include "meta.hh"
#include "enum.hh"
#include "array.hh"
-
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -141,10 +140,10 @@ private:
friend class Scope;
SafePtr<HookManager> m_parent;
- Array<Vector<std::unique_ptr<HookData>, MemoryDomain::Hooks>, enum_desc(Meta::Type<Hook>{}).size()> m_hooks;
+ Array<Vector<UniquePtr<HookData>, MemoryDomain::Hooks>, enum_desc(Meta::Type<Hook>{}).size()> m_hooks;
mutable Vector<std::pair<Hook, StringView>, MemoryDomain::Hooks> m_running_hooks;
- mutable Vector<std::unique_ptr<HookData>, MemoryDomain::Hooks> m_hooks_trash;
+ mutable Vector<UniquePtr<HookData>, MemoryDomain::Hooks> m_hooks_trash;
};
}
diff --git a/src/input_handler.cc b/src/input_handler.cc
index d5f010c7..0c501edb 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -205,7 +205,7 @@ struct MouseHandler
}
private:
- std::unique_ptr<ScopedSelectionEdition> m_dragging;
+ UniquePtr<ScopedSelectionEdition> m_dragging;
BufferCoord m_anchor;
};
diff --git a/src/main.cc b/src/main.cc
index 60c0669e..8cf3349a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -213,7 +213,7 @@ static const EnvVarDesc builtin_env_vars[] = { {
"client_list", false,
[](StringView name, const Context& context) -> Vector<String>
{ return ClientManager::instance() |
- transform([](const std::unique_ptr<Client>& c) -> const String&
+ transform([](const UniquePtr<Client>& c) -> const String&
{ return c->context().name(); }) | gather<Vector<String>>(); }
}, {
"modified", false,
@@ -333,10 +333,10 @@ void register_registers()
RegisterManager& register_manager = RegisterManager::instance();
for (Codepoint c : StringView{"abcdefghijklmnopqrstuvwxyz\"^@"})
- register_manager.add_register(c, std::make_unique<StaticRegister>(String{c}));
+ register_manager.add_register(c, make_unique_ptr<StaticRegister>(String{c}));
for (Codepoint c : StringView{"/|:\\"})
- register_manager.add_register(c, std::make_unique<HistoryRegister>(String{c}));
+ register_manager.add_register(c, make_unique_ptr<HistoryRegister>(String{c}));
using StringList = Vector<String, MemoryDomain::Registers>;
@@ -388,7 +388,7 @@ void register_registers()
}));
}
- register_manager.add_register('_', std::make_unique<NullRegister>());
+ register_manager.add_register('_', make_unique_ptr<NullRegister>());
}
void register_keymaps()
@@ -551,7 +551,7 @@ UIType parse_ui_type(StringView ui_name)
throw parameter_error(format("error: unknown ui type: '{}'", ui_name));
}
-std::unique_ptr<UserInterface> make_ui(UIType ui_type)
+UniquePtr<UserInterface> make_ui(UIType ui_type)
{
struct DummyUI : UserInterface
{
@@ -577,9 +577,9 @@ std::unique_ptr<UserInterface> make_ui(UIType ui_type)
switch (ui_type)
{
- case UIType::Terminal: return std::make_unique<TerminalUI>();
- case UIType::Json: return std::make_unique<JsonUI>();
- case UIType::Dummy: return std::make_unique<DummyUI>();
+ case UIType::Terminal: return make_unique_ptr<TerminalUI>();
+ case UIType::Json: return make_unique_ptr<JsonUI>();
+ case UIType::Dummy: return make_unique_ptr<DummyUI>();
}
throw logic_error{};
}
@@ -598,7 +598,7 @@ pid_t fork_server_to_background()
return 0;
}
-std::unique_ptr<UserInterface> create_local_ui(UIType ui_type)
+UniquePtr<UserInterface> create_local_ui(UIType ui_type)
{
auto ui = make_ui(ui_type);
diff --git a/src/option_manager.cc b/src/option_manager.cc
index 0a77548f..ad7ce481 100644
--- a/src/option_manager.cc
+++ b/src/option_manager.cc
@@ -64,7 +64,7 @@ Option& OptionManager::get_local_option(StringView name)
else if (m_parent)
{
auto* clone = (*m_parent)[name].clone(*this);
- return *m_options.insert({clone->name(), std::unique_ptr<Option>{clone}});
+ return *m_options.insert({clone->name(), UniquePtr<Option>{clone}});
}
else
throw option_not_found(name);
@@ -120,7 +120,7 @@ void OptionManager::on_option_changed(const Option& option)
CandidateList OptionsRegistry::complete_option_name(StringView prefix,
ByteCount cursor_pos) const
{
- using OptionPtr = std::unique_ptr<const OptionDesc>;
+ using OptionPtr = UniquePtr<const OptionDesc>;
return complete(prefix, cursor_pos, m_descs |
filter([](const OptionPtr& desc)
{ return not (desc->flags() & OptionFlags::Hidden); }) |
diff --git a/src/option_manager.hh b/src/option_manager.hh
index c36aeb6d..cf51fc5d 100644
--- a/src/option_manager.hh
+++ b/src/option_manager.hh
@@ -10,8 +10,8 @@
#include "vector.hh"
#include "format.hh"
#include "string_utils.hh"
+#include "unique_ptr.hh"
-#include <memory>
#include <utility>
namespace Kakoune
@@ -121,7 +121,7 @@ private:
// the only one allowed to construct a root option manager
friend class Scope;
friend class OptionsRegistry;
- using OptionMap = HashMap<StringView, std::unique_ptr<Option>, MemoryDomain::Options>;
+ using OptionMap = HashMap<StringView, UniquePtr<Option>, MemoryDomain::Options>;
OptionMap m_options;
OptionManager* m_parent;
@@ -268,13 +268,13 @@ public:
: format("[{}] - {}", option_type_name(Meta::Type<T>{}), docstring);
m_descs.emplace_back(new OptionDesc{name.str(), std::move(doc), flags});
return *opts.insert({m_descs.back()->name(),
- std::make_unique<TypedCheckedOption<T, validator>>(m_global_manager, *m_descs.back(), value)});
+ make_unique_ptr<TypedCheckedOption<T, validator>>(m_global_manager, *m_descs.back(), value)});
}
const OptionDesc* option_desc(StringView name) const
{
auto it = find_if(m_descs,
- [&name](const std::unique_ptr<const OptionDesc>& opt)
+ [&name](const UniquePtr<const OptionDesc>& opt)
{ return opt->name() == name; });
return it != m_descs.end() ? it->get() : nullptr;
}
@@ -284,11 +284,11 @@ public:
CandidateList complete_option_name(StringView prefix, ByteCount cursor_pos) const;
void clear_option_trash() { m_option_trash.clear(); }
- void move_to_trash(std::unique_ptr<Option>&& option) { m_option_trash.push_back(std::move(option)); }
+ void move_to_trash(UniquePtr<Option>&& option) { m_option_trash.push_back(std::move(option)); }
private:
OptionManager& m_global_manager;
- Vector<std::unique_ptr<const OptionDesc>, MemoryDomain::Options> m_descs;
- Vector<std::unique_ptr<Option>> m_option_trash;
+ Vector<UniquePtr<const OptionDesc>, MemoryDomain::Options> m_descs;
+ Vector<UniquePtr<Option>> m_option_trash;
};
}
diff --git a/src/regex_impl.cc b/src/regex_impl.cc
index 8a46d833..f64fc7a9 100644
--- a/src/regex_impl.cc
+++ b/src/regex_impl.cc
@@ -1046,7 +1046,7 @@ private:
template<RegexMode direction>
[[gnu::noinline]]
- std::unique_ptr<CompiledRegex::StartDesc> compute_start_desc() const
+ UniquePtr<CompiledRegex::StartDesc> compute_start_desc() const
{
CompiledRegex::StartDesc start_desc{};
if (compute_start_desc<direction>(0, start_desc) or
@@ -1056,7 +1056,7 @@ private:
if (std::count(std::begin(start_desc.map), std::end(start_desc.map), true) == 1)
start_desc.start_byte = find(start_desc.map, true) - std::begin(start_desc.map);
- return std::make_unique<CompiledRegex::StartDesc>(start_desc);
+ return make_unique_ptr<CompiledRegex::StartDesc>(start_desc);
}
void optimize(size_t begin, size_t end)
diff --git a/src/regex_impl.hh b/src/regex_impl.hh
index 8853ced5..d62261ec 100644
--- a/src/regex_impl.hh
+++ b/src/regex_impl.hh
@@ -169,8 +169,8 @@ struct CompiledRegex : UseMemoryDomain<MemoryDomain::Regex>
bool map[count];
};
- std::unique_ptr<StartDesc> forward_start_desc;
- std::unique_ptr<StartDesc> backward_start_desc;
+ UniquePtr<StartDesc> forward_start_desc;
+ UniquePtr<StartDesc> backward_start_desc;
};
String dump_regex(const CompiledRegex& program);
@@ -751,7 +751,7 @@ private:
return res;
}
- std::unique_ptr<Thread[]> m_data;
+ UniquePtr<Thread[]> m_data;
uint32_t m_capacity_mask = 0; // Maximum capacity should be 2*instruction count, so 65536
uint32_t m_current = 0;
uint32_t m_next_begin = 0;
diff --git a/src/register_manager.cc b/src/register_manager.cc
index b9d09a52..b9055287 100644
--- a/src/register_manager.cc
+++ b/src/register_manager.cc
@@ -104,7 +104,7 @@ Register& RegisterManager::operator[](Codepoint c) const
return *(it->value);
}
-void RegisterManager::add_register(Codepoint c, std::unique_ptr<Register> reg)
+void RegisterManager::add_register(Codepoint c, UniquePtr<Register> reg)
{
auto& reg_ptr = m_registers[c];
kak_assert(not reg_ptr);
diff --git a/src/register_manager.hh b/src/register_manager.hh
index 9d843eff..78125bac 100644
--- a/src/register_manager.hh
+++ b/src/register_manager.hh
@@ -84,19 +84,19 @@ public:
};
template<typename Func>
-std::unique_ptr<Register> make_dyn_reg(String name, Func func)
+UniquePtr<Register> make_dyn_reg(String name, Func func)
{
auto setter = [](Context&, ConstArrayView<String>)
{
throw runtime_error("this register is not assignable");
};
- return std::make_unique<DynamicRegister<Func, decltype(setter)>>(name, std::move(func), setter);
+ return make_unique_ptr<DynamicRegister<Func, decltype(setter)>>(name, std::move(func), setter);
}
template<typename Getter, typename Setter>
-std::unique_ptr<Register> make_dyn_reg(String name, Getter getter, Setter setter)
+UniquePtr<Register> make_dyn_reg(String name, Getter getter, Setter setter)
{
- return std::make_unique<DynamicRegister<Getter, Setter>>(name, std::move(getter), std::move(setter));
+ return make_unique_ptr<DynamicRegister<Getter, Setter>>(name, std::move(getter), std::move(setter));
}
class NullRegister : public Register
@@ -120,14 +120,14 @@ class RegisterManager : public Singleton<RegisterManager>
public:
Register& operator[](StringView reg) const;
Register& operator[](Codepoint c) const;
- void add_register(Codepoint c, std::unique_ptr<Register> reg);
+ void add_register(Codepoint c, UniquePtr<Register> reg);
CandidateList complete_register_name(StringView prefix, ByteCount cursor_pos) const;
auto begin() const { return m_registers.begin(); }
auto end() const { return m_registers.end(); }
protected:
- HashMap<Codepoint, std::unique_ptr<Register>, MemoryDomain::Registers> m_registers;
+ HashMap<Codepoint, UniquePtr<Register>, MemoryDomain::Registers> m_registers;
};
}
diff --git a/src/remote.cc b/src/remote.cc
index f4e62419..871b967e 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -655,7 +655,7 @@ bool check_session(StringView session)
return connect(sock, (sockaddr*)&addr, sizeof(addr.sun_path)) != -1;
}
-RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<UserInterface>&& ui,
+RemoteClient::RemoteClient(StringView session, StringView name, UniquePtr<UserInterface>&& ui,
int pid, const EnvVarMap& env_vars, StringView init_command,
Optional<BufferCoord> init_coord, Optional<int> stdin_fd)
: m_ui(std::move(ui))
@@ -810,7 +810,7 @@ private:
AutoScroll::NotInitially);
auto* ui = new RemoteUI{sock, dimensions};
ClientManager::instance().create_client(
- std::unique_ptr<UserInterface>(ui), pid, std::move(name),
+ UniquePtr<UserInterface>(ui), pid, std::move(name),
std::move(env_vars), init_cmds, {}, init_coord,
[ui](int status) { ui->exit(status); });
diff --git a/src/remote.hh b/src/remote.hh
index dc6bc41f..40d0367e 100644
--- a/src/remote.hh
+++ b/src/remote.hh
@@ -6,8 +6,7 @@
#include "utils.hh"
#include "vector.hh"
#include "optional.hh"
-
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -30,15 +29,15 @@ using RemoteBuffer = Vector<char, MemoryDomain::Remote>;
class RemoteClient
{
public:
- RemoteClient(StringView session, StringView name, std::unique_ptr<UserInterface>&& ui,
+ RemoteClient(StringView session, StringView name, UniquePtr<UserInterface>&& ui,
int pid, const EnvVarMap& env_vars, StringView init_command,
Optional<BufferCoord> init_coord, Optional<int> stdin_fd);
bool is_ui_ok() const;
const Optional<int>& exit_status() const { return m_exit_status; }
private:
- std::unique_ptr<UserInterface> m_ui;
- std::unique_ptr<FDWatcher> m_socket_watcher;
+ UniquePtr<UserInterface> m_ui;
+ UniquePtr<FDWatcher> m_socket_watcher;
RemoteBuffer m_send_buffer;
Optional<int> m_exit_status;
};
@@ -68,8 +67,8 @@ private:
String m_session;
bool m_is_daemon;
- std::unique_ptr<FDWatcher> m_listener;
- Vector<std::unique_ptr<Accepter>, MemoryDomain::Remote> m_accepters;
+ UniquePtr<FDWatcher> m_listener;
+ Vector<UniquePtr<Accepter>, MemoryDomain::Remote> m_accepters;
};
bool check_session(StringView session);
diff --git a/src/terminal_ui.hh b/src/terminal_ui.hh
index 064edafe..49032f6c 100644
--- a/src/terminal_ui.hh
+++ b/src/terminal_ui.hh
@@ -84,7 +84,7 @@ private:
explicit operator bool() const { return (bool)lines; }
struct Line;
- std::unique_ptr<Line[]> lines;
+ UniquePtr<Line[]> lines;
};
struct Screen : Window
@@ -92,7 +92,7 @@ private:
void output(bool force, bool synchronized, Writer& writer);
void set_face(const Face& face, Writer& writer);
- std::unique_ptr<size_t[]> hashes;
+ UniquePtr<size_t[]> hashes;
Face m_active_face;
};
diff --git a/src/unique_ptr.hh b/src/unique_ptr.hh
new file mode 100644
index 00000000..86f9ac86
--- /dev/null
+++ b/src/unique_ptr.hh
@@ -0,0 +1,69 @@
+#ifndef unique_ptr_hh_INCLUDED
+#define unique_ptr_hh_INCLUDED
+
+#include <utility>
+#include <type_traits>
+#include <cstddef>
+
+namespace Kakoune
+{
+
+template<typename T>
+class UniquePtr
+{
+ using Type = std::remove_extent_t<T>;
+
+public:
+ explicit UniquePtr(Type* ptr = nullptr) : m_ptr{ptr} {}
+ UniquePtr(nullptr_t) : m_ptr{nullptr} {}
+
+ UniquePtr(const UniquePtr&) = delete;
+ UniquePtr& operator=(const UniquePtr&) = delete;
+
+ template<typename U> requires std::is_convertible_v<U*, T*>
+ UniquePtr(UniquePtr<U>&& other) noexcept { m_ptr = other.release(); }
+
+ template<typename U> requires std::is_convertible_v<U*, T*>
+ UniquePtr& operator=(UniquePtr<U>&& other) noexcept(noexcept(std::declval<Type>().~Type()))
+ {
+ destroy();
+ m_ptr = other.release();
+ return *this;
+ }
+ ~UniquePtr() { destroy(); }
+
+ Type* get() const { return m_ptr; }
+ Type* operator->() const { return m_ptr; };
+ Type& operator*() const { return *m_ptr; };
+ Type& operator[](size_t i) const requires std::is_array_v<T> { return m_ptr[i]; }
+ Type* release() { auto ptr = m_ptr; m_ptr = nullptr; return ptr; }
+
+ void reset(Type* ptr = nullptr) { destroy(); m_ptr = ptr; }
+
+ explicit operator bool() const { return m_ptr != nullptr; }
+
+ friend bool operator==(const UniquePtr&, const UniquePtr&) = default;
+ friend bool operator==(const UniquePtr& lhs, const Type* rhs) { return lhs.get() == rhs; }
+
+private:
+ void destroy()
+ {
+ if constexpr (std::is_array_v<T>)
+ delete[] m_ptr;
+ else
+ delete m_ptr;
+ m_ptr = nullptr;
+ }
+
+ Type* m_ptr;
+};
+
+template<typename T, typename... Args>
+UniquePtr<T> make_unique_ptr(Args&&... args)
+{
+ return UniquePtr<T>(new T(std::forward<Args>(args)...));
+}
+
+}
+
+#endif // unique_ptr_hh_INCLUDED
diff --git a/src/utils.hh b/src/utils.hh
index b517735f..ba8cf737 100644
--- a/src/utils.hh
+++ b/src/utils.hh
@@ -2,8 +2,7 @@
#define utils_hh_INCLUDED
#include "assert.hh"
-
-#include <memory>
+#include "unique_ptr.hh"
namespace Kakoune
{
@@ -127,14 +126,6 @@ private:
bool m_condition;
};
-// *** Misc helper functions ***
-
-template<typename T>
-bool operator== (const std::unique_ptr<T>& lhs, T* rhs)
-{
- return lhs.get() == rhs;
-}
-
template<typename T>
const T& clamp(const T& val, const T& min, const T& max)
{
diff --git a/src/value.hh b/src/value.hh
index f38e4fa2..0895927b 100644
--- a/src/value.hh
+++ b/src/value.hh
@@ -3,9 +3,9 @@
#include "hash_map.hh"
#include "meta.hh"
+#include "unique_ptr.hh"
#include <type_traits>
-#include <memory>
namespace Kakoune
{
@@ -68,7 +68,7 @@ private:
T m_content;
};
- std::unique_ptr<Concept> m_value;
+ UniquePtr<Concept> m_value;
};
enum class ValueId : int {};