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:
2023-08-06 13:52:46 +02:00
parent 1549ef27a7
commit a1f1717e22
6 changed files with 346 additions and 1 deletions

View File

@@ -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