diff --git a/src/alias_registry.cc b/src/alias_registry.cc index 9804aefc..96f2e4ef 100644 --- a/src/alias_registry.cc +++ b/src/alias_registry.cc @@ -1,7 +1,7 @@ #include "alias_registry.hh" #include "command_manager.hh" -#include "containers.hh" +#include "ranges.hh" namespace Kakoune { diff --git a/src/buffer.cc b/src/buffer.cc index 147e1bbf..a44cccf1 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -4,12 +4,12 @@ #include "buffer_manager.hh" #include "buffer_utils.hh" #include "client.hh" -#include "containers.hh" #include "context.hh" #include "diff.hh" #include "file.hh" #include "flags.hh" #include "option_types.hh" +#include "ranges.hh" #include "shared_string.hh" #include "unit_tests.hh" #include "utils.hh" diff --git a/src/buffer_manager.cc b/src/buffer_manager.cc index 430f8eff..0c9b052f 100644 --- a/src/buffer_manager.cc +++ b/src/buffer_manager.cc @@ -3,9 +3,9 @@ #include "assert.hh" #include "buffer.hh" #include "client_manager.hh" -#include "containers.hh" #include "exception.hh" #include "file.hh" +#include "ranges.hh" #include "string.hh" namespace Kakoune diff --git a/src/client_manager.cc b/src/client_manager.cc index fd4cfe1a..c721f1db 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -2,10 +2,10 @@ #include "buffer_manager.hh" #include "command_manager.hh" -#include "containers.hh" #include "event_manager.hh" #include "face_registry.hh" #include "file.hh" +#include "ranges.hh" #include "window.hh" namespace Kakoune diff --git a/src/color.cc b/src/color.cc index 26855d20..19df9752 100644 --- a/src/color.cc +++ b/src/color.cc @@ -1,7 +1,7 @@ #include "color.hh" -#include "containers.hh" #include "exception.hh" +#include "ranges.hh" #include "regex.hh" #include diff --git a/src/command_manager.cc b/src/command_manager.cc index 61c4f74c..1d9a5042 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -2,14 +2,14 @@ #include "alias_registry.hh" #include "assert.hh" +#include "buffer_utils.hh" #include "context.hh" #include "flags.hh" +#include "optional.hh" +#include "ranges.hh" #include "register_manager.hh" #include "shell_manager.hh" #include "utils.hh" -#include "optional.hh" -#include "containers.hh" -#include "buffer_utils.hh" #include diff --git a/src/commands.cc b/src/commands.cc index 1e583adb..a52c34e3 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -7,7 +7,6 @@ #include "client_manager.hh" #include "command_manager.hh" #include "completion.hh" -#include "containers.hh" #include "context.hh" #include "event_manager.hh" #include "face_registry.hh" @@ -15,14 +14,15 @@ #include "hash_map.hh" #include "highlighter.hh" #include "highlighters.hh" +#include "insert_completer.hh" #include "option_manager.hh" #include "option_types.hh" #include "parameters_parser.hh" +#include "ranges.hh" #include "ranked_match.hh" -#include "register_manager.hh" -#include "insert_completer.hh" -#include "remote.hh" #include "regex.hh" +#include "register_manager.hh" +#include "remote.hh" #include "shell_manager.hh" #include "string.hh" #include "user_interface.hh" diff --git a/src/containers.hh b/src/containers.hh deleted file mode 100644 index fe986f1a..00000000 --- a/src/containers.hh +++ /dev/null @@ -1,333 +0,0 @@ -#ifndef containers_hh_INCLUDED -#define containers_hh_INCLUDED - -#include -#include -#include -#include - -namespace Kakoune -{ - -template struct ViewFactory { Func func; }; - -template -ViewFactory> -make_view_factory(Func&& func) { return {std::forward(func)}; } - -template -decltype(auto) operator| (Container&& container, ViewFactory factory) -{ - return factory.func(std::forward(container)); -} - -template -struct decay_container_impl { using type = std::decay_t; }; - -template -struct decay_container_impl { using type = Container&; }; - -template -using decay_container = typename decay_container_impl::type; - -template -struct ReverseView -{ - decltype(auto) begin() { return m_container.rbegin(); } - decltype(auto) end() { return m_container.rend(); } - - Container m_container; -}; - -inline auto reverse() -{ - return make_view_factory([](auto&& container) { - using Container = decltype(container); - return ReverseView>{std::forward(container)}; - }); -} - -template -using IteratorOf = decltype(std::begin(std::declval())); - -template -using ValueOf = typename Container::value_type; - -template -struct FilterView -{ - using ContainerIt = IteratorOf; - - struct Iterator : std::iterator::value_type> - { - Iterator(const FilterView& view, ContainerIt it, ContainerIt end) - : m_it{std::move(it)}, m_end{std::move(end)}, m_view{view} - { - do_filter(); - } - - decltype(auto) operator*() { 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; - }; - - Iterator begin() const { return {*this, std::begin(m_container), std::end(m_container)}; } - Iterator end() const { return {*this, std::end(m_container), std::end(m_container)}; } - - Container m_container; - mutable Filter m_filter; -}; - -template -inline auto filter(Filter f) -{ - return make_view_factory([f = std::move(f)](auto&& container) { - using Container = decltype(container); - return FilterView, Filter>{std::forward(container), std::move(f)}; - }); -} - -template -struct TransformView -{ - using ContainerIt = IteratorOf; - using ResType = decltype(std::declval()(*std::declval())); - - struct Iterator : std::iterator> - { - Iterator(const TransformView& view, ContainerIt it) - : m_it{std::move(it)}, m_view{view} {} - - decltype(auto) operator*() { 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; - }; - - Iterator begin() const { return {*this, std::begin(m_container)}; } - Iterator end() const { return {*this, std::end(m_container)}; } - - Container m_container; - mutable Transform m_transform; -}; - -template -inline auto transform(Transform t) -{ - return make_view_factory([t = std::move(t)](auto&& container) { - using Container = decltype(container); - return TransformView, Transform>{std::forward(container), std::move(t)}; - }); -} - -template, - typename ValueTypeParam = void> -struct SplitView -{ - using ContainerIt = IteratorOf; - using ValueType = std::conditional_t::value, - std::pair, IteratorOf>, - ValueTypeParam>; - - struct Iterator : std::iterator - { - Iterator(ContainerIt pos, ContainerIt end, char separator) - : pos(pos), sep(pos), end(end), separator(separator) - { - while (sep != end and *sep != separator) - ++sep; - } - - Iterator& operator++() { advance(); return *this; } - Iterator operator++(int) { auto copy = *this; advance(); return copy; } - - bool operator==(const Iterator& other) const { return pos == other.pos; } - bool operator!=(const Iterator& other) const { return pos != other.pos; } - - ValueType operator*() { return {pos, sep}; } - - private: - void advance() - { - if (sep == end) - { - pos = end; - return; - } - - pos = sep+1; - for (sep = pos; sep != end; ++sep) - { - if (*sep == separator) - break; - } - } - - ContainerIt pos; - ContainerIt sep; - ContainerIt end; - Separator separator; - }; - - Iterator begin() const { return {std::begin(m_container), std::end(m_container), m_separator}; } - Iterator end() const { return {std::end(m_container), std::end(m_container), m_separator}; } - - Container m_container; - Separator m_separator; -}; - -template -auto split(Separator separator) -{ - return make_view_factory([s = std::move(separator)](auto&& container) { - using Container = decltype(container); - return SplitView, Separator, ValueType>{std::forward(container), std::move(s)}; - }); -} - -template -struct ConcatView -{ - using ContainerIt1 = decltype(begin(std::declval())); - using ContainerIt2 = decltype(begin(std::declval())); - using ValueType = typename std::common_type_t::value_type, - typename std::iterator_traits::value_type>; - - struct Iterator : std::iterator - { - static_assert(std::is_convertible::value_type, ValueType>::value, ""); - static_assert(std::is_convertible::value_type, ValueType>::value, ""); - - Iterator(ContainerIt1 it1, ContainerIt1 end1, ContainerIt2 it2) - : m_it1(std::move(it1)), m_end1(std::move(end1)), - m_it2(std::move(it2)) {} - - ValueType 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()}; } - -private: - Container1& m_container1; - Container2& m_container2; -}; - -template -ConcatView concatenated(Container1&& container1, Container2&& container2) -{ - return {container1, container2}; -} - -template -auto find(Container&& container, const T& value) -{ - using std::begin; using std::end; - return std::find(begin(container), end(container), value); -} - -template -auto find_if(Container&& container, T op) -{ - using std::begin; using std::end; - return std::find_if(begin(container), end(container), op); -} - -template -bool contains(Container&& container, const T& value) -{ - using std::end; - return find(container, value) != end(container); -} - -template -bool contains_that(Container&& container, T op) -{ - using std::end; - return find_if(container, op) != end(container); -} - -template -void unordered_erase(Container&& vec, U&& value) -{ - auto it = find(vec, std::forward(value)); - if (it != vec.end()) - { - using std::swap; - swap(vec.back(), *it); - vec.pop_back(); - } -} - -template -Init accumulate(Container&& c, Init&& init, BinOp&& op) -{ - using std::begin; using std::end; - return std::accumulate(begin(c), end(c), init, op); -} - -} - -#endif // containers_hh_INCLUDED diff --git a/src/event_manager.cc b/src/event_manager.cc index 7a0614dc..63f47858 100644 --- a/src/event_manager.cc +++ b/src/event_manager.cc @@ -1,7 +1,7 @@ #include "event_manager.hh" -#include "containers.hh" #include "flags.hh" +#include "ranges.hh" #include diff --git a/src/face_registry.cc b/src/face_registry.cc index f6129554..8d509f04 100644 --- a/src/face_registry.cc +++ b/src/face_registry.cc @@ -1,7 +1,7 @@ #include "face_registry.hh" -#include "containers.hh" #include "exception.hh" +#include "ranges.hh" namespace Kakoune { diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc index eaa8d4bc..4860d59d 100644 --- a/src/highlighter_group.cc +++ b/src/highlighter_group.cc @@ -1,6 +1,6 @@ #include "highlighter_group.hh" -#include "containers.hh" +#include "ranges.hh" namespace Kakoune { diff --git a/src/highlighters.cc b/src/highlighters.cc index 71d0abb9..71ff7a1b 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -3,21 +3,21 @@ #include "assert.hh" #include "buffer_utils.hh" #include "changes.hh" -#include "context.hh" -#include "containers.hh" #include "command_manager.hh" +#include "context.hh" #include "display_buffer.hh" #include "face_registry.hh" #include "highlighter_group.hh" #include "line_modification.hh" #include "option.hh" #include "parameters_parser.hh" -#include "register_manager.hh" +#include "ranges.hh" #include "regex.hh" +#include "register_manager.hh" #include "string.hh" -#include "window.hh" #include "utf8.hh" #include "utf8_iterator.hh" +#include "window.hh" #include #include diff --git a/src/hook_manager.cc b/src/hook_manager.cc index fc274f8a..5e538681 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -1,14 +1,14 @@ #include "hook_manager.hh" -#include "clock.hh" -#include "containers.hh" -#include "context.hh" #include "buffer_utils.hh" +#include "clock.hh" +#include "command_manager.hh" +#include "context.hh" #include "display_buffer.hh" #include "face_registry.hh" -#include "command_manager.hh" -#include "regex.hh" #include "option.hh" +#include "ranges.hh" +#include "regex.hh" namespace Kakoune { diff --git a/src/json_ui.cc b/src/json_ui.cc index e907be24..8f4d4663 100644 --- a/src/json_ui.cc +++ b/src/json_ui.cc @@ -1,13 +1,13 @@ #include "json_ui.hh" -#include "containers.hh" #include "display_buffer.hh" -#include "exception.hh" -#include "keys.hh" -#include "file.hh" #include "event_manager.hh" -#include "value.hh" +#include "exception.hh" +#include "file.hh" +#include "keys.hh" +#include "ranges.hh" #include "unit_tests.hh" +#include "value.hh" #include diff --git a/src/keys.cc b/src/keys.cc index 3b2c7100..8ddea2b4 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -1,7 +1,7 @@ #include "keys.hh" -#include "containers.hh" #include "exception.hh" +#include "ranges.hh" #include "string.hh" #include "unit_tests.hh" #include "utf8_iterator.hh" diff --git a/src/main.cc b/src/main.cc index 81ad37bc..66394627 100644 --- a/src/main.cc +++ b/src/main.cc @@ -6,7 +6,6 @@ #include "client_manager.hh" #include "command_manager.hh" #include "commands.hh" -#include "containers.hh" #include "context.hh" #include "event_manager.hh" #include "face_registry.hh" @@ -17,6 +16,7 @@ #include "ncurses_ui.hh" #include "option_types.hh" #include "parameters_parser.hh" +#include "ranges.hh" #include "regex.hh" #include "register_manager.hh" #include "remote.hh" diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index b9e80e52..b9131462 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -1,9 +1,9 @@ #include "ncurses_ui.hh" -#include "containers.hh" #include "display_buffer.hh" #include "event_manager.hh" #include "keys.hh" +#include "ranges.hh" #include diff --git a/src/normal.cc b/src/normal.cc index bc8d955b..c7b37811 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -3,17 +3,17 @@ #include "buffer.hh" #include "buffer_manager.hh" #include "buffer_utils.hh" -#include "client_manager.hh" #include "changes.hh" +#include "client_manager.hh" #include "command_manager.hh" #include "commands.hh" -#include "containers.hh" #include "context.hh" #include "diff.hh" #include "face_registry.hh" #include "file.hh" #include "flags.hh" #include "option_manager.hh" +#include "ranges.hh" #include "regex.hh" #include "register_manager.hh" #include "selectors.hh" diff --git a/src/option_manager.hh b/src/option_manager.hh index 08bb0aa6..3e2568cb 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -2,12 +2,12 @@ #define option_manager_hh_INCLUDED #include "completion.hh" -#include "containers.hh" #include "exception.hh" -#include "option.hh" -#include "vector.hh" #include "hash_map.hh" +#include "option.hh" +#include "ranges.hh" #include "utils.hh" +#include "vector.hh" #include #include diff --git a/src/option_types.hh b/src/option_types.hh index 1c44ddce..01d7ea3b 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -3,11 +3,11 @@ #include "array_view.hh" #include "coord.hh" -#include "containers.hh" #include "exception.hh" #include "flags.hh" #include "hash_map.hh" #include "option.hh" +#include "ranges.hh" #include "string.hh" #include "units.hh" diff --git a/src/ranges.hh b/src/ranges.hh new file mode 100644 index 00000000..f1c11be8 --- /dev/null +++ b/src/ranges.hh @@ -0,0 +1,333 @@ +#ifndef ranges_hh_INCLUDED +#define ranges_hh_INCLUDED + +#include +#include +#include +#include + +namespace Kakoune +{ + +template struct ViewFactory { Func func; }; + +template +ViewFactory> +make_view_factory(Func&& func) { return {std::forward(func)}; } + +template +decltype(auto) operator| (Range&& range, ViewFactory factory) +{ + return factory.func(std::forward(range)); +} + +template +struct decay_range_impl { using type = std::decay_t; }; + +template +struct decay_range_impl { using type = Range&; }; + +template +using decay_range = typename decay_range_impl::type; + +template +struct ReverseView +{ + decltype(auto) begin() { return m_range.rbegin(); } + decltype(auto) end() { return m_range.rend(); } + + Range m_range; +}; + +inline auto reverse() +{ + return make_view_factory([](auto&& range) { + using Range = decltype(range); + return ReverseView>{std::forward(range)}; + }); +} + +template +using IteratorOf = decltype(std::begin(std::declval())); + +template +using ValueOf = typename Range::value_type; + +template +struct FilterView +{ + using RangeIt = IteratorOf; + + struct Iterator : std::iterator::value_type> + { + Iterator(const FilterView& view, RangeIt it, RangeIt end) + : m_it{std::move(it)}, m_end{std::move(end)}, m_view{view} + { + do_filter(); + } + + decltype(auto) operator*() { 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 RangeIt& base() const { return m_it; } + + private: + void do_filter() + { + while (m_it != m_end and not m_view.m_filter(*m_it)) + ++m_it; + } + + RangeIt m_it; + RangeIt m_end; + const FilterView& m_view; + }; + + Iterator begin() const { return {*this, std::begin(m_range), std::end(m_range)}; } + Iterator end() const { return {*this, std::end(m_range), std::end(m_range)}; } + + Range m_range; + mutable Filter m_filter; +}; + +template +inline auto filter(Filter f) +{ + return make_view_factory([f = std::move(f)](auto&& range) { + using Range = decltype(range); + return FilterView, Filter>{std::forward(range), std::move(f)}; + }); +} + +template +struct TransformView +{ + using RangeIt = IteratorOf; + using ResType = decltype(std::declval()(*std::declval())); + + struct Iterator : std::iterator> + { + Iterator(const TransformView& view, RangeIt it) + : m_it{std::move(it)}, m_view{view} {} + + decltype(auto) operator*() { 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); + } + + RangeIt base() const { return m_it; } + + private: + RangeIt m_it; + const TransformView& m_view; + }; + + Iterator begin() const { return {*this, std::begin(m_range)}; } + Iterator end() const { return {*this, std::end(m_range)}; } + + Range m_range; + mutable Transform m_transform; +}; + +template +inline auto transform(Transform t) +{ + return make_view_factory([t = std::move(t)](auto&& range) { + using Range = decltype(range); + return TransformView, Transform>{std::forward(range), std::move(t)}; + }); +} + +template, + typename ValueTypeParam = void> +struct SplitView +{ + using RangeIt = IteratorOf; + using ValueType = std::conditional_t::value, + std::pair, IteratorOf>, + ValueTypeParam>; + + struct Iterator : std::iterator + { + Iterator(RangeIt pos, RangeIt end, char separator) + : pos(pos), sep(pos), end(end), separator(separator) + { + while (sep != end and *sep != separator) + ++sep; + } + + Iterator& operator++() { advance(); return *this; } + Iterator operator++(int) { auto copy = *this; advance(); return copy; } + + bool operator==(const Iterator& other) const { return pos == other.pos; } + bool operator!=(const Iterator& other) const { return pos != other.pos; } + + ValueType operator*() { return {pos, sep}; } + + private: + void advance() + { + if (sep == end) + { + pos = end; + return; + } + + pos = sep+1; + for (sep = pos; sep != end; ++sep) + { + if (*sep == separator) + break; + } + } + + RangeIt pos; + RangeIt sep; + RangeIt end; + Separator separator; + }; + + Iterator begin() const { return {std::begin(m_range), std::end(m_range), m_separator}; } + Iterator end() const { return {std::end(m_range), std::end(m_range), m_separator}; } + + Range m_range; + Separator m_separator; +}; + +template +auto split(Separator separator) +{ + return make_view_factory([s = std::move(separator)](auto&& range) { + using Range = decltype(range); + return SplitView, Separator, ValueType>{std::forward(range), std::move(s)}; + }); +} + +template +struct ConcatView +{ + using RangeIt1 = decltype(begin(std::declval())); + using RangeIt2 = decltype(begin(std::declval())); + using ValueType = typename std::common_type_t::value_type, + typename std::iterator_traits::value_type>; + + struct Iterator : std::iterator + { + static_assert(std::is_convertible::value_type, ValueType>::value, ""); + static_assert(std::is_convertible::value_type, ValueType>::value, ""); + + Iterator(RangeIt1 it1, RangeIt1 end1, RangeIt2 it2) + : m_it1(std::move(it1)), m_end1(std::move(end1)), + m_it2(std::move(it2)) {} + + ValueType 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; } + + RangeIt1 m_it1; + RangeIt1 m_end1; + RangeIt2 m_it2; + }; + + ConcatView(Range1& range1, Range2& range2) + : m_range1(range1), m_range2(range2) {} + + Iterator begin() const { return {m_range1.begin(), m_range1.end(), m_range2.begin()}; } + Iterator end() const { return {m_range1.end(), m_range1.end(), m_range2.end()}; } + +private: + Range1& m_range1; + Range2& m_range2; +}; + +template +ConcatView concatenated(Range1&& range1, Range2&& range2) +{ + return {range1, range2}; +} + +template +auto find(Range&& range, const T& value) +{ + using std::begin; using std::end; + return std::find(begin(range), end(range), value); +} + +template +auto find_if(Range&& range, T op) +{ + using std::begin; using std::end; + return std::find_if(begin(range), end(range), op); +} + +template +bool contains(Range&& range, const T& value) +{ + using std::end; + return find(range, value) != end(range); +} + +template +bool contains_that(Range&& range, T op) +{ + using std::end; + return find_if(range, op) != end(range); +} + +template +void unordered_erase(Range&& vec, U&& value) +{ + auto it = find(vec, std::forward(value)); + if (it != vec.end()) + { + using std::swap; + swap(vec.back(), *it); + vec.pop_back(); + } +} + +template +Init accumulate(Range&& c, Init&& init, BinOp&& op) +{ + using std::begin; using std::end; + return std::accumulate(begin(c), end(c), init, op); +} + +} + +#endif // ranges_hh_INCLUDED diff --git a/src/string.cc b/src/string.cc index f14abddb..baebf29f 100644 --- a/src/string.cc +++ b/src/string.cc @@ -1,9 +1,9 @@ #include "string.hh" #include "exception.hh" -#include "containers.hh" -#include "utf8_iterator.hh" +#include "ranges.hh" #include "unit_tests.hh" +#include "utf8_iterator.hh" #include diff --git a/src/unicode.hh b/src/unicode.hh index 1355d687..5ce8cd6a 100644 --- a/src/unicode.hh +++ b/src/unicode.hh @@ -5,9 +5,9 @@ #include #include -#include "units.hh" #include "array_view.hh" -#include "containers.hh" +#include "ranges.hh" +#include "units.hh" namespace Kakoune {