summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-03-25 00:14:56 +0000
committerMaxime Coste <frrrwww@gmail.com>2016-03-25 20:38:26 +0000
commitd3ef2d36ead57e6a0490cebba3cdbc434c729e24 (patch)
treeaf4b0c911d3593d6d3104a66974649ca14537f11 /src
parent87704227ad9bef1d09ed3620977d106bf0a16485 (diff)
Add a SplitView container view
Diffstat (limited to 'src')
-rw-r--r--src/containers.hh82
-rw-r--r--src/enum.hh2
-rw-r--r--src/file.cc2
-rw-r--r--src/normal.cc2
-rw-r--r--src/selection.cc2
5 files changed, 84 insertions, 6 deletions
diff --git a/src/containers.hh b/src/containers.hh
index b0fc58e3..675a7fb5 100644
--- a/src/containers.hh
+++ b/src/containers.hh
@@ -49,10 +49,16 @@ struct ReverseFactory
inline ContainerView<ReverseFactory> reverse() { return {}; }
+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 = decltype(begin(std::declval<Container>()));
+ using ContainerIt = IteratorOf<Container>;
struct Iterator : std::iterator<std::forward_iterator_tag,
typename ContainerIt::value_type>
@@ -119,7 +125,7 @@ using TransformedResult = decltype(std::declval<T>()(*std::declval<I>()));
template<typename Container, typename Transform>
struct TransformView
{
- using ContainerIt = decltype(begin(std::declval<Container>()));
+ using ContainerIt = IteratorOf<Container>;
struct Iterator : std::iterator<std::forward_iterator_tag,
typename std::remove_reference<TransformedResult<ContainerIt, Transform>>::type>
@@ -170,6 +176,78 @@ struct TransformFactory
template<typename Transform>
inline ContainerView<TransformFactory<Transform>> transform(Transform t) { return {{std::move(t)}}; }
+template<typename Container, typename Separator = ValueOf<Container>,
+ typename ValueTypeParam = void>
+struct SplitView
+{
+ using ContainerIt = IteratorOf<Container>;
+ using ValueType = typename std::conditional<std::is_same<void, ValueTypeParam>::value,
+ std::pair<IteratorOf<Container>, IteratorOf<Container>>,
+ ValueTypeParam>::type;
+
+ 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 {m_container.begin(), m_container.end(), m_separator}; }
+ Iterator end() const { return {m_container.end(), m_container.end(), m_separator}; }
+
+ Container m_container;
+ Separator m_separator;
+};
+
+template<typename ValueType, typename Separator>
+struct SplitViewFactory
+{
+ template<typename Container>
+ SplitView<RemoveReference<Container>, Separator, ValueType>
+ operator()(Container&& container) const { return {std::move(container), std::move(separator)}; }
+
+ template<typename Container>
+ SplitView<Container&, Separator, ValueType>
+ operator()(Container& container) const { return {container, std::move(separator)}; }
+
+ Separator separator;
+};
+
+template<typename ValueType = void, typename Separator>
+ContainerView<SplitViewFactory<ValueType, Separator>> split(Separator separator) { return {{std::move(separator)}}; }
template<typename Container1, typename Container2>
struct ConcatView
diff --git a/src/enum.hh b/src/enum.hh
index 728a56d2..6f4a4bdb 100644
--- a/src/enum.hh
+++ b/src/enum.hh
@@ -54,7 +54,7 @@ EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags)
{
constexpr auto desc = enum_desc(Flags{});
flags = Flags{};
- for (auto s : split(str, '|'))
+ for (auto s : str | split<StringView>('|'))
{
auto it = find_if(desc, [s](const EnumDesc<Flags>& d) { return d.name == s; });
if (it == desc.end())
diff --git a/src/file.cc b/src/file.cc
index 6cf9a735..a558dc29 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -449,7 +449,7 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
static UnorderedMap<String, CommandCache, MemoryDomain::Commands> command_cache;
Vector<RankedMatch> matches;
- for (auto dir : split(getenv("PATH"), ':'))
+ for (auto dir : StringView{getenv("PATH")} | split<StringView>(':'))
{
auto dirname = ((not dir.empty() and dir.back() == '/') ? dir.substr(0, dir.length()-1) : dir).str();
diff --git a/src/normal.cc b/src/normal.cc
index ab08da9b..13ecd9e2 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -1385,7 +1385,7 @@ void restore_selections(Context& context, NormalParams params)
size_t timestamp = str_to_int({percent + 1, desc.end()});
Vector<Selection> sels;
- for (auto sel_desc : split({desc.begin(), arobase}, ':'))
+ for (auto sel_desc : StringView{desc.begin(), arobase} | split<StringView>(':'))
sels.push_back(selection_from_string(sel_desc));
SelectionList sel_list{buffer, std::move(sels), timestamp};
diff --git a/src/selection.cc b/src/selection.cc
index 8d9c7274..a2b2d1f2 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -587,7 +587,7 @@ Selection selection_from_string(StringView desc)
SelectionList selection_list_from_string(Buffer& buffer, StringView desc)
{
Vector<Selection> sels;
- for (auto sel_desc : split(desc, ':'))
+ for (auto sel_desc : desc | split<StringView>(':'))
sels.push_back(selection_from_string(sel_desc));
return {buffer, std::move(sels)};
}