Rename containers.hh to ranges.hh (and Container to Range)
This commit is contained in:
parent
c0a0ba3c0a
commit
ab6a999431
|
@ -1,7 +1,7 @@
|
|||
#include "alias_registry.hh"
|
||||
|
||||
#include "command_manager.hh"
|
||||
#include "containers.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "color.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "exception.hh"
|
||||
#include "ranges.hh"
|
||||
#include "regex.hh"
|
||||
|
||||
#include <cstdio>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -1,7 +1,7 @@
|
|||
#include "event_manager.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "flags.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "face_registry.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "exception.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "highlighter_group.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 <utility>
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
333
src/ranges.hh
Normal file
333
src/ranges.hh
Normal file
|
@ -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
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user