Add a SplitView container view

This commit is contained in:
Maxime Coste 2016-03-25 00:14:56 +00:00
parent 87704227ad
commit d3ef2d36ea
5 changed files with 84 additions and 6 deletions

View File

@ -49,10 +49,16 @@ struct ReverseFactory
inline ContainerView<ReverseFactory> reverse() { return {}; } 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> template<typename Container, typename Filter>
struct FilterView struct FilterView
{ {
using ContainerIt = decltype(begin(std::declval<Container>())); using ContainerIt = IteratorOf<Container>;
struct Iterator : std::iterator<std::forward_iterator_tag, struct Iterator : std::iterator<std::forward_iterator_tag,
typename ContainerIt::value_type> typename ContainerIt::value_type>
@ -119,7 +125,7 @@ using TransformedResult = decltype(std::declval<T>()(*std::declval<I>()));
template<typename Container, typename Transform> template<typename Container, typename Transform>
struct TransformView struct TransformView
{ {
using ContainerIt = decltype(begin(std::declval<Container>())); using ContainerIt = IteratorOf<Container>;
struct Iterator : std::iterator<std::forward_iterator_tag, struct Iterator : std::iterator<std::forward_iterator_tag,
typename std::remove_reference<TransformedResult<ContainerIt, Transform>>::type> typename std::remove_reference<TransformedResult<ContainerIt, Transform>>::type>
@ -170,6 +176,78 @@ struct TransformFactory
template<typename Transform> template<typename Transform>
inline ContainerView<TransformFactory<Transform>> transform(Transform t) { return {{std::move(t)}}; } 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> template<typename Container1, typename Container2>
struct ConcatView struct ConcatView

View File

@ -54,7 +54,7 @@ EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags)
{ {
constexpr auto desc = enum_desc(Flags{}); constexpr auto desc = enum_desc(Flags{});
flags = 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; }); auto it = find_if(desc, [s](const EnumDesc<Flags>& d) { return d.name == s; });
if (it == desc.end()) if (it == desc.end())

View File

@ -449,7 +449,7 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
static UnorderedMap<String, CommandCache, MemoryDomain::Commands> command_cache; static UnorderedMap<String, CommandCache, MemoryDomain::Commands> command_cache;
Vector<RankedMatch> matches; 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(); auto dirname = ((not dir.empty() and dir.back() == '/') ? dir.substr(0, dir.length()-1) : dir).str();

View File

@ -1385,7 +1385,7 @@ void restore_selections(Context& context, NormalParams params)
size_t timestamp = str_to_int({percent + 1, desc.end()}); size_t timestamp = str_to_int({percent + 1, desc.end()});
Vector<Selection> sels; 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)); sels.push_back(selection_from_string(sel_desc));
SelectionList sel_list{buffer, std::move(sels), timestamp}; SelectionList sel_list{buffer, std::move(sels), timestamp};

View File

@ -587,7 +587,7 @@ Selection selection_from_string(StringView desc)
SelectionList selection_list_from_string(Buffer& buffer, StringView desc) SelectionList selection_list_from_string(Buffer& buffer, StringView desc)
{ {
Vector<Selection> sels; Vector<Selection> sels;
for (auto sel_desc : split(desc, ':')) for (auto sel_desc : desc | split<StringView>(':'))
sels.push_back(selection_from_string(sel_desc)); sels.push_back(selection_from_string(sel_desc));
return {buffer, std::move(sels)}; return {buffer, std::move(sels)};
} }