// The transform iterator transforms values from the base iterator with a given // transformation function. It can serve as a replacement for std::transform(), i.e. // std::copy(MakeTransformIterator(begin, f), MakeTransformIterator(end, f), out) // is equivalent to // std::transform(begin, end, f) // If the function returns an l-value reference or a wrapper that supports assignment, // the TransformIterator can be used also as an output iterator, i.e. // std::copy(begin, end, MakeTransformIterator(out, f)) // is equivalent to // for (auto it = begin; it != end; ++it) { // f(*out++) = *it; // } template <typename BaseIterator, typename Function> class TransformIterator { private:
static_assert(std::is_base_of_v<std::input_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "Transform iterator base must be an input iterator.");
using BaseReference = typename std::iterator_traits<BaseIterator>::reference; using InputType = std::conditional_t<std::is_same_v<BaseReference, void>, typename std::iterator_traits<BaseIterator>::value_type,
BaseReference>; using ResultType = std::invoke_result_t<Function, InputType>;
public: using iterator_category = typename std::iterator_traits<BaseIterator>::iterator_category; using value_type = std::remove_const_t<std::remove_reference_t<ResultType>>; using difference_type = typename std::iterator_traits<BaseIterator>::difference_type; using pointer = std::conditional_t<std::is_reference_v<ResultType>,
std::add_pointer_t<std::remove_reference_t<ResultType>>,
TransformIterator>; using reference = ResultType;
TransformIterator(BaseIterator base, Function fn)
: data_(base, fn) { }
TransformIterator& operator--() {
static_assert(std::is_base_of_v<std::bidirectional_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "BaseIterator must be bidirectional iterator to use operator--()");
--data_.base_; return *this;
}
reference operator[](difference_type n) const {
static_assert(std::is_base_of_v<std::random_access_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "BaseIterator must be random access iterator to use operator[]"); return GetFunction()(base()[n]);
}
TransformIterator operator+(difference_type n) const {
static_assert(std::is_base_of_v<std::random_access_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "BaseIterator must be random access iterator to use operator+"); return TransformIterator(base() + n, GetFunction());
}
TransformIterator operator-(difference_type n) const {
static_assert(std::is_base_of_v<std::random_access_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "BaseIterator must be random access iterator to use operator-"); return TransformIterator(base() - n, GetFunction());
}
difference_type operator-(const TransformIterator& other) const {
static_assert(std::is_base_of_v<std::random_access_iterator_tag, typename std::iterator_traits<BaseIterator>::iterator_category>, "BaseIterator must be random access iterator to use operator-"); return base() - other.base();
}
// Retrieve the base iterator.
BaseIterator base() const { return data_.base_;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.