/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2010-2018 Danny Robson <danny@nerdcruft.net> */ #pragma once namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// template <typename OutputIt, typename FunctionT> OutputIt _transform_by_block ( const cruft::view<OutputIt> &, OutputIt cursor, FunctionT && ) { return cursor; } //------------------------------------------------------------------------- template <typename OutputIt, typename FunctionT, typename InputT, typename ...TailT> OutputIt _transform_by_block ( const cruft::view<OutputIt> &dst, OutputIt cursor, FunctionT &&func, const InputT &_src, TailT &&...tail ) { auto remain = _src; if (cursor != dst.begin ()) { auto infill = std::distance (cursor, dst.end ()); if (remain.size () < static_cast<size_t> (infill)) { return _transform_by_block ( dst, std::copy_n (remain.begin (), remain.size (), cursor), std::forward<FunctionT> (func), std::forward<TailT> (tail)... ); } std::copy_n (remain.begin (), infill, cursor); func (dst); cursor = dst.begin (); remain = { remain.begin () + infill, remain.end () }; } while (remain.size () >= dst.size ()) { std::copy_n (remain.begin (), dst.size (), dst.begin ()); func (dst); remain = { remain.begin () + dst.size (), remain.end () }; } return _transform_by_block ( dst, std::copy (remain.begin (), remain.end (), cursor), std::forward<FunctionT> (func), std::forward<TailT> (tail)... ); } //------------------------------------------------------------------------- template <typename OutputIt, typename FunctionT, typename ...Args> OutputIt transform_by_block (const cruft::view<OutputIt> &dst, FunctionT &&func, Args &&...src) { return _transform_by_block ( dst, dst.begin (), std::forward<FunctionT> (func), std::forward<Args> (src)... ); } };