Add a SplitView container view
This commit is contained in:
parent
87704227ad
commit
d3ef2d36ea
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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)};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user