diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-08-29 15:23:03 +0700 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-08-29 15:23:03 +0700 |
| commit | ab6a99943140cdc3892df1c491efc7838db4cb88 (patch) | |
| tree | e7121edab33080d5319cdc5eda1276071326ee84 | |
| parent | c0a0ba3c0afe1f782e5667466e049b61465d9d0d (diff) | |
Rename containers.hh to ranges.hh (and Container to Range)
| -rw-r--r-- | src/alias_registry.cc | 2 | ||||
| -rw-r--r-- | src/buffer.cc | 2 | ||||
| -rw-r--r-- | src/buffer_manager.cc | 2 | ||||
| -rw-r--r-- | src/client_manager.cc | 2 | ||||
| -rw-r--r-- | src/color.cc | 2 | ||||
| -rw-r--r-- | src/command_manager.cc | 6 | ||||
| -rw-r--r-- | src/commands.cc | 6 | ||||
| -rw-r--r-- | src/containers.hh | 333 | ||||
| -rw-r--r-- | src/event_manager.cc | 2 | ||||
| -rw-r--r-- | src/face_registry.cc | 2 | ||||
| -rw-r--r-- | src/highlighter_group.cc | 2 | ||||
| -rw-r--r-- | src/highlighters.cc | 8 | ||||
| -rw-r--r-- | src/hook_manager.cc | 8 | ||||
| -rw-r--r-- | src/json_ui.cc | 8 | ||||
| -rw-r--r-- | src/keys.cc | 2 | ||||
| -rw-r--r-- | src/main.cc | 2 | ||||
| -rw-r--r-- | src/ncurses_ui.cc | 2 | ||||
| -rw-r--r-- | src/normal.cc | 4 | ||||
| -rw-r--r-- | src/option_manager.hh | 6 | ||||
| -rw-r--r-- | src/option_types.hh | 2 | ||||
| -rw-r--r-- | src/ranges.hh | 333 | ||||
| -rw-r--r-- | src/string.cc | 4 | ||||
| -rw-r--r-- | src/unicode.hh | 4 |
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 { |
