summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-08-29 15:23:03 +0700
committerMaxime Coste <mawww@kakoune.org>2017-08-29 15:23:03 +0700
commitab6a99943140cdc3892df1c491efc7838db4cb88 (patch)
treee7121edab33080d5319cdc5eda1276071326ee84
parentc0a0ba3c0afe1f782e5667466e049b61465d9d0d (diff)
Rename containers.hh to ranges.hh (and Container to Range)
-rw-r--r--src/alias_registry.cc2
-rw-r--r--src/buffer.cc2
-rw-r--r--src/buffer_manager.cc2
-rw-r--r--src/client_manager.cc2
-rw-r--r--src/color.cc2
-rw-r--r--src/command_manager.cc6
-rw-r--r--src/commands.cc6
-rw-r--r--src/containers.hh333
-rw-r--r--src/event_manager.cc2
-rw-r--r--src/face_registry.cc2
-rw-r--r--src/highlighter_group.cc2
-rw-r--r--src/highlighters.cc8
-rw-r--r--src/hook_manager.cc8
-rw-r--r--src/json_ui.cc8
-rw-r--r--src/keys.cc2
-rw-r--r--src/main.cc2
-rw-r--r--src/ncurses_ui.cc2
-rw-r--r--src/normal.cc4
-rw-r--r--src/option_manager.hh6
-rw-r--r--src/option_types.hh2
-rw-r--r--src/ranges.hh333
-rw-r--r--src/string.cc4
-rw-r--r--src/unicode.hh4
23 files changed, 372 insertions, 372 deletions
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 <cstdio>
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 <algorithm>
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 "regex.hh"
#include "register_manager.hh"
-#include "insert_completer.hh"
#include "remote.hh"
-#include "regex.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 <algorithm>
-#include <utility>
-#include <iterator>
-#include <numeric>
-
-namespace Kakoune
-{
-
-template<typename Func> struct ViewFactory { Func func; };
-
-template<typename Func>
-ViewFactory<std::decay_t<Func>>
-make_view_factory(Func&& func) { return {std::forward<Func>(func)}; }
-
-template<typename Container, typename Func>
-decltype(auto) operator| (Container&& container, ViewFactory<Func> factory)
-{
- return factory.func(std::forward<Container>(container));
-}
-
-template<typename Container>
-struct decay_container_impl { using type = std::decay_t<Container>; };
-
-template<typename Container>
-struct decay_container_impl<Container&> { using type = Container&; };
-
-template<typename Container>
-using decay_container = typename decay_container_impl<Container>::type;
-
-template<typename Container>
-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<decay_container<Container>>{std::forward<Container>(container)};
- });
-}
-
-template<typename Container>
-using IteratorOf = decltype(std::begin(std::declval<Container>()));
-
-template<typename Container>
-using ValueOf = typename Container::value_type;
-
-template<typename Container, typename Filter>
-struct FilterView
-{
- using ContainerIt = IteratorOf<Container>;
-
- struct Iterator : std::iterator<std::forward_iterator_tag,
- typename std::iterator_traits<ContainerIt>::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<typename Filter>
-inline auto filter(Filter f)
-{
- return make_view_factory([f = std::move(f)](auto&& container) {
- using Container = decltype(container);
- return FilterView<decay_container<Container>, Filter>{std::forward<Container>(container), std::move(f)};
- });
-}
-
-template<typename Container, typename Transform>
-struct TransformView
-{
- using ContainerIt = IteratorOf<Container>;
- using ResType = decltype(std::declval<Transform>()(*std::declval<ContainerIt>()));
-
- struct Iterator : std::iterator<std::forward_iterator_tag, std::remove_reference_t<ResType>>
- {
- 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<typename Transform>
-inline auto transform(Transform t)
-{
- return make_view_factory([t = std::move(t)](auto&& container) {
- using Container = decltype(container);
- return TransformView<decay_container<Container>, Transform>{std::forward<Container>(container), std::move(t)};
- });
-}
-
-template<typename Container, typename Separator = ValueOf<Container>,
- typename ValueTypeParam = void>
-struct SplitView
-{
- using ContainerIt = IteratorOf<Container>;
- using ValueType = std::conditional_t<std::is_same<void, ValueTypeParam>::value,
- std::pair<IteratorOf<Container>, IteratorOf<Container>>,
- ValueTypeParam>;
-
- struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
- {
- 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<typename ValueType = void, typename Separator>
-auto split(Separator separator)
-{
- return make_view_factory([s = std::move(separator)](auto&& container) {
- using Container = decltype(container);
- return SplitView<decay_container<Container>, Separator, ValueType>{std::forward<Container>(container), std::move(s)};
- });
-}
-
-template<typename Container1, typename Container2>
-struct ConcatView
-{
- using ContainerIt1 = decltype(begin(std::declval<Container1>()));
- using ContainerIt2 = decltype(begin(std::declval<Container2>()));
- using ValueType = typename std::common_type_t<typename std::iterator_traits<ContainerIt1>::value_type,
- typename std::iterator_traits<ContainerIt2>::value_type>;
-
- struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
- {
- static_assert(std::is_convertible<typename std::iterator_traits<ContainerIt1>::value_type, ValueType>::value, "");
- static_assert(std::is_convertible<typename std::iterator_traits<ContainerIt2>::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<typename Container1, typename Container2>
-ConcatView<Container1, Container2> concatenated(Container1&& container1, Container2&& container2)
-{
- return {container1, container2};
-}
-
-template<typename Container, typename T>
-auto find(Container&& container, const T& value)
-{
- using std::begin; using std::end;
- return std::find(begin(container), end(container), value);
-}
-
-template<typename Container, typename T>
-auto find_if(Container&& container, T op)
-{
- using std::begin; using std::end;
- return std::find_if(begin(container), end(container), op);
-}
-
-template<typename Container, typename T>
-bool contains(Container&& container, const T& value)
-{
- using std::end;
- return find(container, value) != end(container);
-}
-
-template<typename Container, typename T>
-bool contains_that(Container&& container, T op)
-{
- using std::end;
- return find_if(container, op) != end(container);
-}
-
-template<typename Container, typename U>
-void unordered_erase(Container&& vec, U&& value)
-{
- auto it = find(vec, std::forward<U>(value));
- if (it != vec.end())
- {
- using std::swap;
- swap(vec.back(), *it);
- vec.pop_back();
- }
-}
-
-template<typename Container, typename Init, typename BinOp>
-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 <unistd.h>
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 <locale>
#include <cstdio>
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 "buffer_utils.hh"
#include "clock.hh"
-#include "containers.hh"
+#include "command_manager.hh"
#include "context.hh"
-#include "buffer_utils.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 "event_manager.hh"
#include "exception.hh"
-#include "keys.hh"
#include "file.hh"
-#include "event_manager.hh"
-#include "value.hh"
+#include "keys.hh"
+#include "ranges.hh"
#include "unit_tests.hh"
+#include "value.hh"
#include <utility>
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 <algorithm>
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 <memory>
#include <type_traits>
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 <algorithm>
+#include <utility>
+#include <iterator>
+#include <numeric>
+
+namespace Kakoune
+{
+
+template<typename Func> struct ViewFactory { Func func; };
+
+template<typename Func>
+ViewFactory<std::decay_t<Func>>
+make_view_factory(Func&& func) { return {std::forward<Func>(func)}; }
+
+template<typename Range, typename Func>
+decltype(auto) operator| (Range&& range, ViewFactory<Func> factory)
+{
+ return factory.func(std::forward<Range>(range));
+}
+
+template<typename Range>
+struct decay_range_impl { using type = std::decay_t<Range>; };
+
+template<typename Range>
+struct decay_range_impl<Range&> { using type = Range&; };
+
+template<typename Range>
+using decay_range = typename decay_range_impl<Range>::type;
+
+template<typename Range>
+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<decay_range<Range>>{std::forward<Range>(range)};
+ });
+}
+
+template<typename Range>
+using IteratorOf = decltype(std::begin(std::declval<Range>()));
+
+template<typename Range>
+using ValueOf = typename Range::value_type;
+
+template<typename Range, typename Filter>
+struct FilterView
+{
+ using RangeIt = IteratorOf<Range>;
+
+ struct Iterator : std::iterator<std::forward_iterator_tag,
+ typename std::iterator_traits<RangeIt>::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<typename Filter>
+inline auto filter(Filter f)
+{
+ return make_view_factory([f = std::move(f)](auto&& range) {
+ using Range = decltype(range);
+ return FilterView<decay_range<Range>, Filter>{std::forward<Range>(range), std::move(f)};
+ });
+}
+
+template<typename Range, typename Transform>
+struct TransformView
+{
+ using RangeIt = IteratorOf<Range>;
+ using ResType = decltype(std::declval<Transform>()(*std::declval<RangeIt>()));
+
+ struct Iterator : std::iterator<std::forward_iterator_tag, std::remove_reference_t<ResType>>
+ {
+ 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<typename Transform>
+inline auto transform(Transform t)
+{
+ return make_view_factory([t = std::move(t)](auto&& range) {
+ using Range = decltype(range);
+ return TransformView<decay_range<Range>, Transform>{std::forward<Range>(range), std::move(t)};
+ });
+}
+
+template<typename Range, typename Separator = ValueOf<Range>,
+ typename ValueTypeParam = void>
+struct SplitView
+{
+ using RangeIt = IteratorOf<Range>;
+ using ValueType = std::conditional_t<std::is_same<void, ValueTypeParam>::value,
+ std::pair<IteratorOf<Range>, IteratorOf<Range>>,
+ ValueTypeParam>;
+
+ struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
+ {
+ 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<typename ValueType = void, typename Separator>
+auto split(Separator separator)
+{
+ return make_view_factory([s = std::move(separator)](auto&& range) {
+ using Range = decltype(range);
+ return SplitView<decay_range<Range>, Separator, ValueType>{std::forward<Range>(range), std::move(s)};
+ });
+}
+
+template<typename Range1, typename Range2>
+struct ConcatView
+{
+ using RangeIt1 = decltype(begin(std::declval<Range1>()));
+ using RangeIt2 = decltype(begin(std::declval<Range2>()));
+ using ValueType = typename std::common_type_t<typename std::iterator_traits<RangeIt1>::value_type,
+ typename std::iterator_traits<RangeIt2>::value_type>;
+
+ struct Iterator : std::iterator<std::forward_iterator_tag, ValueType>
+ {
+ static_assert(std::is_convertible<typename std::iterator_traits<RangeIt1>::value_type, ValueType>::value, "");
+ static_assert(std::is_convertible<typename std::iterator_traits<RangeIt2>::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<typename Range1, typename Range2>
+ConcatView<Range1, Range2> concatenated(Range1&& range1, Range2&& range2)
+{
+ return {range1, range2};
+}
+
+template<typename Range, typename T>
+auto find(Range&& range, const T& value)
+{
+ using std::begin; using std::end;
+ return std::find(begin(range), end(range), value);
+}
+
+template<typename Range, typename T>
+auto find_if(Range&& range, T op)
+{
+ using std::begin; using std::end;
+ return std::find_if(begin(range), end(range), op);
+}
+
+template<typename Range, typename T>
+bool contains(Range&& range, const T& value)
+{
+ using std::end;
+ return find(range, value) != end(range);
+}
+
+template<typename Range, typename T>
+bool contains_that(Range&& range, T op)
+{
+ using std::end;
+ return find_if(range, op) != end(range);
+}
+
+template<typename Range, typename U>
+void unordered_erase(Range&& vec, U&& value)
+{
+ auto it = find(vec, std::forward<U>(value));
+ if (it != vec.end())
+ {
+ using std::swap;
+ swap(vec.back(), *it);
+ vec.pop_back();
+ }
+}
+
+template<typename Range, typename Init, typename BinOp>
+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 <cstdio>
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 <cwchar>
#include <locale>
-#include "units.hh"
#include "array_view.hh"
-#include "containers.hh"
+#include "ranges.hh"
+#include "units.hh"
namespace Kakoune
{