/* * 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 */ #pragma once namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// template OutputIt _transform_by_block ( const cruft::view &, OutputIt cursor, FunctionT && ) { return cursor; } //------------------------------------------------------------------------- template OutputIt _transform_by_block ( const cruft::view &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 (infill)) { return _transform_by_block ( dst, std::copy_n (remain.begin (), remain.size (), cursor), std::forward (func), std::forward (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 (func), std::forward (tail)... ); } //------------------------------------------------------------------------- template OutputIt transform_by_block (const cruft::view &dst, FunctionT &&func, Args &&...src) { return _transform_by_block ( dst, dst.begin (), std::forward (func), std::forward (src)... ); } };