diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2016-03-25 00:14:56 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2016-03-25 20:38:26 +0000 |
| commit | d3ef2d36ead57e6a0490cebba3cdbc434c729e24 (patch) | |
| tree | af4b0c911d3593d6d3104a66974649ca14537f11 /src | |
| parent | 87704227ad9bef1d09ed3620977d106bf0a16485 (diff) | |
Add a SplitView container view
Diffstat (limited to 'src')
| -rw-r--r-- | src/containers.hh | 82 | ||||
| -rw-r--r-- | src/enum.hh | 2 | ||||
| -rw-r--r-- | src/file.cc | 2 | ||||
| -rw-r--r-- | src/normal.cc | 2 | ||||
| -rw-r--r-- | src/selection.cc | 2 |
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)}; } |
