From 9e15181dc9b56435c5e1d3ab87dd03404d6c31c9 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 8 Mar 2016 21:35:56 +0000 Subject: [PATCH] Rework container helpers, use pipe syntax and cleanup implementation use 'container | filter(func) | reverse() | transform(func)' instead of 'transform(reverse(filter(container), func), func)' to express container transformations. --- src/alias_registry.cc | 2 +- src/buffer.cc | 2 +- src/client.cc | 2 +- src/client_manager.cc | 8 +- src/command_manager.cc | 15 ++- src/commands.cc | 4 +- src/containers.hh | 276 ++++++++++++++++++++++----------------- src/face_registry.cc | 5 +- src/file.cc | 2 +- src/highlighter_group.cc | 7 +- src/highlighters.cc | 2 +- src/hook_manager.cc | 2 +- src/main.cc | 8 +- src/selection.cc | 4 +- src/selectors.cc | 2 +- 15 files changed, 185 insertions(+), 156 deletions(-) diff --git a/src/alias_registry.cc b/src/alias_registry.cc index 375246a3..690cde54 100644 --- a/src/alias_registry.cc +++ b/src/alias_registry.cc @@ -57,7 +57,7 @@ Vector> AliasRegistry::flatten_aliases() const res = m_parent->flatten_aliases(); for (auto& alias : m_aliases) { - if (not contains(transformed(res, [](const AliasDesc& val) { return val.first; }), alias.key)) + if (not contains(res | transform([](const AliasDesc& val) { return val.first; }), alias.key)) res.emplace_back(alias.key, alias.value); } return res; diff --git a/src/buffer.cc b/src/buffer.cc index e140f333..c0e25f0a 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -304,7 +304,7 @@ bool Buffer::undo() --m_history_cursor; - for (const Modification& modification : reversed(*m_history_cursor)) + for (const Modification& modification : *m_history_cursor | reverse()) apply_modification(modification.inverse()); return true; } diff --git a/src/client.cc b/src/client.cc index fcbba14c..cf8b3e71 100644 --- a/src/client.cc +++ b/src/client.cc @@ -235,7 +235,7 @@ void Client::redraw_ifn() void Client::force_redraw() { - m_ui_pending |= Refresh | Draw | + m_ui_pending |= Refresh | Draw | StatusLine | (m_menu.items.empty() ? MenuHide : MenuShow | MenuSelect) | (m_info.content.empty() ? InfoHide : InfoShow); } diff --git a/src/client_manager.cc b/src/client_manager.cc index b625fdc5..aff88d93 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -87,7 +87,7 @@ void ClientManager::remove_client(Client& client, bool graceful) WindowAndSelections ClientManager::get_free_window(Buffer& buffer) { - auto it = find_if(reversed(m_free_windows), + auto it = find_if(m_free_windows | reverse(), [&](const WindowAndSelections& ws) { return &ws.window->buffer() == &buffer; }); @@ -177,10 +177,8 @@ void ClientManager::redraw_clients() const CandidateList ClientManager::complete_client_name(StringView prefix, ByteCount cursor_pos) const { - auto c = transformed(m_clients, - [](const std::unique_ptr& c) -> const String& - { return c->context().name(); }); - + auto c = m_clients | transform([](const std::unique_ptr& c) -> const String& + { return c->context().name(); }); return complete(prefix, cursor_pos, c); } diff --git a/src/command_manager.cc b/src/command_manager.cc index 65de501c..4902f068 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -515,12 +515,15 @@ CommandInfo CommandManager::command_info(const Context& context, StringView comm Completions CommandManager::complete_command_name(const Context& context, StringView query) const { - return{0, query.length(), Kakoune::complete(query, query.length(), concatenated( - transformed(filtered(m_commands, [](const CommandMap::value_type& cmd) - { return not (cmd.second.flags & CommandFlags::Hidden); }), - [](const CommandMap::value_type& cmd) { return StringView{cmd.first}; }), - transformed(context.aliases().flatten_aliases(), - [](AliasRegistry::AliasDesc alias) { return alias.first; })))}; + auto candidates = Kakoune::complete( + query, query.length(), concatenated( + m_commands + | filter([](const CommandMap::value_type& cmd) { return not (cmd.second.flags & CommandFlags::Hidden); }) + | transform([](const CommandMap::value_type& cmd) { return StringView{cmd.first}; }), + context.aliases().flatten_aliases() + | transform([](AliasRegistry::AliasDesc alias) { return alias.first; }))); + + return {0, query.length(), std::move(candidates)}; } Completions CommandManager::complete(const Context& context, diff --git a/src/commands.cc b/src/commands.cc index 3a8d6132..b376f081 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -543,7 +543,7 @@ Completions add_highlighter_completer( if (token_to_complete == 1 and params[0] == "-group") return complete_highlighter(context, params[1], pos_in_token, true); else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group")) - return { 0_byte, arg.length(), complete(arg, pos_in_token, transformed(HighlighterRegistry::instance(), HighlighterRegistry::get_id)) }; + return { 0_byte, arg.length(), complete(arg, pos_in_token, HighlighterRegistry::instance() | transform(HighlighterRegistry::get_id)) }; return Completions{}; } @@ -626,7 +626,7 @@ const CommandDesc rm_highlighter_cmd = { [](const ParametersParser& parser, Context& context, const ShellContext&) { StringView path = parser[0]; - auto sep_it = find(reversed(path), '/'); + auto sep_it = find(path | reverse(), '/'); auto& group = sep_it != path.rend() ? get_highlighter(context, {path.begin(), sep_it.base()}) : context.window().highlighters(); diff --git a/src/containers.hh b/src/containers.hh index 871714ef..e37208dc 100644 --- a/src/containers.hh +++ b/src/containers.hh @@ -8,11 +8,21 @@ namespace Kakoune { +template +struct ContainerView { Factory factory; }; + +template +auto operator| (Container&& container, ContainerView view) -> + decltype(view.factory(std::forward(container))) +{ + return view.factory(std::forward(container)); +} + template -struct ReversedContainer +struct ReverseView { using iterator = decltype(std::declval().rbegin()); - ReversedContainer(Container& container) : m_container(container) {} + ReverseView(Container& container) : m_container(container) {} iterator begin() { return m_container.rbegin(); } iterator end() { return m_container.rend(); } @@ -21,166 +31,186 @@ private: Container& m_container; }; -template -ReversedContainer reversed(Container&& container) +struct ReverseFactory { - return ReversedContainer(container); -} - -template -struct FilteredIterator : std::iterator -{ - FilteredIterator(Filter filter, Iterator it, Iterator end) - : m_it{std::move(it)}, m_end{std::move(end)}, m_filter{std::move(filter)} + template + ReverseView operator()(Container&& container) const { - do_filter(); + return {container}; } - - auto operator*() -> decltype(*std::declval()) { return *m_it; } - FilteredIterator& operator++() { ++m_it; do_filter(); return *this; } - FilteredIterator operator++(int) { auto copy = *this; ++(*this); return copy; } - - friend bool operator==(const FilteredIterator& lhs, const FilteredIterator& rhs) - { - return lhs.m_it == rhs.m_it; - } - - friend bool operator!=(const FilteredIterator& lhs, const FilteredIterator& rhs) - { - return not (lhs == rhs); - } - - Iterator base() const { return m_it; } - -private: - void do_filter() - { - while (m_it != m_end and not m_filter(*m_it)) - ++m_it; - } - - Iterator m_it; - Iterator m_end; - Filter m_filter; }; +inline ContainerView reverse() { return {}; } + template -struct FilteredContainer +struct FilterView { - using iterator = FilteredIterator())), Filter>; - FilteredContainer(Container& container, Filter filter) + using ContainerIt = decltype(begin(std::declval())); + + struct Iterator : std::iterator + { + Iterator(const FilterView& view, ContainerIt it, ContainerIt end) + : m_it{std::move(it)}, m_end{std::move(end)}, m_view{view} + { + do_filter(); + } + + auto operator*() -> decltype(*std::declval()) { return *m_it; } + Iterator& operator++() { ++m_it; do_filter(); return *this; } + Iterator operator++(int) { auto copy = *this; ++(*this); return copy; } + + friend bool operator==(const Iterator& lhs, const Iterator& rhs) + { + return lhs.m_it == rhs.m_it; + } + + friend bool operator!=(const Iterator& lhs, const Iterator& rhs) + { + return not (lhs == rhs); + } + + const ContainerIt& base() const { return m_it; } + + private: + void do_filter() + { + while (m_it != m_end and not m_view.m_filter(*m_it)) + ++m_it; + } + + ContainerIt m_it; + ContainerIt m_end; + const FilterView& m_view; + }; + + FilterView(Container& container, Filter filter) : m_container{container}, m_filter{std::move(filter)} {} - iterator begin() const { return {m_filter, m_container.begin(), m_container.end()}; } - iterator end() const { return {m_filter, m_container.end(), m_container.end()}; } + Iterator begin() const { return {*this, m_container.begin(), m_container.end()}; } + Iterator end() const { return {*this, m_container.end(), m_container.end()}; } private: Container& m_container; Filter m_filter; }; -template -FilteredContainer filtered(Container&& container, Filter filter) +template +struct FilterFactory { - return {container, std::move(filter)}; -} + template + FilterView operator()(Container&& container) const { return {container, std::move(m_filter)}; } + + Filter m_filter; +}; + +template +inline ContainerView> filter(Filter f) { return {std::move(f)}; } template using TransformedResult = decltype(std::declval()(*std::declval())); -template -struct TransformedIterator : std::iterator>::type> -{ - TransformedIterator(Transform transform, Iterator it) - : m_it{std::move(it)}, m_transform{std::move(transform)} {} - - auto operator*() -> TransformedResult { return m_transform(*m_it); } - TransformedIterator& operator++() { ++m_it; return *this; } - TransformedIterator operator++(int) { auto copy = *this; ++m_it; return copy; } - - friend bool operator==(const TransformedIterator& lhs, const TransformedIterator& rhs) - { - return lhs.m_it == rhs.m_it; - } - - friend bool operator!=(const TransformedIterator& lhs, const TransformedIterator& rhs) - { - return not (lhs == rhs); - } - - Iterator base() const { return m_it; } - -private: - Iterator m_it; - Transform m_transform; -}; - template -struct TransformedContainer +struct TransformView { - using iterator = TransformedIterator())), Transform>; - TransformedContainer(Container& container, Transform transform) + using ContainerIt = decltype(begin(std::declval())); + + struct Iterator : std::iterator>::type> + { + Iterator(const TransformView& view, ContainerIt it) + : m_it{std::move(it)}, m_view{view} {} + + auto operator*() -> TransformedResult { return m_view.m_transform(*m_it); } + Iterator& operator++() { ++m_it; return *this; } + Iterator operator++(int) { auto copy = *this; ++m_it; return copy; } + + friend bool operator==(const Iterator& lhs, const Iterator& rhs) + { + return lhs.m_it == rhs.m_it; + } + + friend bool operator!=(const Iterator& lhs, const Iterator& rhs) + { + return not (lhs == rhs); + } + + ContainerIt base() const { return m_it; } + + private: + ContainerIt m_it; + const TransformView& m_view; + }; + + TransformView(Container& container, Transform transform) : m_container{container}, m_transform{std::move(transform)} {} - iterator begin() const { return {m_transform, m_container.begin()}; } - iterator end() const { return {m_transform, m_container.end()}; } + Iterator begin() const { return {*this, m_container.begin()}; } + Iterator end() const { return {*this, m_container.end()}; } private: Container& m_container; Transform m_transform; }; -template -TransformedContainer transformed(Container&& container, Transform transform) +template +struct TransformFactory { - return {container, std::move(transform)}; -} + template + TransformView operator()(Container&& container) const { return {container, std::move(m_transform)}; } -template -struct ConcatenatedIterator : std::iterator -{ - static_assert(std::is_convertible::value, ""); - static_assert(std::is_convertible::value, ""); - - ConcatenatedIterator(Iterator1 it1, Iterator1 end1, Iterator2 it2) - : m_it1(std::move(it1)), m_end1(std::move(end1)), m_it2(std::move(it2)) {} - - decltype(*std::declval()) operator*() { return is2() ? *m_it2 : *m_it1; } - ConcatenatedIterator& operator++() { if (is2()) ++m_it2; else ++m_it1; return *this; } - ConcatenatedIterator operator++(int) { auto copy = *this; ++*this; return copy; } - - friend bool operator==(const ConcatenatedIterator& lhs, const ConcatenatedIterator& rhs) - { - return lhs.m_it1 == rhs.m_it1 and lhs.m_end1 == rhs.m_end1 and lhs.m_it2 == rhs.m_it2; - } - - friend bool operator!=(const ConcatenatedIterator& lhs, const ConcatenatedIterator& rhs) - { - return not (lhs == rhs); - } - -private: - bool is2() const { return m_it1 == m_end1; } - - Iterator1 m_it1; - Iterator1 m_end1; - Iterator2 m_it2; + Transform m_transform; }; +template +inline ContainerView> transform(Transform t) { return {std::move(t)}; } + + template -struct ConcatenatedContainer +struct ConcatView { - using iterator = ConcatenatedIterator())), - decltype(begin(std::declval()))>; + using ContainerIt1 = decltype(begin(std::declval())); + using ContainerIt2 = decltype(begin(std::declval())); + using ValueType = typename ContainerIt1::value_type; - ConcatenatedContainer(Container1& container1, Container2& container2) + struct Iterator : std::iterator + { + static_assert(std::is_convertible::value, ""); + static_assert(std::is_convertible::value, ""); + + Iterator(ContainerIt1 it1, ContainerIt1 end1, ContainerIt2 it2) + : m_it1(std::move(it1)), m_end1(std::move(end1)), + m_it2(std::move(it2)) {} + + decltype(*std::declval()) operator*() { return is2() ? *m_it2 : *m_it1; } + Iterator& operator++() { if (is2()) ++m_it2; else ++m_it1; return *this; } + Iterator operator++(int) { auto copy = *this; ++*this; return copy; } + + friend bool operator==(const Iterator& lhs, const Iterator& rhs) + { + return lhs.m_it1 == rhs.m_it1 and lhs.m_end1 == rhs.m_end1 and + lhs.m_it2 == rhs.m_it2; + } + + friend bool operator!=(const Iterator& lhs, const Iterator& rhs) + { + return not (lhs == rhs); + } + + private: + bool is2() const { return m_it1 == m_end1; } + + ContainerIt1 m_it1; + ContainerIt1 m_end1; + ContainerIt2 m_it2; + }; + + ConcatView(Container1& container1, Container2& container2) : m_container1{container1}, m_container2{container2} {} - iterator begin() const { return {m_container1.begin(), m_container1.end(), m_container2.begin()}; } - iterator end() const { return {m_container1.end(), m_container1.end(), m_container2.end()}; } + Iterator begin() const { return {m_container1.begin(), m_container1.end(), m_container2.begin()}; } + Iterator end() const { return {m_container1.end(), m_container1.end(), m_container2.end()}; } private: Container1& m_container1; @@ -188,7 +218,7 @@ private: }; template -ConcatenatedContainer concatenated(Container1&& container1, Container2&& container2) +ConcatView concatenated(Container1&& container1, Container2&& container2) { return {container1, container2}; } diff --git a/src/face_registry.cc b/src/face_registry.cc index 3a5ac6e1..7da57e9c 100644 --- a/src/face_registry.cc +++ b/src/face_registry.cc @@ -95,9 +95,8 @@ CandidateList FaceRegistry::complete_alias_name(StringView prefix, ByteCount cursor_pos) const { return complete(prefix, cursor_pos, - transformed(m_aliases, - [](const AliasMap::value_type& v) -> const String& - { return v.first; })); + m_aliases | transform([](const AliasMap::value_type& v) -> const String& + { return v.first; })); } FaceRegistry::FaceRegistry() diff --git a/src/file.cc b/src/file.cc index 2d3e6a82..6cf9a735 100644 --- a/src/file.cc +++ b/src/file.cc @@ -63,7 +63,7 @@ String parse_filename(StringView filename) std::pair split_path(StringView path) { - auto it = find(reversed(path), '/'); + auto it = find(path | reverse(), '/'); if (it == path.rend()) return { {}, path }; const char* slash = it.base()-1; diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc index d3755734..2d0a7a74 100644 --- a/src/highlighter_group.cc +++ b/src/highlighter_group.cc @@ -52,10 +52,9 @@ Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_p auto candidates = complete( path, cursor_pos, - transformed(filtered(m_highlighters, - [=](const HighlighterMap::Element& hl) - { return not group or hl.value->has_children(); }), - HighlighterMap::get_id)); + m_highlighters | filter([=](const HighlighterMap::Element& hl) + { return not group or hl.value->has_children(); }) + | transform(HighlighterMap::get_id)); return { 0, 0, std::move(candidates) }; } diff --git a/src/highlighters.cc b/src/highlighters.cc index 740320ac..871d549c 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -1303,7 +1303,7 @@ public: return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset); } - auto container = transformed(m_groups, decltype(m_groups)::get_id); + auto container = m_groups | transform(decltype(m_groups)::get_id); return { 0, 0, complete(path, cursor_pos, container) }; } diff --git a/src/hook_manager.cc b/src/hook_manager.cc index 81a00730..389c8504 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -31,7 +31,7 @@ CandidateList HookManager::complete_hook_group(StringView prefix, ByteCount pos_ CandidateList res; for (auto& list : m_hook) { - auto container = transformed(list.value, decltype(list.value)::get_id); + auto container = list.value | transform(decltype(list.value)::get_id); for (auto& c : complete(prefix, pos_in_token, container)) { if (!contains(res, c)) diff --git a/src/main.cc b/src/main.cc index 622543f1..0a9e713e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -61,9 +61,9 @@ void register_env_vars() }, { "buflist", false, [](StringView name, const Context& context) - { return join(transformed(BufferManager::instance(), - [](const SafePtr& b) - { return b->display_name(); }), ':'); } + { return join(BufferManager::instance() | + transform([](const SafePtr& b) + { return b->display_name(); }), ':'); } }, { "timestamp", false, [](StringView name, const Context& context) -> String @@ -520,7 +520,7 @@ int run_server(StringView session, StringView init_command, { // create buffers in reverse order so that the first given buffer // is the most recently created one. - for (auto& file : reversed(files)) + for (auto& file : files | reverse()) { try { diff --git a/src/selection.cc b/src/selection.cc index f24b0939..90580bdd 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -555,8 +555,8 @@ String selection_to_string(const Selection& selection) String selection_list_to_string(const SelectionList& selections) { - return join(transformed(selections, [](const Selection& s) - { return selection_to_string(s); }), + return join(selections | transform([](const Selection& s) + { return selection_to_string(s); }), ':', false); } diff --git a/src/selectors.cc b/src/selectors.cc index 662cd6b0..1ca42a28 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -128,7 +128,7 @@ find_surrounding(Iterator begin, Iterator end, { using RevIt = std::reverse_iterator; auto res = find_closing(RevIt{pos+1}, RevIt{begin}, - reversed(closing), reversed(opening), + closing | reverse(), opening | reverse(), init_level, nestable); if (not res) return {};