Added ProcessStream to for running processes (on Linux) and streaming their output.
Added map() function for creating a mapping iterator. Added mijin::pipe types for map() and join().
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#define MIJIN_UTIL_ITERATORS_HPP_INCLUDED 1
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
@@ -247,6 +248,94 @@ auto replace(
|
||||
};
|
||||
}
|
||||
|
||||
template<typename TIterator, typename TFunctor>
|
||||
struct MappingIterator
|
||||
{
|
||||
using orig_value_type = typename std::iterator_traits<TIterator>::value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = std::invoke_result_t<TFunctor, orig_value_type>;
|
||||
using iterator_category = std::bidirectional_iterator_tag; // TODO?
|
||||
|
||||
TIterator base;
|
||||
TFunctor functor;
|
||||
|
||||
MappingIterator(TIterator base_, TFunctor functor_) noexcept : base(base_), functor(std::move(functor_)) {}
|
||||
MappingIterator(const MappingIterator&) noexcept = default;
|
||||
MappingIterator(MappingIterator&&) noexcept = default;
|
||||
|
||||
MappingIterator& operator=(const MappingIterator&) noexcept = default;
|
||||
MappingIterator& operator=(MappingIterator&&) noexcept = default;
|
||||
|
||||
value_type operator*() const noexcept
|
||||
{
|
||||
return functor(*base);
|
||||
}
|
||||
|
||||
MappingIterator& operator++() noexcept
|
||||
{
|
||||
++base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MappingIterator operator++(int) noexcept
|
||||
{
|
||||
ReplacingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
MappingIterator& operator--() noexcept
|
||||
{
|
||||
--base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MappingIterator operator--(int) noexcept
|
||||
{
|
||||
EnumeratingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const MappingIterator& other) const noexcept
|
||||
{
|
||||
return functor == other.functor && base == other.base;
|
||||
}
|
||||
|
||||
bool operator!=(const MappingIterator& other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TIterable, typename TFunctor>
|
||||
struct MappingRange : RangeAdapter
|
||||
{
|
||||
using value_type = typename std::iterator_traits<decltype(std::begin(std::declval<TIterable>()))>::value_type;
|
||||
|
||||
RangeRef<TIterable> base;
|
||||
TFunctor functor;
|
||||
|
||||
auto begin() const noexcept
|
||||
{
|
||||
return MappingIterator(base.begin(), functor);
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
{
|
||||
return MappingIterator(base.end(), functor);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TIterable, typename TFunctor>
|
||||
auto map(TIterable&& iterable, TFunctor&& functor)
|
||||
{
|
||||
return MappingRange<TIterable, TFunctor>{
|
||||
.base = {std::forward<TIterable>(iterable)},
|
||||
.functor = std::forward<TFunctor>(functor)
|
||||
};
|
||||
}
|
||||
|
||||
template<typename TFirstIterator, typename TSecondIterator>
|
||||
struct ChainingIterator
|
||||
{
|
||||
@@ -419,6 +508,22 @@ auto operator|(Chain2<TFirstIterable> chain2, TSecondIterable&& secondIterable)
|
||||
{
|
||||
return chain(chain2.range.range, std::forward<TSecondIterable>(secondIterable));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct Map
|
||||
{
|
||||
T functor;
|
||||
|
||||
explicit Map(T functor_) : functor(std::move(functor_)) {}
|
||||
};
|
||||
template<typename T>
|
||||
Map(T) -> Map<T>;
|
||||
|
||||
template<typename TIterable, typename TFunctor>
|
||||
auto operator|(TIterable&& iterable, Map<TFunctor> mapper)
|
||||
{
|
||||
return map(std::forward<TIterable>(iterable), std::move(mapper.functor));
|
||||
}
|
||||
}
|
||||
} // namespace mijin
|
||||
|
||||
|
||||
Reference in New Issue
Block a user